diff --git a/.gitattributes b/.gitattributes index ff21364..6bc25bc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,8 +3,10 @@ # # Linux start script should use lf /gradlew text eol=lf + # These are Windows script files and should use crlf *.bat text eol=crlf + # Binary files should be left untouched *.jar binary *.bin filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 30c69cc..fbdb198 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,10 +13,6 @@ jobs: steps: - uses: actions/checkout@v3 - with: - lfs: true - fetch-depth: 1 - - name: Set up JDK 21 uses: actions/setup-java@v3 @@ -35,6 +31,37 @@ jobs: path: dist/portable/*-portable.jar retention-days: 7 + build-web: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + pages: write + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'temurin' + cache: gradle + + - name: Build Web Application + run: ./gradlew buildBundledWebApp + + - name: Upload pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: 'dist/web-bundle' + + - name: Deploy to GitHub Pages + if: github.event_name == 'release' + id: deployment + uses: actions/deploy-pages@v4 + + build-native: runs-on: ${{ matrix.os }} strategy: @@ -51,10 +78,7 @@ jobs: steps: - uses: actions/checkout@v3 - with: - lfs: true - fetch-depth: 1 - + - name: Set up GraalVM uses: graalvm/setup-graalvm@v1 with: @@ -62,15 +86,6 @@ jobs: distribution: 'graalvm' github-token: ${{ secrets.GITHUB_TOKEN }} native-image-job-reports: 'true' - - - name: Build Installer for ${{ matrix.platform }} - shell: bash - run: | - if [[ "${{ matrix.platform }}" == "linux" ]]; then - sudo apt-get install -y rpm - fi - ./gradlew buildInstaller - ls -R dist - name: Build Native Executable for ${{ matrix.platform }} shell: bash diff --git a/.gitignore b/.gitignore index 4c54fec..f7c2d9f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,15 @@ -# Ignore Gradle project-specific cache directory .gradle - -# Ignore Gradle build output directory build bin dist *.hprof .idea -.DS_Store \ No newline at end of file +.DS_Store +gradle-local.properties +.idea/ +node_modules/ +*.map +.sourcemaps +.settings +platform-web/.env.nostr-deploy.local +local.properties \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index c01fa40..4e0f238 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,22 +4,22 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ - { "type": "java", - "name": "Current File", - "request": "launch", - "mainClass": "${file}" - }, - { - "type": "java", - "name": "DesktopLauncher", + "name": "Debug Application", "request": "launch", "mainClass": "org.ngengine.platform.DesktopLauncher", "projectName": "platform-desktop", "osx": { "vmArgs": "-XstartOnFirstThread" - } + }, + "linux": { + "env": { + "__GL_THREADED_OPTIMIZATIONS": "0" + } + }, + "vmArgs": "-ea -Dthreadwarden=true -Djava.util.logging.config.file=${workspaceFolder}/dev-logging.properties", + } ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index e0f15db..595047f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,16 @@ { - "java.configuration.updateBuildConfiguration": "automatic" + "java.configuration.updateBuildConfiguration": "automatic", + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/gradle": true, + "**/.gradle": true, + // "**/build": true, + "**/bin": true, + // "platform-*": true + + } } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index e63f4f3..0bf0251 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,6 +23,7 @@ dependencies { java { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 -} \ No newline at end of file + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} diff --git a/app/src/main/java/org/ngengine/app/Main.java b/app/src/main/java/org/ngengine/app/Main.java index 77a00fb..7bc8136 100644 --- a/app/src/main/java/org/ngengine/app/Main.java +++ b/app/src/main/java/org/ngengine/app/Main.java @@ -12,34 +12,15 @@ import org.ngengine.demo.adc.PhysicsComponent; import org.ngengine.demo.adc.PostprocessingComponent; import org.ngengine.demo.adc.SoundComponent; import org.ngengine.gui.win.NWindowManagerComponent; -import org.ngengine.nostr4j.keypair.NostrPublicKey; - -import com.jme3.system.AppSettings; public class Main { public static NGEAppRunner main(String arg[]){ - AppSettings settings = new AppSettings(true); - settings.setRenderer(AppSettings.LWJGL_OPENGL32); - settings.setWidth(1280); - settings.setHeight(720); - settings.setGammaCorrection(true); - settings.setSamples(2); - settings.setStencilBits(8); - settings.setDepthBits(24); - settings.setVSync(true); - settings.setGraphicsDebug(false); - settings.setX11PlatformPreferred(true); - settings.setTitle("Nostr Game Engine Demo"); - settings.setEmulateMouse(true); - settings.setEmulateKeyboard(true); - - NostrPublicKey appId = NostrPublicKey.fromBech32("npub1tc32kq8hr992tzvt09rwuc5wk6aa08pquqawasv20acjp4umny5q6axr4t"); - NGEAppRunner appRunner = NGEApplication.createApp(appId, settings, app -> { + NGEAppRunner appRunner = NGEApplication.createApp( app -> { ImmersiveAdComponent dep = app.enableAds(); ComponentManager mng = app.getComponentManager(); diff --git a/app/src/main/java/org/ngengine/demo/adc/HudComponent.java b/app/src/main/java/org/ngengine/demo/adc/HudComponent.java index 0e332ce..04fa561 100644 --- a/app/src/main/java/org/ngengine/demo/adc/HudComponent.java +++ b/app/src/main/java/org/ngengine/demo/adc/HudComponent.java @@ -15,7 +15,7 @@ import com.simsilica.lemur.HAlignment; import com.simsilica.lemur.VAlignment; public class HudComponent implements Component, InputHandlerFragment { - private Runnable closeHud; + private NHud hud; @Override public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime, @@ -26,22 +26,18 @@ public class HudComponent implements Component, InputHandlerFragment { windowManager.showCursor(false); - this.closeHud= windowManager.showWindow( - NHud.class, - (win, err) -> { - win.setFitContent(false); - win.setFullscreen(true); - NLabel crossair = new NLabel("+"); - crossair.setTextVAlignment(VAlignment.Center); - crossair.setTextHAlignment(HAlignment.Center); - win.getCenter().addChild(crossair); - } - ); + this.hud = windowManager.showWindow( NHud.class ); + hud.setFitContent(false); + hud.setFullscreen(true); + NLabel crossair = new NLabel("+"); + crossair.setTextVAlignment(VAlignment.Center); + crossair.setTextHAlignment(HAlignment.Center); + hud.getCenter().addChild(crossair); } @Override public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) { - this.closeHud.run(); + hud.close(); } @Override diff --git a/app/src/main/java/org/ngengine/demo/adc/LoadingScreenComponent.java b/app/src/main/java/org/ngengine/demo/adc/LoadingScreenComponent.java index 0203514..51607cd 100644 --- a/app/src/main/java/org/ngengine/demo/adc/LoadingScreenComponent.java +++ b/app/src/main/java/org/ngengine/demo/adc/LoadingScreenComponent.java @@ -16,7 +16,7 @@ import com.simsilica.lemur.HAlignment; import com.simsilica.lemur.VAlignment; public class LoadingScreenComponent implements Component, LogicFragment { - private Runnable closeHud; + private NHud hud; private NLabel txt; @Override public void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime, @@ -28,23 +28,20 @@ public class LoadingScreenComponent implements Component, LogicFragment windowManager.showCursor(false); txt = new NLabel("Loading"); - - this.closeHud= windowManager.showWindow( - NHud.class, - (win, err) -> { - win.setFitContent(false); - win.setFullscreen(true); - txt.setFontSize(32); - txt.setTextVAlignment(VAlignment.Center); - txt.setTextHAlignment(HAlignment.Center); - win.getCenter().addChild(txt); - } - ); + + hud = windowManager.showWindow(NHud.class); + hud.setFitContent(false); + hud.setFullscreen(true); + txt.setFontSize(32); + txt.setTextVAlignment(VAlignment.Center); + txt.setTextHAlignment(HAlignment.Center); + hud.getCenter().addChild(txt); + } @Override public void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore) { - this.closeHud.run(); + hud.close(); } float time = 0; diff --git a/app/src/main/java/org/ngengine/demo/adc/MapComponent.java b/app/src/main/java/org/ngengine/demo/adc/MapComponent.java index 7013944..56296c2 100644 --- a/app/src/main/java/org/ngengine/demo/adc/MapComponent.java +++ b/app/src/main/java/org/ngengine/demo/adc/MapComponent.java @@ -83,7 +83,6 @@ public class MapComponent implements Component, AsyncAssetLoadingFragmen preload.accept(sky); } catch(Exception e){ e.printStackTrace(); - System.exit(1); } } diff --git a/app/src/main/resources/ngeapp.json b/app/src/main/resources/ngeapp.json new file mode 100644 index 0000000..76fa507 --- /dev/null +++ b/app/src/main/resources/ngeapp.json @@ -0,0 +1,47 @@ +{ + + "AppId": "npub146wutmuxfmnlx9fcty0lkns2rpwhnl57kpes26mmt4hygalsakrsdllryz", + "Display": 0, + "Width": 1280, + "Height": 720, + "Fullscreen": false, + "Resizable": true, + "Title": "AdCity", + "Version": "1.0.0", + "VersionCode": 1, + "ShortName": "adc", + "Namespace":"org.ngengine.adc", + "Copyright": "", + "VSync": true, + "GammaCorrection": true, + "ScreenOrientation": "landscape", + "relays": { + "blossom": { + "default": [ + "https://blossom.primal.net", + "https://blossom.band/" + ] + }, + "nostr": { + "ads":[ + "wss://nostr.rblb.it", + "wss://relay.damus.io" + ], + "default": [ + "wss://relay.ngengine.org", + "wss://relay2.ngengine.org", + "wss://relay.damus.io", + "wss://relay.primal.net", + "wss://relay.nostr.band", + "wss://relay.snort.social", + "wss://nos.lol" + ], + "nip46": [ + "wss://relay.nsec.app", + "wss://relay.ngengine.org", + "wss://relay2.ngengine.org" + ] + } + } + +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 135e75e..9ff9933 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,19 +2,8 @@ org.gradle.configuration-cache=false org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true +teaVmVersion=0.12.3 # NGE versions -ngePlatformVersion=0.1.3 -ngeVersion=0.1 - -# Build targets -withDesktopPlatform=true -withAndroidPlatform=false - -# Project settings -version=1.0.0 -versionCode=1 -projectName=adcity -applicationId=org.ngengine.demo.AdcDemo -copyright=Copyright (c) 2025 -javaOptions= +ngePlatformVersion=0.2.1 +ngeVersion=0.2-rc3 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 466d564..14a0352 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,9 +8,8 @@ constraintlayout = "2.2.1" espressoCore = "3.7.0" guava = "33.3.1-jre" junit = "4.13.2" -junitVersion = "4.13.3-SNAPSHOT" +junitVersion = "4.13.2" material = "1.12.0" -ngePlatformAndroid = "0.1.0-SNAPSHOT" navigationFragment = "2.6.0" navigationUi = "2.6.0" diff --git a/gradle/libs/android-icon-gen.gradle b/gradle/libs/android-icon-gen.gradle new file mode 100644 index 0000000..2789485 --- /dev/null +++ b/gradle/libs/android-icon-gen.gradle @@ -0,0 +1,54 @@ +import javax.imageio.ImageIO +import java.awt.Image +import java.awt.image.BufferedImage +import java.awt.geom.Ellipse2D + +gradle.ext.generateAndroidIcons = { inputLogoPath, outputDirPath -> + def inputLogo = file(inputLogoPath) + def outputDir = file(outputDirPath) + + def densities = [ + mdpi : 48, + hdpi : 72, + xhdpi: 96, + xxhdpi: 144, + xxxhdpi: 192 + ] + + if (!inputLogo.exists()) { + throw new GradleException("Logo file not found at ${inputLogo}") + } + + def original = ImageIO.read(inputLogo) + + densities.each { name, size -> + def dir = new File(outputDir, "mipmap-${name}") + dir.mkdirs() + + // --- Regular square launcher --- + def square = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB) + def g = square.createGraphics() + g.drawImage(original.getScaledInstance(size, size, Image.SCALE_SMOOTH), 0, 0, null) + g.dispose() + + def launcherFile = new File(dir, "ic_launcher.png") + ImageIO.write(square, "png", launcherFile) + def launcherFileF = new File(dir, "ic_launcher_foreground.png") + ImageIO.write(square, "png", launcherFileF) + println "Generated ${launcherFile} (${size}x${size})" + + // --- Round launcher --- + def round = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB) + def gr = round.createGraphics() + + // Create circular clipping mask + gr.setClip(new Ellipse2D.Float(0, 0, size, size)) + gr.drawImage(original.getScaledInstance(size, size, Image.SCALE_SMOOTH), 0, 0, null) + gr.dispose() + + def roundFile = new File(dir, "ic_launcher_round.png") + ImageIO.write(round, "png", roundFile) + println "Generated ${roundFile} (circular ${size}x${size})" + } + +} diff --git a/gradle/libs/class-finder.gradle b/gradle/libs/class-finder.gradle new file mode 100644 index 0000000..dfd4f7a --- /dev/null +++ b/gradle/libs/class-finder.gradle @@ -0,0 +1,231 @@ +project.ext { + dynamicTargetTypes = [ + 'com.jme3.export.Savable', + 'com.jme3.asset.AssetLoader', + 'com.jme3.asset.plugins.FileLocator', + 'com.jme3.network.Message', + // 'com.jme3.network.serializing.Serializable', + // 'org.ngengine.network.protocol.NetworkSafe', + 'org.ngengine.components.fragments.Fragment', + 'org.ngengine.components.Component', + 'com.jme3.asset.cache.AssetCache', + 'com.jme3.asset.AssetProcessor', + 'com.jme3.post.Filter', + 'com.jme3.util.BufferAllocator', + 'com.jme3.asset.AssetLocator', + 'com.jme3.anim.util.JointModelTransform', + 'com.jme3.material.logic.TechniqueDefLogic', + 'com.jme3.material.Technique', + 'com.jme3.material.TechniqueDef', + 'com.jme3.util.clone.JmeCloneable', + 'com.jme3.system.JmeSystem', + 'com.jme3.system.JmeSystemDelegate', + 'com.jme3.util.SafeArrayList', + 'com.jme3.plugins.json.JsonParser', + 'java.lang.Cloneable', + 'com.jme3.asset.CloneableSmartAsset', + 'com.jme3.post.SceneProcessor', + 'com.jme3.util.res.ResourceLoader', + 'org.ngengine.nostr4j.listeners.NostrRelayComponent', + 'org.ngengine.auth.Auth', + 'org.ngengine.gui.win.NWindow', + 'org.ngengine.auth.AuthStrategy', + 'org.ngengine.auth.AuthConfig', + 'com.simsilica.lemur.core.GuiComponent', + 'com.simsilica.lemur.Panel', + + 'com.simsilica.lemur.style.Styles', + 'com.simsilica.lemur.style.StyleTree', + // 'com.simsilica.lemur.style.StyleDefaults', + // 'com.simsilica.lemur.style.StyleAttribute', + 'com.simsilica.lemur.style.Selector', + 'com.simsilica.lemur.style.ElementId', + 'com.simsilica.lemur.style.Attributes', + + + + + ] + + dynamicAdditionalClasses = [ + + ] + dynamicScanSubclasses = true + dynamicExcludePatterns = [ + 'org\\.teavm\\..*', + 'java\\.lang\\..*', + 'org\\.joda\\.time\\..*', + 'java\\..*', + 'javax\\..*', + 'kotlin\\..*', + 'com\\.google\\.gson\\..*', + 'org\\.threeten\\..*', + 'org\\.apache\\..*', + 'com\\.simsilica\\.lemur\\.ColorChooser.*', + 'org\\.slf4j\\..*' + + + + ] + dynamicClassesFound = new TreeSet() + dynamicReflectionClasses = new TreeSet() +} + +ext.scanClasspathForClasses = { project -> + // Create a collection to hold all classpath entries + Set classpath = new LinkedHashSet<>() + + // Add project's compiled classes + if (project.sourceSets.findByName('main')) { + classpath.addAll(project.sourceSets.main.output.classesDirs.files) + classpath.addAll(project.sourceSets.main.output.resourcesDir) + } + + // Add runtime dependencies + if (project.configurations.findByName('runtimeClasspath')) { + classpath.addAll(project.configurations.runtimeClasspath.files) + } + + // Add compile dependencies (some may not be in runtime) + if (project.configurations.findByName('compileClasspath')) { + classpath.addAll(project.configurations.compileClasspath.files) + } + + // Keep only existing dirs/jars + classpath = classpath.findAll { + it.exists() && (it.isDirectory() || it.name.endsWith('.jar')) + } as LinkedHashSet + + println "Scanning ${classpath.size()} classpath entries" + + // Build a single loader for EVERYTHING + URL[] urls = classpath.collect { it.toURI().toURL() } as URL[] + ClassLoader scanLoader = new URLClassLoader(urls, this.class.classLoader) + + // println "Target types: ${project.ext.dynamicTargetTypes}" + + // Reset results + project.ext.dynamicClassesFound.clear() + project.ext.dynamicReflectionClasses.clear() + + // Check target types loadable with the same loader + project.ext.dynamicTargetTypes.each { targetType -> + try { + Class.forName(targetType, false, scanLoader) + // println "✓ Target type $targetType is loadable" + } catch (Throwable t) { + println "✗ Target type $targetType is not loadable: ${t.class.simpleName}: ${t.message}" + } + } + + // Seed manual classes + project.ext.dynamicAdditionalClasses.each { cn -> + project.ext.dynamicClassesFound.add(cn) + project.ext.dynamicReflectionClasses.add(cn) + } + + int totalProcessed = 0 + int totalMatched = 0 + + classpath.each { file -> + if (file.isDirectory()) { + def r = scanDirectory(file, file, project.ext.dynamicTargetTypes, + project.ext.dynamicClassesFound, project.ext.dynamicReflectionClasses, + project.ext.dynamicScanSubclasses, project.ext.dynamicExcludePatterns, + scanLoader) + totalProcessed += r.processed; totalMatched += r.matched + } else { + def r = scanJar(file, project.ext.dynamicTargetTypes, + project.ext.dynamicClassesFound, project.ext.dynamicReflectionClasses, + project.ext.dynamicScanSubclasses, project.ext.dynamicExcludePatterns, + scanLoader) + totalProcessed += r.processed; totalMatched += r.matched + } + } + + println "Processed ${totalProcessed} classes total" + println "Matched ${totalMatched} classes" + println "Found ${project.ext.dynamicClassesFound.size()} dynamic classes" + + [classes: project.ext.dynamicClassesFound, reflectionClasses: project.ext.dynamicReflectionClasses] +} +def scanDirectory(baseDir, dir, targetTypes, classesFound, reflectionClasses, scanSubclasses, excludePatterns, ClassLoader scanLoader) { + int processed = 0, matched = 0 + dir.eachFileRecurse { file -> + if (file.isFile() && file.name.endsWith('.class')) { + def rel = baseDir.toPath().relativize(file.toPath()).toString() + def className = rel.substring(0, rel.length() - 6).replace(File.separator, '.') + processed++ + if (!className.contains('$') && className != 'module-info' && className != 'package-info' && !isExcluded(className, excludePatterns)) { + try { + Class clazz = Class.forName(className, false, scanLoader) + if (isCompatibleType(clazz, targetTypes, scanSubclasses, scanLoader)) { + classesFound.add(className) + reflectionClasses.add(className) + matched++ + } + } catch (Throwable ignored) {} + } + } + } + [processed: processed, matched: matched] +} + +def scanJar(jarFile, targetTypes, classesFound, reflectionClasses, scanSubclasses, excludePatterns, ClassLoader scanLoader) { + int processed = 0, matched = 0 + try { + new java.util.jar.JarFile(jarFile).withCloseable { jar -> + jar.entries().findAll { !it.isDirectory() && it.name.endsWith('.class') }.each { e -> + def className = e.name.substring(0, e.name.length() - 6).replace('/', '.') + processed++ + if (!className.contains('$') && className != 'module-info' && className != 'package-info' && !isExcluded(className, excludePatterns)) { + try { + Class clazz = Class.forName(className, false, scanLoader) + if (isCompatibleType(clazz, targetTypes, scanSubclasses, scanLoader)) { + classesFound.add(className) + reflectionClasses.add(className) + matched++ + } + } catch (Throwable ignored) {} + } + } + } + } catch (Throwable t) { + println "Error scanning JAR ${jarFile.name}: ${t.message}" + } + [processed: processed, matched: matched] +} + +def isCompatibleType(Class clazz, Collection targetTypes, boolean scanSubclasses, ClassLoader scanLoader) { + if (clazz == null) return false + + // Assignable to any target class/interface + for (def targetType : targetTypes) { + try { + Class targetClass = Class.forName(targetType, false, scanLoader) + if (targetClass.isAssignableFrom(clazz)) return true + } catch (Throwable ignored) {} + } + + // Traverse interfaces + for (def iface : clazz.interfaces) { + if (targetTypes.contains(iface.name) || (scanSubclasses && isCompatibleType(iface, targetTypes, scanSubclasses, scanLoader))) { + return true + } + } + + // Traverse superclass + scanSubclasses && isCompatibleType(clazz.superclass, targetTypes, scanSubclasses, scanLoader) +} + +// Helper to check if a class should be excluded +def isExcluded(String className, Collection excludePatterns) { + for (def pattern : excludePatterns) { + if (className.matches(pattern)) { + return true + } + } + return false +} + + diff --git a/gradle/libs/props.gradle b/gradle/libs/props.gradle new file mode 100644 index 0000000..7c5a851 --- /dev/null +++ b/gradle/libs/props.gradle @@ -0,0 +1,15 @@ +import groovy.json.JsonSlurper + +gradle.ext.loadNgeAppProperties = { path -> + def ngeappFile = file(path) + if (ngeappFile.exists()) { + def jsonSlurper = new JsonSlurper() + def fileContent = ngeappFile.text.replaceAll(/\/\/.*?$/, '').trim() + def ngeappConfig = jsonSlurper.parseText(fileContent) + + return ngeappConfig + } else { + logger.warn(path+" file not found") + return [:] + } +} \ No newline at end of file diff --git a/icon.icns b/icon.icns deleted file mode 100644 index 0b992fb..0000000 Binary files a/icon.icns and /dev/null differ diff --git a/local.properties b/local.properties index 27d9bd5..8d16733 100644 --- a/local.properties +++ b/local.properties @@ -1,8 +1 @@ -## This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -#Mon Sep 01 09:13:24 CEST 2025 -sdk.dir=/home/riccardobl/Android/Sdk +sdk.dir=/home/riccardobl/Android/Sdk \ No newline at end of file diff --git a/platform-android/build.gradle b/platform-android/build.gradle index b9f5cb3..ec1e0f2 100644 --- a/platform-android/build.gradle +++ b/platform-android/build.gradle @@ -2,19 +2,31 @@ plugins { id 'com.android.application' } +def localPropsFile = file("${rootDir}/local.properties") +if (!localPropsFile.exists()) { + def userHome = System.getProperty('user.home') + localPropsFile.text = "sdk.dir=${userHome}/Android/Sdk" + println "Created local.properties with sdk.dir=${userHome}/Android/Sdk" +} + android { compileSdk 36 - namespace "${project.applicationId}" + namespace "${project.Namespace}" defaultConfig { - applicationId "${project.applicationId}" + applicationId "${project.Namespace}" minSdk 33 targetSdk 33 - versionCode project.versionCode.toInteger() - versionName project.version - + versionCode project.VersionCode.toInteger() + versionName project.Version testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + manifestPlaceholders = [ + appLabel : (project.findProperty('Title') ?: "NGE Unnamed App"), + screenOrientation: (project.findProperty('ScreenOrientation') ?: "landscape") + ] } + packagingOptions { jniLibs { useLegacyPackaging = true @@ -27,14 +39,17 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } + buildFeatures { viewBinding true } + } @@ -52,7 +67,19 @@ dependencies { implementation project(':app') implementation "org.ngengine:nge-platform-android:${ngePlatformVersion}" implementation "org.ngengine:nge-app:${ngeVersion}" - implementation "org.ngengine:jme3-android:${ngeVersion}" - implementation "org.ngengine:jme3-android-native:${ngeVersion}" + implementation "org.ngengine:nge-android:${ngeVersion}" } + +apply from: "${rootDir}/gradle/libs/android-icon-gen.gradle" + +task generateAndroidLauncherIcons (){ + doLast { + gradle.ext.generateAndroidIcons("${rootDir}/icon.png", "${projectDir}/src/main/res") + } +} + +android.applicationVariants.all { variant -> + variant.mergeResourcesProvider.configure { dependsOn(generateAndroidLauncherIcons) } +} + \ No newline at end of file diff --git a/platform-android/src/main/AndroidManifest.xml b/platform-android/src/main/AndroidManifest.xml index 5a62138..825365d 100644 --- a/platform-android/src/main/AndroidManifest.xml +++ b/platform-android/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ + android:screenOrientation="${screenOrientation}" + android:theme="@style/Theme.AppCompat.NoActionBar" + > diff --git a/platform-android/src/main/java/org/ngengine/platform/AndroidLauncherActivity.java b/platform-android/src/main/java/org/ngengine/platform/AndroidLauncherActivity.java index d0a8cfd..5d90d6d 100644 --- a/platform-android/src/main/java/org/ngengine/platform/AndroidLauncherActivity.java +++ b/platform-android/src/main/java/org/ngengine/platform/AndroidLauncherActivity.java @@ -13,22 +13,22 @@ import androidx.navigation.Navigation; import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.NavigationUI; +import org.ngengine.app.Main; +import org.ngengine.platform.android.AndroidThreadedPlatform; -import org.ngengine.demo.AdcDemo.R; public class AndroidLauncherActivity extends AppCompatActivity { - private AndroidLauncherFragment launcherFragment; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_android_launcher); + int layoutId = getResources().getIdentifier("activity_android_launcher", "layout", getPackageName()); + setContentView(layoutId); - launcherFragment = new AndroidLauncherFragment(); + int containerId = getResources().getIdentifier("fragment_container", "id", getPackageName()); getSupportFragmentManager() .beginTransaction() - .add(R.id.fragment_container, launcherFragment) + .add(containerId, new AndroidLauncherFragment(Main::main, AndroidThreadedPlatform::new)) .commit(); } diff --git a/platform-android/src/main/java/org/ngengine/platform/AndroidLauncherFragment.java b/platform-android/src/main/java/org/ngengine/platform/AndroidLauncherFragment.java deleted file mode 100644 index cfebea4..0000000 --- a/platform-android/src/main/java/org/ngengine/platform/AndroidLauncherFragment.java +++ /dev/null @@ -1,308 +0,0 @@ - -package org.ngengine.platform; - -import android.content.Context; -import android.opengl.GLSurfaceView; -import android.os.Bundle; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.fragment.app.Fragment; - -import com.jme3.audio.AudioRenderer; -import com.jme3.input.JoyInput; -import com.jme3.input.android.AndroidSensorJoyInput; - -import com.jme3.system.AppSettings; -import com.jme3.system.SystemListener; -import com.jme3.system.android.JmeAndroidSystem; -import com.jme3.system.android.OGLESContext; -import com.jme3.util.AndroidLogHandler; -import com.jme3.util.AndroidNativeBufferAllocator; -import com.jme3.util.BufferAllocatorFactory; - -import android.app.AlertDialog; -import org.ngengine.NGEApplication.NGEAppRunner; - -import org.ngengine.NGEApplication; -import org.ngengine.app.Main; -import org.ngengine.platform.android.AndroidThreadedPlatform; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogManager; -import java.util.logging.Logger; - - -public class AndroidLauncherFragment extends Fragment implements - SystemListener { - private static final Logger logger = Logger.getLogger(AndroidLauncherFragment.class.getName()); - - protected GLSurfaceView view = null; - - private NGEApplication app = null; - private boolean finishOnAppStop = true; - - - @Override - public void onAttach(Context context) { - super.onAttach(context); - } - - public void setCloseActivityOnAppStop(boolean close){ - this.finishOnAppStop = close; - } - - /** - * onCreate is called once for this Fragment instance. - * Note: AppSettings configuration has been removed. Configure settings in your app. - */ - @Override - @SuppressWarnings("unchecked") - public void onCreate(Bundle savedInstanceState) { - initializeLogHandler(); - logger.fine("onCreate"); - super.onCreate(savedInstanceState); - - System.setProperty( BufferAllocatorFactory.PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION, AndroidNativeBufferAllocator.class.getName()); - NGEPlatform.set(new AndroidThreadedPlatform(this.getContext())); - NGEAppRunner runner = Main.main(new String[0]); - app = runner.app(); - - AppSettings settings = app.getSettings(); - settings.setAudioRenderer(AppSettings.ANDROID_OPENAL_SOFT); - - app.start(); - - - OGLESContext ctx = (OGLESContext) app.getJme3App().getContext(); - ctx.setSystemListener(this); - } - - /** - * Create the GLSurfaceView and return it as the Fragment's view. - */ - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - logger.fine("onCreateView"); - view = ((OGLESContext) app.getJme3App().getContext()).createView(requireActivity()); - JmeAndroidSystem.setView(view); - return view; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - logger.fine("onActivityCreated"); - super.onActivityCreated(savedInstanceState); - } - - @Override - public void onStart() { - logger.fine("onStart"); - super.onStart(); - } - - /** - * When the Fragment resumes, call gainFocus() in the jME application. - */ - @Override - public void onResume() { - logger.fine("onResume"); - super.onResume(); - gainFocus(); - } - - /** - * When the Fragment pauses, call loseFocus() in the jME application. - */ - @Override - public void onPause() { - logger.fine("onPause"); - loseFocus(); - super.onPause(); - } - - @Override - public void onStop() { - logger.fine("onStop"); - super.onStop(); - } - - /** - * Clear references to the GLSurfaceView. - */ - @Override - public void onDestroyView() { - logger.fine("onDestroyView"); - if (view != null) { - if (view.getParent() instanceof ViewGroup) { - ((ViewGroup) view.getParent()).removeView(view); - } - } - view = null; - JmeAndroidSystem.setView(null); - super.onDestroyView(); - } - - /** - * Called by the system when the application is being destroyed. - */ - @Override - public void onDestroy() { - logger.fine("onDestroy"); - if (app != null) { - app.stop(); - } - app = null; - super.onDestroy(); - } - - /** - * Called when an error has occurred. Shows an error message and logs the exception. - */ - @Override - public void handleError(final String errorMsg, final Throwable t) { - String stackTrace = ""; - String title = "Error"; - - if (t != null) { - // Convert exception to string - StringWriter sw = new StringWriter(100); - t.printStackTrace(new PrintWriter(sw)); - stackTrace = sw.toString(); - title = t.toString(); - } - - final String finalTitle = title; - final String finalMsg = (errorMsg != null ? errorMsg : "Uncaught Exception") - + "\n" + stackTrace; - - logger.log(Level.SEVERE, finalMsg); - - requireActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()); - builder.setTitle(finalTitle); - builder.setMessage(finalMsg); - - AlertDialog dialog = builder.create(); - dialog.show(); - } - }); - } - - - - - /** - * Removes the standard Android log handler due to an issue with not logging - * entries lower than INFO level and adds a handler that produces - * JME formatted log messages. - */ - protected void initializeLogHandler() { - Logger log = LogManager.getLogManager().getLogger(""); - for (Handler handler : log.getHandlers()) { - if (log.getLevel() != null && log.getLevel().intValue() <= Level.FINE.intValue()) { - Log.v("AndroidHarness", "Removing Handler class: " + handler.getClass().getName()); - } - log.removeHandler(handler); - } - Handler handler = new AndroidLogHandler(); - log.addHandler(handler); - handler.setLevel(Level.ALL); - } - - @Override - public void initialize() { - app.getJme3App().initialize(); - - } - - @Override - public void reshape(int width, int height) { - app.getJme3App().reshape(width, height); - } - - @Override - public void rescale(float x, float y) { - app.getJme3App().rescale(x, y); - } - - @Override - public void update() { - app.getJme3App().update(); - } - - @Override - public void requestClose(boolean esc) { - app.getJme3App().requestClose(esc); - } - - @Override - public void destroy() { - if (app != null) { - app.getJme3App().destroy(); - } - if (finishOnAppStop) { - requireActivity().finish(); - } - } - - @Override - public void gainFocus() { - logger.fine("gainFocus"); - if (view != null) { - view.onResume(); - } - - if (app != null) { - // resume the audio - AudioRenderer audioRenderer = app.getJme3App().getAudioRenderer(); - if (audioRenderer != null) { - audioRenderer.resumeAll(); - } - // resume the sensors (aka joysticks) - if (app.getJme3App().getContext() != null) { - JoyInput joyInput = app.getJme3App().getContext().getJoyInput(); - if (joyInput instanceof AndroidSensorJoyInput) { - ((AndroidSensorJoyInput) joyInput).resumeSensors(); - } - } - app.getJme3App().gainFocus(); - } - } - - @Override - public void loseFocus() { - logger.fine("loseFocus"); - if (app != null) { - app.getJme3App().loseFocus(); - } - - if (view != null) { - view.onPause(); - } - - if (app != null) { - // pause the audio - AudioRenderer audioRenderer = app.getJme3App().getAudioRenderer(); - if (audioRenderer != null) { - audioRenderer.pauseAll(); - } - // pause the sensors (aka joysticks) - if (app.getJme3App().getContext() != null) { - JoyInput joyInput = app.getJme3App().getContext().getJoyInput(); - if (joyInput instanceof AndroidSensorJoyInput) { - ((AndroidSensorJoyInput) joyInput).pauseSensors(); - } - } - } - } - - -} \ No newline at end of file diff --git a/platform-android/src/main/res/drawable-v24/ic_launcher_foreground.xml b/platform-android/src/main/res/drawable-v24/ic_launcher_foreground.xml index 7706ab9..2d4cc47 100644 --- a/platform-android/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/platform-android/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,30 +1,11 @@ - - - - - - - - - - - + + + \ No newline at end of file diff --git a/platform-android/src/main/res/drawable/ic_launcher_background.xml b/platform-android/src/main/res/drawable/ic_launcher_background.xml index 07d5da9..0001463 100644 --- a/platform-android/src/main/res/drawable/ic_launcher_background.xml +++ b/platform-android/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + \ No newline at end of file diff --git a/platform-android/src/main/res/mipmap-hdpi/.gitkeep b/platform-android/src/main/res/mipmap-hdpi/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/mipmap-hdpi/ic_launcher.png b/platform-android/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..d7cce2b Binary files /dev/null and b/platform-android/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/platform-android/src/main/res/mipmap-hdpi/ic_launcher.webp b/platform-android/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index 3e37e73..0000000 Binary files a/platform-android/src/main/res/mipmap-hdpi/ic_launcher.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/platform-android/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..d7cce2b Binary files /dev/null and b/platform-android/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/platform-android/src/main/res/mipmap-hdpi/ic_launcher_round.png b/platform-android/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..d7cce2b Binary files /dev/null and b/platform-android/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/platform-android/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/platform-android/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index 992a775..0000000 Binary files a/platform-android/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-mdpi/.gitkeep b/platform-android/src/main/res/mipmap-mdpi/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/mipmap-mdpi/ic_launcher.png b/platform-android/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c47d1ec Binary files /dev/null and b/platform-android/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/platform-android/src/main/res/mipmap-mdpi/ic_launcher.webp b/platform-android/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 60e2f8c..0000000 Binary files a/platform-android/src/main/res/mipmap-mdpi/ic_launcher.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/platform-android/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..c47d1ec Binary files /dev/null and b/platform-android/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/platform-android/src/main/res/mipmap-mdpi/ic_launcher_round.png b/platform-android/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..c47d1ec Binary files /dev/null and b/platform-android/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/platform-android/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/platform-android/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 04c69c0..0000000 Binary files a/platform-android/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-xhdpi/.gitkeep b/platform-android/src/main/res/mipmap-xhdpi/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/mipmap-xhdpi/ic_launcher.png b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..97e9539 Binary files /dev/null and b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/platform-android/src/main/res/mipmap-xhdpi/ic_launcher.webp b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 13410d7..0000000 Binary files a/platform-android/src/main/res/mipmap-xhdpi/ic_launcher.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..97e9539 Binary files /dev/null and b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..97e9539 Binary files /dev/null and b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 554b15e..0000000 Binary files a/platform-android/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-xxhdpi/.gitkeep b/platform-android/src/main/res/mipmap-xxhdpi/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher.png b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..352c635 Binary files /dev/null and b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index fe6bf91..0000000 Binary files a/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..352c635 Binary files /dev/null and b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..352c635 Binary files /dev/null and b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index f8baf99..0000000 Binary files a/platform-android/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-xxxhdpi/.gitkeep b/platform-android/src/main/res/mipmap-xxxhdpi/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..c3243cb Binary files /dev/null and b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index 698b15c..0000000 Binary files a/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and /dev/null differ diff --git a/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000..c3243cb Binary files /dev/null and b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..c3243cb Binary files /dev/null and b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 4f3ce06..0000000 Binary files a/platform-android/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/platform-android/src/main/res/navigation/.gitkeep b/platform-android/src/main/res/navigation/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/values-land/.gitkeep b/platform-android/src/main/res/values-land/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/values-night/.gitkeep b/platform-android/src/main/res/values-night/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/values-v23/.gitkeep b/platform-android/src/main/res/values-v23/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/values-w1240dp/.gitkeep b/platform-android/src/main/res/values-w1240dp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/values-w600dp/.gitkeep b/platform-android/src/main/res/values-w600dp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-android/src/main/res/values/.gitkeep b/platform-android/src/main/res/values/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/platform-desktop/build.gradle b/platform-desktop/build.gradle index abf953e..a8c48f0 100644 --- a/platform-desktop/build.gradle +++ b/platform-desktop/build.gradle @@ -6,6 +6,12 @@ plugins { } +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + dependencies { testImplementation libs.junit @@ -16,11 +22,17 @@ dependencies { implementation project(':app') } - application { mainClass = "org.ngengine.platform.DesktopLauncher" } +configurations { + nativeImageCompileOnly { + canBeResolved = true + } +} + + run { jvmArgs = [ "-Djava.util.logging.config.file=${rootProject.projectDir}/dev-logging.properties", @@ -43,8 +55,6 @@ shadowJar { } -build.dependsOn shadowJar - graalvmNative { toolchainDetection = true metadataRepository { @@ -84,9 +94,9 @@ graalvmNative { ] // Add G1 GC only if linux - if (org.gradle.internal.os.OperatingSystem.current().isLinux()) { - arguments.add('--gc=G1') - } + // if (org.gradle.internal.os.OperatingSystem.current().isLinux()) { + // arguments.add('--gc=G1') + // } buildArgs.addAll(arguments) sharedLibrary = false @@ -94,11 +104,6 @@ graalvmNative { } } -configurations { - nativeImageCompileOnly { - canBeResolved = true - } -} def getOsName(){ def osName = org.gradle.internal.os.OperatingSystem.current().getName().toLowerCase() @@ -116,8 +121,6 @@ def getOsName(){ task traceNative(type: JavaExec) { - group = 'graalvm' - description = 'Trace reflection and resource usage' mainClass = application.mainClass.get() classpath = sourceSets.main.runtimeClasspath jvmArgs = [ @@ -152,8 +155,6 @@ task traceNative(type: JavaExec) { task buildNativeExecutable { - group = 'graalvm' - description = 'Build native executable for current platform' dependsOn 'nativeCompile' doLast { def buildDirNative = "${project.buildDir}/native/nativeCompile" @@ -185,84 +186,10 @@ task buildNativeExecutable { - def jpackage(installerType, distDir){ - def os = org.gradle.internal.os.OperatingSystem.current() - - - - def jarFile = shadowJar.archiveFile.get().asFile - def jarDir = jarFile.parentFile - def mainClass = application.mainClass.get() - - - def shadowJarFile = shadowJar.archiveFile.get().asFile - - def commandLine = [ - 'jpackage', - '--input', jarDir.absolutePath, - '--main-jar', jarFile.name, - '--main-class', mainClass, - '--name', rootProject.name, - '--app-version', project.version, - '--type', installerType, - '--dest', distDir, - '--java-options', project.findProperty('javaOptions') ?: '', - '--copyright', project.findProperty('copyright') - ] - - // Optional: platform-specific flags - if (os.isWindows()) { - commandLine += ['--win-menu', '--win-shortcut'] - } else if (os.isMacOsX()) { - commandLine += ['--icon', "${rootProject.projectDir}/icon.icns"] - } else if (os.isLinux()) { - commandLine += ['--icon', "${rootProject.projectDir}/icon.png"] - } - return commandLine -} - - - -task buildInstaller(type: DefaultTask) { - group = 'distribution' - description = 'Create native installer using jpackage' - dependsOn shadowJar - - def os = org.gradle.internal.os.OperatingSystem.current() - def osName = getOsName() - def osArch = System.getProperty("os.arch").toLowerCase() - def buildName = "${rootProject.name}-${project.version}-${osName}-${osArch}-SETUP"; - def distDir = file("${rootProject.projectDir}/dist/${buildName}.setup") - - +task buildPortable { + dependsOn shadowJar doLast { - if (distDir.exists()) { - println "Deleting existing output directory: ${distDir}" - delete distDir - } - - if(os.isWindows()){ - exec { - commandLine jpackage('exe', distDir) - } - } else if(os.isMacOsX()){ - exec { - commandLine jpackage('dmg', distDir) - } - } else if(os.isLinux()){ - exec { - commandLine jpackage('deb', distDir) - } - exec { - commandLine jpackage('rpm', distDir) - } - } + println "Portable JAR created: ${shadowJar.destinationDirectory}/${shadowJar.archiveFileName.get()}" } } - - -java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 -} \ No newline at end of file diff --git a/platform-desktop/src/main/java/org/ngengine/platform/DesktopLauncher.java b/platform-desktop/src/main/java/org/ngengine/platform/DesktopLauncher.java index 05bd0cd..0e726c3 100644 --- a/platform-desktop/src/main/java/org/ngengine/platform/DesktopLauncher.java +++ b/platform-desktop/src/main/java/org/ngengine/platform/DesktopLauncher.java @@ -2,10 +2,12 @@ package org.ngengine.platform; import org.ngengine.app.Main; import org.ngengine.platform.jvm.JVMAsyncPlatform; + +import java.io.IOException; import org.ngengine.NGEApplication.NGEAppRunner; public class DesktopLauncher { - public static void main(String[] args) { + public static void main(String[] args) throws IOException { NGEPlatform.set(new JVMAsyncPlatform()); NGEAppRunner runner = Main.main(args); runner.start(); diff --git a/platform-desktop/trace/reachability-metadata.json b/platform-desktop/trace/reachability-metadata.json index 16c69d4..76bef42 100644 --- a/platform-desktop/trace/reachability-metadata.json +++ b/platform-desktop/trace/reachability-metadata.json @@ -57,12 +57,6 @@ { "type": "[Lcom.simsilica.lemur.focus.FocusChangeListener;" }, - { - "type": "[Lcom.simsilica.lemur.input.AnalogFunctionListener;" - }, - { - "type": "[Lcom.simsilica.lemur.input.StateFunctionListener;" - }, { "type": "[Ljava.awt.event.MouseMotionListener;" }, @@ -75,24 +69,6 @@ } ] }, - { - "type": "com.bulletphysics.collision.dispatch.CompoundCollisionAlgorithm", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.collision.dispatch.ConvexConvexAlgorithm", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "type": "com.bulletphysics.collision.dispatch.UnionFind$Element", "methods": [ @@ -102,87 +78,6 @@ } ] }, - { - "type": "com.bulletphysics.collision.narrowphase.DiscreteCollisionDetectorInterface$ClosestPointInput", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.collision.narrowphase.GjkEpaSolver$Face", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.collision.narrowphase.GjkEpaSolver$He", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.collision.narrowphase.GjkEpaSolver$Mkv", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.collision.narrowphase.ManifoldPoint", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.collision.narrowphase.PersistentManifold", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.collision.narrowphase.VoronoiSimplexSolver$SubSimplexClosestResult", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.dynamics.constraintsolver.SolverBody", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "type": "com.bulletphysics.dynamics.constraintsolver.SolverConstraint", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "type": "com.jme3.asset.CloneableAssetProcessor", "methods": [ @@ -273,15 +168,6 @@ { "type": "com.jme3.cursors.plugins.CursorLoader" }, - { - "type": "com.jme3.export.SavableWrapSerializable", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "type": "com.jme3.export.binary.BinaryLoader" }, @@ -294,24 +180,6 @@ } ] }, - { - "type": "com.jme3.light.PointLight", - "methods": [ - { - "name": "clone", - "parameterTypes": [] - } - ] - }, - { - "type": "com.jme3.light.SpotLight", - "methods": [ - { - "name": "clone", - "parameterTypes": [] - } - ] - }, { "type": "com.jme3.material.Material", "methods": [ @@ -482,15 +350,6 @@ } ] }, - { - "type": "com.jme3.scene.plugins.gltf.LightsPunctualExtensionLoader", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "type": "com.jme3.scene.plugins.gltf.UserDataLoader", "methods": [ @@ -578,9 +437,6 @@ { "type": "com.jme3.texture.plugins.AWTLoader" }, - { - "type": "com.jme3.texture.plugins.AWTWebpImageLoader" - }, { "type": "com.jme3.texture.plugins.DDSLoader" }, @@ -1230,8 +1086,7 @@ }, { "type": "java.nio.DirectFloatBufferU", - "allDeclaredFields": true, - "unsafeAllocated": true + "allDeclaredFields": true }, { "type": "java.nio.DirectIntBufferU", @@ -3152,9 +3007,6 @@ }, { "type": "org.ngengine.nostr4j.signer.NostrNIP46Signer" - }, - { - "type": "org.ngengine.store.DataStore$SerializableEntry" } ], "jni": [ @@ -3784,12 +3636,6 @@ { "type": "java.lang.System", "methods": [ - { - "name": "getProperty", - "parameterTypes": [ - "java.lang.String" - ] - }, { "name": "load", "parameterTypes": [ diff --git a/platform-desktop/trace/resource-config.json b/platform-desktop/trace/resource-config.json index d3b2df9..c7d2e81 100644 --- a/platform-desktop/trace/resource-config.json +++ b/platform-desktop/trace/resource-config.json @@ -1 +1 @@ -{"resources":{"includes":[]},"bundles":[{"name":"com.jme3.app/SettingsDialog","locales":["und"]},{"name":"com.sun.org.apache.xml.internal.serializer.XMLEntities","locales":["und"]},{"name":"com.sun.swing.internal.plaf.basic.resources.basic","classNames":["com.sun.swing.internal.plaf.basic.resources.basic"]},{"name":"com.sun.swing.internal.plaf.metal.resources.metal","classNames":["com.sun.swing.internal.plaf.metal.resources.metal"]},{"name":"sun.awt.resources.awt","locales":["en-US"],"classNames":["sun.awt.resources.awt"]},{"name":"sun.awt.resources.awtosx","locales":["en-US"]}],"globs":[{"glob":"Common/IBL/IBLKernels.frag"},{"glob":"Common/IBL/IBLKernels.j3md"},{"glob":"Common/IBL/IBLKernels.vert"},{"glob":"Common/IBL/Math.glsl"},{"glob":"Common/IBLSphH/IBLSphH.frag"},{"glob":"Common/IBLSphH/IBLSphH.j3md"},{"glob":"Common/IBLSphH/IBLSphH.vert"},{"glob":"Common/MatDefs/Blur/HGaussianBlur.frag"},{"glob":"Common/MatDefs/Blur/HGaussianBlur.j3md"},{"glob":"Common/MatDefs/Blur/VGaussianBlur.frag"},{"glob":"Common/MatDefs/Blur/VGaussianBlur.j3md"},{"glob":"Common/MatDefs/Light/PBRLighting.frag"},{"glob":"Common/MatDefs/Light/PBRLighting.j3md"},{"glob":"Common/MatDefs/Light/PBRLighting.vert"},{"glob":"Common/MatDefs/Misc/Particle.frag"},{"glob":"Common/MatDefs/Misc/Particle.j3md"},{"glob":"Common/MatDefs/Misc/Particle.vert"},{"glob":"Common/MatDefs/Misc/Sky.frag"},{"glob":"Common/MatDefs/Misc/Sky.vert"},{"glob":"Common/MatDefs/Misc/SkyNonCube.j3md"},{"glob":"Common/MatDefs/Misc/Unshaded.frag"},{"glob":"Common/MatDefs/Misc/Unshaded.j3md"},{"glob":"Common/MatDefs/Misc/Unshaded.vert"},{"glob":"Common/MatDefs/Post/BloomExtract.j3md"},{"glob":"Common/MatDefs/Post/BloomFinal.j3md"},{"glob":"Common/MatDefs/Post/FXAA.frag"},{"glob":"Common/MatDefs/Post/FXAA.j3md"},{"glob":"Common/MatDefs/Post/FXAA.vert"},{"glob":"Common/MatDefs/Post/Fog.frag"},{"glob":"Common/MatDefs/Post/Fog.j3md"},{"glob":"Common/MatDefs/Post/KHRToneMap.frag"},{"glob":"Common/MatDefs/Post/KHRToneMap.j3md"},{"glob":"Common/MatDefs/Post/LightScattering.frag"},{"glob":"Common/MatDefs/Post/LightScattering.j3md"},{"glob":"Common/MatDefs/Post/Post.vert"},{"glob":"Common/MatDefs/Post/ToneMap.frag"},{"glob":"Common/MatDefs/Post/ToneMap.j3md"},{"glob":"Common/MatDefs/Post/bloomExtract.frag"},{"glob":"Common/MatDefs/Post/bloomFinal.frag"},{"glob":"Common/MatDefs/SSAO/Textures/random.png"},{"glob":"Common/MatDefs/SSAO/normal.frag"},{"glob":"Common/MatDefs/SSAO/normal.vert"},{"glob":"Common/MatDefs/SSAO/ssao.frag"},{"glob":"Common/MatDefs/SSAO/ssao.j3md"},{"glob":"Common/MatDefs/SSAO/ssaoBlur.frag"},{"glob":"Common/MatDefs/SSAO/ssaoBlur.j3md"},{"glob":"Common/MatDefs/Water/Textures/foam2.jpg"},{"glob":"Common/ShaderLib/ColorUtils.glsl"},{"glob":"Common/ShaderLib/GLSLCompat.glsllib"},{"glob":"Common/ShaderLib/Hdr.glsllib"},{"glob":"Common/ShaderLib/Instancing.glsllib"},{"glob":"Common/ShaderLib/MaterialFog.glsllib"},{"glob":"Common/ShaderLib/Math.glsllib"},{"glob":"Common/ShaderLib/MorphAnim.glsllib"},{"glob":"Common/ShaderLib/MultiSample.glsllib"},{"glob":"Common/ShaderLib/Optics.glsllib"},{"glob":"Common/ShaderLib/PBR.glsllib"},{"glob":"Common/ShaderLib/Parallax.glsllib"},{"glob":"Common/ShaderLib/Skinning.glsllib"},{"glob":"Common/ShaderLib/module/Light.glsl"},{"glob":"Common/ShaderLib/module/PBRSurface.glsl"},{"glob":"Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib"},{"glob":"Interface/Fonts/Console.fnt"},{"glob":"Interface/Fonts/Console.png"},{"glob":"Interface/Fonts/Default.fnt"},{"glob":"Interface/Fonts/Default.png"},{"glob":"META-INF/linux/x64/org/lwjgl/glfw/libglfw.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/jemalloc/libjemalloc.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/liblwjgl.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/nanovg/liblwjgl_nanovg.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/openal/libopenal.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/opengl/liblwjgl_opengl.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/stb/liblwjgl_stb.so.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/glfw/libglfw.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/jemalloc/libjemalloc.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/liblwjgl.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/nanovg/liblwjgl_nanovg.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/openal/libopenal.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/opengl/liblwjgl_opengl.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/stb/liblwjgl_stb.dylib.sha1"},{"glob":"META-INF/services/java.lang.System$LoggerFinder"},{"glob":"META-INF/services/java.net.spi.InetAddressResolverProvider"},{"glob":"META-INF/services/java.net.spi.URLStreamHandlerProvider"},{"glob":"META-INF/services/java.nio.channels.spi.SelectorProvider"},{"glob":"META-INF/services/java.time.zone.ZoneRulesProvider"},{"glob":"META-INF/services/javax.imageio.spi.ImageInputStreamSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageOutputStreamSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageReaderSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageTranscoderSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageWriterSpi"},{"glob":"META-INF/services/javax.xml.parsers.SAXParserFactory"},{"glob":"Materials/PBR.frag"},{"glob":"Materials/PBR.j3md"},{"glob":"Models/boat/boat.bin"},{"glob":"Models/boat/boat.gltf"},{"glob":"Models/boat/boat_BaseColor.jpg"},{"glob":"Models/boat/boat_Metallic-boat_Roughness.jpg"},{"glob":"Models/boat/boat_Normal.jpg"},{"glob":"Models/boat/flag_Normal.jpg"},{"glob":"Models/boat/sail_Metallic-flag_Roughness.jpg"},{"glob":"Models/boat/smallSail_BaseColor.jpg"},{"glob":"Models/boat/smallSail_Metallic-smallSail_Roughness.jpg"},{"glob":"Models/boat/smallSail_Normal.jpg"},{"glob":"Sky/citrus_orchard_puresky_4k.hdr"},{"glob":"Sounds/Beach_Ocean_Waves_Fienup_001_mono.ogg"},{"glob":"Sounds/fato_shadow_-_lunar_strings.ogg"},{"glob":"Sounds/watersplash.ogg"},{"glob":"Textures/waterNoise.png"},{"glob":"adc/city/KB3D_NEC_AirCon_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_AirCon_metallic-KB3D_NEC_AirCon_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_AirCon_normal.jpg"},{"glob":"adc/city/KB3D_NEC_AsphaltHexagonRoof_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_AsphaltHexagonRoof_metallic-KB3D_NEC_AsphaltHexagonRoof_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_AsphaltHexagonRoof_normal.jpg"},{"glob":"adc/city/KB3D_NEC_BannerA_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_BannerA_metallic-KB3D_NEC_BannerA_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_BannerA_normal.jpg"},{"glob":"adc/city/KB3D_NEC_BlackCloth_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_BlackCloth_metallic-KB3D_NEC_BlackCloth_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_BlackCloth_normal.jpg"},{"glob":"adc/city/KB3D_NEC_Brass_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_Brass_metallic-KB3D_NEC_Brass_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_Brass_normal.jpg"},{"glob":"adc/city/KB3D_NEC_Cardboard_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_Cardboard_metallic-KB3D_NEC_Cardboard_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_Cardboard_normal.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteA_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteA_metallic-KB3D_NEC_ConcreteA_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteA_normal.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteB_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteB_metallic-KB3D_NEC_ConcreteB_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteB_normal.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteTiles_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteTiles_metallic-KB3D_NEC_ConcreteTiles_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteTiles_normal.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteWall_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteWall_metallic-KB3D_NEC_ConcreteWall_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_ConcreteWall_normal.jpg"},{"glob":"adc/city/KB3D_NEC_Concrete_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_Concrete_metallic-KB3D_NEC_Concrete_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_Concrete_normal.jpg"},{"glob":"adc/city/KB3D_NEC_DarkPanels_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_DarkPanels_metallic-KB3D_NEC_DarkPanels_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_DarkPanels_normal.jpg"},{"glob":"adc/city/KB3D_NEC_DecalSheet_basecolor-KB3D_NEC_DecalSheet_opacity.png"},{"glob":"adc/city/KB3D_NEC_DecalSheet_metallic-KB3D_NEC_DecalSheet_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_DecalSheet_normal.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteB_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteB_metallic-KB3D_NEC_DecorConcreteB_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteB_normal.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteCBeige_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteCBeige_metallic-KB3D_NEC_DecorConcreteCBeige_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteCBeige_normal.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteCWhite_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteCWhite_metallic-KB3D_NEC_DecorConcreteCWhite_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_DecorConcreteCWhite_normal.jpg"},{"glob":"adc/city/KB3D_NEC_GalvanizedSteelDirt_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_GalvanizedSteelDirt_metallic-KB3D_NEC_GalvanizedSteelDirt_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_GalvanizedSteelDirt_normal.jpg"},{"glob":"adc/city/KB3D_NEC_GalvanizedSteel_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_GalvanizedSteel_metallic-KB3D_NEC_GalvanizedSteel_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_GalvanizedSteel_normal.jpg"},{"glob":"adc/city/KB3D_NEC_GlassBlack_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_GlassBlack_metallic-KB3D_NEC_GlassBlack_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_GlassBlack_normal.jpg"},{"glob":"adc/city/KB3D_NEC_GlassBottle_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_GlassBottle_metallic-KB3D_NEC_GlassBottle_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_GlassBottle_normal.jpg"},{"glob":"adc/city/KB3D_NEC_GlassLamps_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_GlassLamps_metallic-KB3D_NEC_GlassLamps_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_GlassLamps_normal.jpg"},{"glob":"adc/city/KB3D_NEC_GlassTinted_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_GlassTinted_metallic-KB3D_NEC_GlassTinted_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_GlassTinted_normal.jpg"},{"glob":"adc/city/KB3D_NEC_LeavesBush_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_LeavesBush_metallic-KB3D_NEC_LeavesBush_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_LeavesBush_normal.jpg"},{"glob":"adc/city/KB3D_NEC_Letters_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_Letters_metallic-KB3D_NEC_Letters_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_Letters_normal.jpg"},{"glob":"adc/city/KB3D_NEC_LightBlue_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_LightBlue_emissive.jpg"},{"glob":"adc/city/KB3D_NEC_LightBlue_metallic-KB3D_NEC_LightBlue_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_LightBlue_normal.jpg"},{"glob":"adc/city/KB3D_NEC_LightRed_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_LightRed_emissive.jpg"},{"glob":"adc/city/KB3D_NEC_LightRed_metallic-KB3D_NEC_LightRed_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_LightRed_normal.jpg"},{"glob":"adc/city/KB3D_NEC_LightWhite_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_LightWhite_metallic-KB3D_NEC_LightWhite_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_LightWhite_normal.jpg"},{"glob":"adc/city/KB3D_NEC_LightYellow_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_LightYellow_metallic-KB3D_NEC_LightYellow_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_LightYellow_normal.jpg"},{"glob":"adc/city/KB3D_NEC_LightsA_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_LightsA_emissive.jpg"},{"glob":"adc/city/KB3D_NEC_LightsA_metallic-KB3D_NEC_LightsA_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_LightsA_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalAccent_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_MetalAccent_metallic-KB3D_NEC_MetalAccent_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalAccent_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalDarkWorn_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_MetalDarkWorn_metallic-KB3D_NEC_MetalDarkWorn_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalDarkWorn_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalGrating_basecolor-KB3D_NEC_MetalGrating_opacity.png"},{"glob":"adc/city/KB3D_NEC_MetalGrating_metallic-KB3D_NEC_MetalGrating_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalGrating_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalLightGreyWorn_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_MetalLightGreyWorn_metallic-KB3D_NEC_MetalLightGreyWorn_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalLightGreyWorn_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintRed_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintRed_metallic-KB3D_NEC_MetalPaintRed_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintRed_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintWhiteWorn_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintWhiteWorn_metallic-KB3D_NEC_MetalPaintWhiteWorn_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintWhiteWorn_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintWorn_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintWorn_metallic-KB3D_NEC_MetalPaintWorn_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintWorn_normal.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintYellow_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintYellow_metallic-KB3D_NEC_MetalPaintYellow_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_MetalPaintYellow_normal.jpg"},{"glob":"adc/city/KB3D_NEC_OxidizedSteel_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_OxidizedSteel_metallic-KB3D_NEC_OxidizedSteel_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_OxidizedSteel_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PaintBlack_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PaintBlack_metallic-KB3D_NEC_PaintBlack_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PaintBlack_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PaintBlue_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PaintBlue_metallic-KB3D_NEC_PaintBlue_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PaintBlue_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PaintRed_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PaintRed_metallic-KB3D_NEC_PaintRed_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PaintRed_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PaintWhiteRusty_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PaintWhiteRusty_metallic-KB3D_NEC_PaintWhiteRusty_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PaintWhiteRusty_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PaintedMetal_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PaintedMetal_metallic-KB3D_NEC_PaintedMetal_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PaintedMetal_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PaperWhite_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PaperWhite_metallic-KB3D_NEC_PaperWhite_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PaperWhite_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticBlack_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticBlack_metallic-KB3D_NEC_PlasticBlack_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticBlack_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticWhite_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticWhite_metallic-KB3D_NEC_PlasticWhite_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticWhite_normal.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticYellow_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticYellow_metallic-KB3D_NEC_PlasticYellow_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_PlasticYellow_normal.jpg"},{"glob":"adc/city/KB3D_NEC_RedWhiteStripes_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_RedWhiteStripes_metallic-KB3D_NEC_RedWhiteStripes_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_RedWhiteStripes_normal.jpg"},{"glob":"adc/city/KB3D_NEC_Rubber_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_Rubber_metallic-KB3D_NEC_Rubber_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_Rubber_normal.jpg"},{"glob":"adc/city/KB3D_NEC_SatinSteel_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_SatinSteel_metallic-KB3D_NEC_SatinSteel_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_SatinSteel_normal.jpg"},{"glob":"adc/city/KB3D_NEC_Screens_basecolor-KB3D_NEC_Screens_opacity.png"},{"glob":"adc/city/KB3D_NEC_Screens_emissive.jpg"},{"glob":"adc/city/KB3D_NEC_Screens_metallic-KB3D_NEC_Screens_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_Screens_normal.jpg"},{"glob":"adc/city/KB3D_NEC_SpeedwayTiles_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_SpeedwayTiles_metallic-KB3D_NEC_SpeedwayTiles_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_SpeedwayTiles_normal.jpg"},{"glob":"adc/city/KB3D_NEC_SteelRaw_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_SteelRaw_metallic-KB3D_NEC_SteelRaw_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_SteelRaw_normal.jpg"},{"glob":"adc/city/KB3D_NEC_StreetTiles_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_StreetTiles_metallic-KB3D_NEC_StreetTiles_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_StreetTiles_normal.jpg"},{"glob":"adc/city/KB3D_NEC_TarpA_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_TarpA_metallic-KB3D_NEC_TarpA_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_TarpA_normal.jpg"},{"glob":"adc/city/KB3D_NEC_TreeWalnutBark_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_TreeWalnutBark_metallic-KB3D_NEC_TreeWalnutBark_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_TreeWalnutBark_normal.jpg"},{"glob":"adc/city/KB3D_NEC_TreeWlnutLeaf_basecolor-KB3D_NEC_TreeWlnutLeaf_opacity.png"},{"glob":"adc/city/KB3D_NEC_TreeWlnutLeaf_metallic-KB3D_NEC_TreeWlnutLeaf_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_TreeWlnutLeaf_normal.jpg"},{"glob":"adc/city/KB3D_NEC_WhitePanels_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_WhitePanels_metallic-KB3D_NEC_WhitePanels_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_WhitePanels_normal.jpg"},{"glob":"adc/city/KB3D_NEC_WoodDarkGreyTower_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_WoodDarkGreyTower_metallic-KB3D_NEC_WoodDarkGreyTower_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_WoodDarkGreyTower_normal.jpg"},{"glob":"adc/city/KB3D_NEC_WoodLacquered_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_WoodLacquered_metallic-KB3D_NEC_WoodLacquered_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_WoodLacquered_normal.jpg"},{"glob":"adc/city/KB3D_NEC_Wood_basecolor.jpg"},{"glob":"adc/city/KB3D_NEC_Wood_metallic-KB3D_NEC_Wood_roughness.jpg"},{"glob":"adc/city/KB3D_NEC_Wood_normal.jpg"},{"glob":"adc/city/city.bin"},{"glob":"adc/city/city.gltf"},{"glob":"adc/city/missing-texture128x512.jpg"},{"glob":"adc/city/missing-texture256x512.jpg"},{"glob":"adc/city/missing-texture512x.jpg"},{"glob":"adc/city/missing-texture512x256.jpg"},{"glob":"adc/e.q._city.ogg"},{"glob":"adc/footstep.ogg"},{"glob":"adc/jump.ogg"},{"glob":"adc/night-sky.png"},{"glob":"com/jme3/app/Monkey.png"},{"glob":"com/jme3/asset/Desktop.cfg"},{"glob":"com/jme3/asset/General.cfg"},{"glob":"com/jme3/awt.cfg"},{"glob":"com/jme3/system/version.properties"},{"glob":"com/simsilica/lemur/icons/Check.png"},{"glob":"com/simsilica/lemur/icons/border.png"},{"glob":"data/nostrads/adkey.j3o"},{"glob":"data/ocean/iboceandata.j3o"},{"glob":"defaultPlayerImages/0.png"},{"glob":"defaultPlayerImages/1.png"},{"glob":"ibocean/FlipbookTexture.glsl"},{"glob":"ibocean/Ocean.frag"},{"glob":"ibocean/Ocean.glsl"},{"glob":"ibocean/Ocean.j3md"},{"glob":"ibocean/Ocean.vert"},{"glob":"ibocean/OceanRef.glsl"},{"glob":"icons/outline/activity.svg"},{"glob":"icons/outline/chevron-left.svg"},{"glob":"icons/outline/chevron-right.svg"},{"glob":"icons/outline/clipboard.svg"},{"glob":"icons/outline/copy.svg"},{"glob":"icons/outline/dice.svg"},{"glob":"icons/outline/eye-off.svg"},{"glob":"icons/outline/eye.svg"},{"glob":"icons/outline/info-square-rounded.svg"},{"glob":"icons/outline/loader-2.svg"},{"glob":"icons/outline/search.svg"},{"glob":"icons/outline/square-check.svg"},{"glob":"icons/outline/square.svg"},{"glob":"icons/outline/x.svg"},{"glob":"libEGL.so.1"},{"glob":"libGLX.so.0"},{"glob":"libSystem.dylib"},{"glob":"libobjc.dylib"},{"glob":"linux/x64/org/lwjgl/glfw/libglfw.so"},{"glob":"linux/x64/org/lwjgl/jemalloc/libjemalloc.so"},{"glob":"linux/x64/org/lwjgl/liblwjgl.so"},{"glob":"linux/x64/org/lwjgl/nanovg/liblwjgl_nanovg.so"},{"glob":"linux/x64/org/lwjgl/openal/libopenal.so"},{"glob":"linux/x64/org/lwjgl/opengl/liblwjgl_opengl.so"},{"glob":"linux/x64/org/lwjgl/stb/liblwjgl_stb.so"},{"glob":"macos/arm64/org/lwjgl/glfw/libglfw.dylib"},{"glob":"macos/arm64/org/lwjgl/jemalloc/libjemalloc.dylib"},{"glob":"macos/arm64/org/lwjgl/liblwjgl.dylib"},{"glob":"macos/arm64/org/lwjgl/nanovg/liblwjgl_nanovg.dylib"},{"glob":"macos/arm64/org/lwjgl/openal/libopenal.dylib"},{"glob":"macos/arm64/org/lwjgl/opengl/liblwjgl_opengl.dylib"},{"glob":"macos/arm64/org/lwjgl/stb/liblwjgl_stb.dylib"},{"glob":"native/linux/64/libwebp-imageio.so"},{"glob":"org/ngengine/NGE.cfg"},{"glob":"org/ngengine/nostrads/taxonomy/nostr-content-taxonomy.csv"},{"glob":"skies/alienSkyLOWEXP.png"},{"glob":"ui/blurred-qr.png"},{"glob":"ui/frame.png"},{"module":"java.base","glob":"jdk/internal/icu/impl/data/icudt76b/nfc.nrm"},{"module":"java.base","glob":"jdk/internal/icu/impl/data/icudt76b/nfkc.nrm"},{"module":"java.base","glob":"jdk/internal/icu/impl/data/icudt76b/uprops.icu"},{"module":"java.base","glob":"sun/net/idn/uidna.spp"},{"module":"java.datatransfer","glob":"sun/datatransfer/resources/flavormap.properties"},{"module":"java.desktop","glob":"sun/awt/resources/awt_en.properties"},{"module":"java.desktop","glob":"sun/awt/resources/awt_en_US.properties"},{"module":"java.desktop","glob":"sun/awt/resources/awtosx_en.properties"},{"module":"java.desktop","glob":"sun/awt/resources/awtosx_en_US.properties"},{"module":"java.logging","glob":"sun/util/logging/resources/logging_en.properties"},{"module":"java.logging","glob":"sun/util/logging/resources/logging_en_FR.properties"},{"module":"java.logging","glob":"sun/util/logging/resources/logging_en_US.properties"},{"module":"java.xml","glob":"jdk/xml/internal/jdkcatalog/JDKCatalog.xml"}]} +{"resources":{"includes":[]},"bundles":[{"name":"com.jme3.app/SettingsDialog","locales":["und"]},{"name":"com.sun.org.apache.xml.internal.serializer.XMLEntities","locales":["und"]},{"name":"com.sun.swing.internal.plaf.basic.resources.basic","classNames":["com.sun.swing.internal.plaf.basic.resources.basic"]},{"name":"com.sun.swing.internal.plaf.metal.resources.metal","classNames":["com.sun.swing.internal.plaf.metal.resources.metal"]},{"name":"sun.awt.resources.awt","locales":["en-US"],"classNames":["sun.awt.resources.awt"]}],"globs":[{"glob":"Common/IBL/IBLKernels.frag"},{"glob":"Common/IBL/IBLKernels.j3md"},{"glob":"Common/IBL/IBLKernels.vert"},{"glob":"Common/IBL/Math.glsl"},{"glob":"Common/IBLSphH/IBLSphH.frag"},{"glob":"Common/IBLSphH/IBLSphH.j3md"},{"glob":"Common/IBLSphH/IBLSphH.vert"},{"glob":"Common/MatDefs/Light/PBRLighting.frag"},{"glob":"Common/MatDefs/Light/PBRLighting.j3md"},{"glob":"Common/MatDefs/Light/PBRLighting.vert"},{"glob":"Common/MatDefs/Misc/Particle.frag"},{"glob":"Common/MatDefs/Misc/Particle.j3md"},{"glob":"Common/MatDefs/Misc/Particle.vert"},{"glob":"Common/MatDefs/Misc/Sky.frag"},{"glob":"Common/MatDefs/Misc/Sky.vert"},{"glob":"Common/MatDefs/Misc/SkyNonCube.j3md"},{"glob":"Common/MatDefs/Misc/Unshaded.frag"},{"glob":"Common/MatDefs/Misc/Unshaded.j3md"},{"glob":"Common/MatDefs/Misc/Unshaded.vert"},{"glob":"Common/MatDefs/Post/Fog.frag"},{"glob":"Common/MatDefs/Post/Fog.j3md"},{"glob":"Common/MatDefs/Post/LightScattering.frag"},{"glob":"Common/MatDefs/Post/LightScattering.j3md"},{"glob":"Common/MatDefs/Post/Post.vert"},{"glob":"Common/MatDefs/Post/ToneMap.frag"},{"glob":"Common/MatDefs/Post/ToneMap.j3md"},{"glob":"Common/MatDefs/Water/Textures/foam2.jpg"},{"glob":"Common/ShaderLib/ColorUtils.glsl"},{"glob":"Common/ShaderLib/GLSLCompat.glsllib"},{"glob":"Common/ShaderLib/Instancing.glsllib"},{"glob":"Common/ShaderLib/MaterialFog.glsllib"},{"glob":"Common/ShaderLib/Math.glsllib"},{"glob":"Common/ShaderLib/MorphAnim.glsllib"},{"glob":"Common/ShaderLib/MultiSample.glsllib"},{"glob":"Common/ShaderLib/Optics.glsllib"},{"glob":"Common/ShaderLib/PBR.glsllib"},{"glob":"Common/ShaderLib/Parallax.glsllib"},{"glob":"Common/ShaderLib/Skinning.glsllib"},{"glob":"Common/ShaderLib/module/Light.glsl"},{"glob":"Common/ShaderLib/module/PBRSurface.glsl"},{"glob":"Common/ShaderLib/module/pbrlighting/PBRLightingUtils.glsllib"},{"glob":"Interface/Fonts/Console.fnt"},{"glob":"Interface/Fonts/Console.png"},{"glob":"Interface/Fonts/Default.fnt"},{"glob":"Interface/Fonts/Default.png"},{"glob":"META-INF/linux/x64/org/lwjgl/glfw/libglfw.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/jemalloc/libjemalloc.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/liblwjgl.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/openal/libopenal.so.sha1"},{"glob":"META-INF/linux/x64/org/lwjgl/opengl/liblwjgl_opengl.so.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/glfw/libglfw.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/jemalloc/libjemalloc.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/liblwjgl.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/nanovg/liblwjgl_nanovg.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/openal/libopenal.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/opengl/liblwjgl_opengl.dylib.sha1"},{"glob":"META-INF/macos/arm64/org/lwjgl/stb/liblwjgl_stb.dylib.sha1"},{"glob":"META-INF/services/java.lang.System$LoggerFinder"},{"glob":"META-INF/services/java.net.spi.InetAddressResolverProvider"},{"glob":"META-INF/services/java.net.spi.URLStreamHandlerProvider"},{"glob":"META-INF/services/java.nio.channels.spi.SelectorProvider"},{"glob":"META-INF/services/java.time.zone.ZoneRulesProvider"},{"glob":"META-INF/services/javax.imageio.spi.ImageInputStreamSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageOutputStreamSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageReaderSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageTranscoderSpi"},{"glob":"META-INF/services/javax.imageio.spi.ImageWriterSpi"},{"glob":"META-INF/services/javax.xml.parsers.SAXParserFactory"},{"glob":"Materials/PBR.frag"},{"glob":"Materials/PBR.j3md"},{"glob":"Models/boat/boat.bin"},{"glob":"Models/boat/boat.gltf"},{"glob":"Models/boat/boat_BaseColor.jpg"},{"glob":"Models/boat/boat_Metallic-boat_Roughness.jpg"},{"glob":"Models/boat/boat_Normal.jpg"},{"glob":"Models/boat/flag_Normal.jpg"},{"glob":"Models/boat/sail_Metallic-flag_Roughness.jpg"},{"glob":"Models/boat/smallSail_BaseColor.jpg"},{"glob":"Models/boat/smallSail_Metallic-smallSail_Roughness.jpg"},{"glob":"Models/boat/smallSail_Normal.jpg"},{"glob":"Sky/citrus_orchard_puresky_4k.hdr"},{"glob":"Sounds/Beach_Ocean_Waves_Fienup_001_mono.ogg"},{"glob":"Sounds/fato_shadow_-_lunar_strings.ogg"},{"glob":"Sounds/watersplash.ogg"},{"glob":"Textures/waterNoise.png"},{"glob":"com/jme3/app/Monkey.png"},{"glob":"com/jme3/asset/Desktop.cfg"},{"glob":"com/jme3/asset/General.cfg"},{"glob":"com/jme3/system/version.properties"},{"glob":"com/simsilica/lemur/icons/Check.png"},{"glob":"com/simsilica/lemur/icons/border.png"},{"glob":"data/ocean/iboceandata.j3o"},{"glob":"defaultPlayerImages/0.png"},{"glob":"defaultPlayerImages/1.png"},{"glob":"ibocean/FlipbookTexture.glsl"},{"glob":"ibocean/Ocean.frag"},{"glob":"ibocean/Ocean.glsl"},{"glob":"ibocean/Ocean.j3md"},{"glob":"ibocean/Ocean.vert"},{"glob":"ibocean/OceanRef.glsl"},{"glob":"icons/outline/activity.svg"},{"glob":"icons/outline/chevron-left.svg"},{"glob":"icons/outline/chevron-right.svg"},{"glob":"icons/outline/clipboard.svg"},{"glob":"icons/outline/copy.svg"},{"glob":"icons/outline/dice.svg"},{"glob":"icons/outline/eye-off.svg"},{"glob":"icons/outline/eye.svg"},{"glob":"icons/outline/info-square-rounded.svg"},{"glob":"icons/outline/loader-2.svg"},{"glob":"icons/outline/search.svg"},{"glob":"icons/outline/square-check.svg"},{"glob":"icons/outline/square.svg"},{"glob":"icons/outline/x.svg"},{"glob":"libGLX.so.0"},{"glob":"libSystem.dylib"},{"glob":"libobjc.dylib"},{"glob":"linux/x64/org/lwjgl/glfw/libglfw.so"},{"glob":"linux/x64/org/lwjgl/jemalloc/libjemalloc.so"},{"glob":"linux/x64/org/lwjgl/liblwjgl.so"},{"glob":"linux/x64/org/lwjgl/openal/libopenal.so"},{"glob":"linux/x64/org/lwjgl/opengl/liblwjgl_opengl.so"},{"glob":"macos/arm64/org/lwjgl/glfw/libglfw.dylib"},{"glob":"macos/arm64/org/lwjgl/jemalloc/libjemalloc.dylib"},{"glob":"macos/arm64/org/lwjgl/liblwjgl.dylib"},{"glob":"macos/arm64/org/lwjgl/nanovg/liblwjgl_nanovg.dylib"},{"glob":"macos/arm64/org/lwjgl/openal/libopenal.dylib"},{"glob":"macos/arm64/org/lwjgl/opengl/liblwjgl_opengl.dylib"},{"glob":"macos/arm64/org/lwjgl/stb/liblwjgl_stb.dylib"},{"glob":"native/linux/64/libwebp-imageio.so"},{"glob":"org/ngengine/NGE.cfg"},{"glob":"skies/alienSkyLOWEXP.png"},{"glob":"ui/blurred-qr.png"},{"glob":"ui/frame.png"},{"module":"java.base","glob":"jdk/internal/icu/impl/data/icudt76b/nfc.nrm"},{"module":"java.base","glob":"jdk/internal/icu/impl/data/icudt76b/nfkc.nrm"},{"module":"java.base","glob":"jdk/internal/icu/impl/data/icudt76b/uprops.icu"},{"module":"java.base","glob":"sun/net/idn/uidna.spp"},{"module":"java.datatransfer","glob":"sun/datatransfer/resources/flavormap.properties"},{"module":"java.desktop","glob":"sun/awt/resources/awt_en.properties"},{"module":"java.desktop","glob":"sun/awt/resources/awt_en_US.properties"},{"module":"java.logging","glob":"sun/util/logging/resources/logging_en.properties"},{"module":"java.logging","glob":"sun/util/logging/resources/logging_en_FR.properties"},{"module":"java.logging","glob":"sun/util/logging/resources/logging_en_US.properties"},{"module":"java.xml","glob":"jdk/xml/internal/jdkcatalog/JDKCatalog.xml"}]} diff --git a/platform-web/build.gradle b/platform-web/build.gradle new file mode 100644 index 0000000..94c1d76 --- /dev/null +++ b/platform-web/build.gradle @@ -0,0 +1,445 @@ + +plugins { + id 'com.github.node-gradle.node' version '7.1.0' + id "java" + id "war" + id "org.teavm" version "${teaVmVersion}" +} + +import java.security.MessageDigest +import java.nio.file.Files +import java.nio.file.Paths +apply from: "${rootDir}/gradle/libs/class-finder.gradle" + +configurations { + withResources { + canBeResolved = true + } +} + +node { + download = true + distBaseUrl = null + version = "22.18.0" +} + +configurations.configureEach { + exclude group: 'org.ngengine', module: 'jme3-jbullet' +} + +dependencies { + implementation "org.teavm:teavm-jso:${teaVmVersion}" + implementation "org.teavm:teavm-jso-apis:${teaVmVersion}" + implementation "org.teavm:teavm-metaprogramming-api:${teaVmVersion}" + implementation "org.teavm:teavm-classlib:${teaVmVersion}" + implementation "org.teavm:teavm-tooling:${teaVmVersion}" + implementation "org.teavm:teavm-core:${teaVmVersion}" + + implementation "org.ngengine:nge-platform-teavm:${ngePlatformVersion}" + implementation "org.ngengine:nge-app:${ngeVersion}" + implementation "org.ngengine:jme3-plugins-json:${ngeVersion}" + implementation "org.ngengine:nge-web:${ngeVersion}" + implementation "org.ngengine:nge-web-bullet:${ngeVersion}" + + implementation project(':app') + + withResources project(':app') + withResources "org.ngengine:nge-platform-teavm:${ngePlatformVersion}" + withResources "org.ngengine:nge-web:${ngeVersion}" + withResources "org.ngengine:nge-web-bullet:${ngeVersion}" +} + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} + +sourceSets { + test { + resources { + srcDirs = ['src/test/resources', 'src/main/resources'] + } + } +} + +def binaryExclusions = [ + '**/*.class', + '**/*.dll', + '**/*.so', + '**/*.dylib', + '**/package.html', + "**/*.kotlin_builtins", + "**/build.data", + "**/*.xml", + "**/test*.png", + // '**/*.java' +] + + + +def generateHashes(File dir) { + def hashes = [] + Files.walk(Paths.get(dir.toURI())).filter { + Files.isRegularFile(it) + }.forEach { file -> + def relativePath = dir.toPath().relativize(file).toString() + if(relativePath.endsWith(".class")) return; + if(relativePath.endsWith(".java")) return; + def hash = generateSHA256(file.toFile()) + def size = file.toFile().length() + hashes << "$hash $size $relativePath" + } + return hashes.join('\n') +} + +def generateSHA256(file) { + def messageDigest = MessageDigest.getInstance("SHA-256") + file.eachByte(4096) { bytes, len -> + messageDigest.update(bytes, 0, len) + } + return messageDigest.digest().collect { String.format("%02x", it) }.join() +} + +task copyAllResources { + + dependsOn configurations.runtimeClasspath.getTaskDependencyFromProjectDependency(true, 'jar') + dependsOn 'jar' + + ['compileTeavmJava','processTeavmResources','compileJava','processResources'] + .each { tn -> if (tasks.findByName(tn) != null) dependsOn tn } + + doLast { + def dest = file("${rootDir}/dist/web") + dest.mkdirs() + + def safeCopy = { spec -> + copy { + into dest + from spec + exclude(*binaryExclusions) + exclude '**/module-info.class' + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + } + safeCopy('src/main/resources') + + def runtimeFiles = configurations.runtimeClasspath.resolvedConfiguration.lenientConfiguration.files + runtimeFiles.each { f -> + if (!f.exists()) return + if (f.isDirectory()) { + safeCopy(f) + } else if (f.name.endsWith('.jar')) { + safeCopy(project.zipTree(f)) + } + } + + println "Resource aggregation complete. Total files: " + fileTree(dest).matching { exclude(*binaryExclusions) }.files.size() + + def manifestFile = file("${rootDir}/dist/web/manifest.json") + if (manifestFile.exists()) { + def manifest = new groovy.json.JsonSlurper().parseText(manifestFile.text) + manifest.name = Title + manifest.short_name = ShortName + + manifestFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(manifest)) + println "Updated manifest.json: name=$Title, short_name=$ShortName" + } + + def outputDir = file("${rootDir}/dist/web/") + def outputFile = file("${rootDir}/dist/web/resources.index.txt") + + outputFile.text = generateHashes(outputDir) + } +} + + +def generateClassListFile(File outputFile, Collection classes, Closure lineFormatter) { + outputFile.parentFile.mkdirs() + outputFile.text = classes.collect(lineFormatter).join('\n') + println "Generated class list at ${outputFile.absolutePath}" +} + +def generateCodeFromTemplate(File outputFile, String template, Map vars) { + outputFile.parentFile.mkdirs() + String result = template + vars.each { key, value -> + result = result.replace("{{$key}}", value.toString()) + } + outputFile.text = result + println "Generated code at ${outputFile.absolutePath}" +} + +task scanClasspathForTeaVM { + dependsOn configurations.compileClasspath.getTaskDependencyFromProjectDependency(true, 'classes') + doLast { + def scanResults = project.scanClasspathForClasses(project) + + def preserveListFile = file("${buildDir}/generated/teaReflectList.txt") + generateClassListFile(preserveListFile, scanResults.classes) { className -> + "**/${className.replace('.', '/')}.java" + } + + def reflectionSupplierFile = file("${buildDir}/generated/teaReflect.java") + def template = """private static void initGenerated() { +{{classInitializers}} + }""" + generateCodeFromTemplate(reflectionSupplierFile, template, [ + classInitializers: scanResults.reflectionClasses.collect { + " TeaReflectionSupplier.addReflectionClass(\"${it}\");" + }.join('\n') + ]) + } +} + +task updateTeaReflectionSupplier { + dependsOn scanClasspathForTeaVM + doLast { + def reflectionSupplierFile = file("${buildDir}/generated/teaReflect.java") + def teaReflectionSupplierFile = file("${projectDir}/src/main/java/org/ngengine/platform/TeaReflectionSupplier.java") + + if (reflectionSupplierFile.exists() && teaReflectionSupplierFile.exists()) { + def content = teaReflectionSupplierFile.text + def initGeneratedContent = reflectionSupplierFile.text + content = content.replaceAll(/(?s)private static void initGenerated\(\)\s*\{.*?\}/, initGeneratedContent) + teaReflectionSupplierFile.text = content + println "Updated TeaReflectionSupplier.java with generated initGenerated() method" + } + } +} + +tasks.named('compileJava').configure { + dependsOn 'updateTeaReflectionSupplier' +} + +teavm.js { + addedToWebApp = false + mainClass = "org.ngengine.platform.WebLauncher" + obfuscated = false + debugInformation = true + strict= false + outOfProcess=false + // optimization=org.teavm.gradle.api.OptimizationLevel.NONE + sourceMap=true + moduleType = org.teavm.gradle.api.JSModuleType.ES2015 + + def classesToPreserve=[] + def preserveListFile = file("${buildDir}/generated/teaReflectList.txt") + if (preserveListFile.exists()) { + preserveListFile.readLines().each { line -> + if (line.trim()) { + classesToPreserve.add(line.trim()) + } + } + } + + def fqcnToPreserve = new LinkedHashSet() + + def toFqcn = { File baseDir, File f -> + def rel = f.path.substring(baseDir.path.length() + 1) + rel = rel.replaceAll(/\.java$/, '').replaceAll(/\.class$/, '') + rel.replace('/', '.') + } + + rootProject.allprojects.each { prj -> + def ss = prj.extensions.findByName('sourceSets') + def mainSS = ss?.findByName('main') + if (mainSS == null) return + mainSS.java.srcDirs.each { srcDir -> + if (!srcDir.exists()) return + fileTree(srcDir).matching { include classesToPreserve }.forEach { f -> + def fqcn = toFqcn(srcDir, f) + fqcnToPreserve.add(fqcn) + } + } + } + + def rtArtifacts = configurations.runtimeClasspath.resolvedConfiguration.lenientConfiguration.files + rtArtifacts.each { artifact -> + if (!artifact.exists()) return + if (artifact.isDirectory()) { + fileTree(artifact).matching { include classesToPreserve.collect { it.replace('.java', '.class') } }.forEach { f -> + def fqcn = toFqcn(artifact, f) + fqcnToPreserve.add(fqcn) + } + } else if (artifact.name.endsWith('.jar')) { + def classFilePatterns = classesToPreserve.collect { it.replace('.java', '.class') } + .collect { it.replace('**/', '') } + + try { + def jarFile = new java.util.jar.JarFile(artifact) + def entries = jarFile.entries() + + while (entries.hasMoreElements()) { + def entry = entries.nextElement() + if (entry.isDirectory()) continue + + def entryName = entry.getName() + if (classFilePatterns.any { pattern -> + entryName.endsWith(pattern) || entryName.matches(pattern.replace("*", ".*")) + }) { + def fqcn = entryName.replaceAll(/\.class$/, '').replace('/', '.') + fqcnToPreserve.add(fqcn) + } + } + jarFile.close() + } catch (Exception e) { + println "WARNING: Could not process JAR file: ${artifact.name} - ${e.message}" + } + } + } + + fqcnToPreserve.each { + preservedClasses.add(it) + } + + targetFileName = "webapp.js" +} + + + +task buildWebApp { + dependsOn 'compileJava', 'generateJavaScript', 'copyAllResources' + doLast { + def jsDir = file("$buildDir/generated/teavm/js") + def distDir = file("${rootDir}/dist/web") + distDir.mkdirs() + copy { + from jsDir + into distDir + } + println "Copied web app to: $distDir" + } +} + + +task buildBundledWebApp { + dependsOn buildWebApp + doLast { + def jsDir = file("$rootDir/dist/web") + def bundledJsDir = file("$rootDir/dist/web-bundle") + def bundleIgnoreFile = file("$jsDir/bundle-ignore.txt") + def zipFile = file("$bundledJsDir/ngeapp-bundle.zip") + def configFile = file("$bundledJsDir/ngeapp.json") + + bundledJsDir.mkdirs() + + // Read ignore patterns from bundle-ignore.txt + def ignorePatterns = [] + if (bundleIgnoreFile.exists()) { + bundleIgnoreFile.eachLine { line -> + if (line.trim() && !line.startsWith('//')) ignorePatterns.add(line.trim()) + } + println "Found ${ignorePatterns.size()} patterns to exclude from bundle" + } else { + println "Warning: bundle-ignore.txt not found at ${bundleIgnoreFile}. No files will be excluded from the bundle." + } + + + // Create zip with everything except ignored files + ant.zip(destfile: zipFile) { + fileset(dir: jsDir) { + ignorePatterns.each { pattern -> + if (pattern.endsWith('/')) { + exclude(name: "${pattern}**") + } else { + exclude(name: pattern) + } + } + } + } + + + // Copy ignored files to bundledjs directory + if (!ignorePatterns.isEmpty()) { + println "Copying excluded files to bundled directory..." + + delete fileTree(bundledJsDir).matching { include '**/*' exclude 'ngeapp-bundle.zip', 'ngeapp-config.json' } + + fileTree(jsDir).visit { fileDetails -> + if (fileDetails.isDirectory()) return + + def relativePath = fileDetails.relativePath.toString() + def matchesPattern = false + + for (pattern in ignorePatterns) { + if (pattern.endsWith('/')) { + if (relativePath.startsWith(pattern) || relativePath.startsWith(pattern.substring(0, pattern.length() - 1))) { + matchesPattern = true + break + } + } else { + if (relativePath == pattern) { + matchesPattern = true + break + } + } + } + + if (matchesPattern) { + println "Copying excluded file: $relativePath" + copy { + from fileDetails.file + into new File(bundledJsDir, fileDetails.relativePath.parent.toString()) + } + } + } + println "Finished copying excluded files" + } + // Calculate hash of zip file + def hash = generateSHA256(zipFile) + + // Set bundle in config file + def config = [:] + if (configFile.exists()) { + try { + config = new groovy.json.JsonSlurper().parseText(configFile.text) + println "Updating existing config file: $configFile.path" + } catch (Exception e) { + println "Warning: Could not parse existing config file: $e.message" + config = [:] + } + } + + config.bundle = "ngeapp-bundle.zip" + config.bundleHash = hash + configFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(config)) + + println "Created bundle: $zipFile.path" + println "Bundle hash: $hash" + println "Config written to: $configFile.path" + + + + } +} + + +task npmCi(type: NpmTask) { + workingDir = file("${projectDir}") + args = ['ci'] +} + +task runWebApp(type: NpxTask) { + dependsOn buildWebApp + workingDir = file("$rootDir/dist/web") + command = 'http-server' + args = [ '.', '-p', '8000'] +} + +task runBundledWebApp(type: NpxTask) { + dependsOn buildBundledWebApp + workingDir = file("$rootDir/dist/web-bundle") + command = 'http-server' + args = [ '.', '-p', '8000'] +} + +task deployWebApp(type: NpxTask) { + dependsOn buildBundledWebApp + dependsOn npmCi + command = 'nostr-deploy-cli' + args = ['deploy','--skip-setup', '-d', "${rootDir}/dist/web-bundle"] + workingDir = file("${projectDir}") +} + diff --git a/platform-web/package-lock.json b/platform-web/package-lock.json new file mode 100644 index 0000000..5267673 --- /dev/null +++ b/platform-web/package-lock.json @@ -0,0 +1,2033 @@ +{ + "name": "platform-web", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "nostr-deploy-cli": "^0.7.6" + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", + "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@noble/ciphers": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.5.3.tgz", + "integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz", + "integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@peculiar/asn1-cms": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.5.0.tgz", + "integrity": "sha512-p0SjJ3TuuleIvjPM4aYfvYw8Fk1Hn/zAVyPJZTtZ2eE9/MIer6/18ROxX6N/e6edVSfvuZBqhxAj3YgsmSjQ/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "@peculiar/asn1-x509-attr": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-csr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.5.0.tgz", + "integrity": "sha512-ioigvA6WSYN9h/YssMmmoIwgl3RvZlAYx4A/9jD2qaqXZwGcNlAxaw54eSx2QG1Yu7YyBC5Rku3nNoHrQ16YsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-ecc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.5.0.tgz", + "integrity": "sha512-t4eYGNhXtLRxaP50h3sfO6aJebUCDGQACoeexcelL4roMFRRVgB20yBIu2LxsPh/tdW9I282gNgMOyg3ywg/mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pfx": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.5.0.tgz", + "integrity": "sha512-Vj0d0wxJZA+Ztqfb7W+/iu8Uasw6hhKtCdLKXLG/P3kEPIQpqGI4P4YXlROfl7gOCqFIbgsj1HzFIFwQ5s20ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.5.0", + "@peculiar/asn1-pkcs8": "^2.5.0", + "@peculiar/asn1-rsa": "^2.5.0", + "@peculiar/asn1-schema": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.5.0.tgz", + "integrity": "sha512-L7599HTI2SLlitlpEP8oAPaJgYssByI4eCwQq2C9eC90otFpm8MRn66PpbKviweAlhinWQ3ZjDD2KIVtx7PaVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.5.0.tgz", + "integrity": "sha512-UgqSMBLNLR5TzEZ5ZzxR45Nk6VJrammxd60WMSkofyNzd3DQLSNycGWSK5Xg3UTYbXcDFyG8pA/7/y/ztVCa6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.5.0", + "@peculiar/asn1-pfx": "^2.5.0", + "@peculiar/asn1-pkcs8": "^2.5.0", + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "@peculiar/asn1-x509-attr": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.5.0.tgz", + "integrity": "sha512-qMZ/vweiTHy9syrkkqWFvbT3eLoedvamcUdnnvwyyUNv5FgFXA3KP8td+ATibnlZ0EANW5PYRm8E6MJzEB/72Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.5.0.tgz", + "integrity": "sha512-YM/nFfskFJSlHqv59ed6dZlLZqtZQwjRVJ4bBAiWV08Oc+1rSd5lDZcBEx0lGDHfSoH3UziI2pXt2UM33KerPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.5.0.tgz", + "integrity": "sha512-CpwtMCTJvfvYTFMuiME5IH+8qmDe3yEWzKHe7OOADbGfq7ohxeLaXwQo0q4du3qs0AII3UbLCvb9NF/6q0oTKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "asn1js": "^3.0.6", + "pvtsutils": "^1.3.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.5.0.tgz", + "integrity": "sha512-9f0hPOxiJDoG/bfNLAFven+Bd4gwz/VzrCIIWc1025LEI4BXO0U5fOCTNDPbbp2ll+UzqKsZ3g61mpBp74gk9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "asn1js": "^3.0.6", + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.0.tgz", + "integrity": "sha512-Yc4PDxN3OrxUPiXgU63c+ZRXKGE8YKF2McTciYhUHFtHVB0KMnjeFSU0qpztGhsp4P0uKix4+J2xEpIEDu8oXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.5.0", + "@peculiar/asn1-csr": "^2.5.0", + "@peculiar/asn1-ecc": "^2.5.0", + "@peculiar/asn1-pkcs9": "^2.5.0", + "@peculiar/asn1-rsa": "^2.5.0", + "@peculiar/asn1-schema": "^2.5.0", + "@peculiar/asn1-x509": "^2.5.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + } + }, + "node_modules/@scure/base": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz", + "integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@scure/bip32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz", + "integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.1.0", + "@noble/hashes": "~1.3.1", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz", + "integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.1" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.2.1.tgz", + "integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.3.0", + "@scure/base": "~1.1.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@types/node": { + "version": "24.5.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~7.12.0" + } + }, + "node_modules/acme-client": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/acme-client/-/acme-client-5.4.0.tgz", + "integrity": "sha512-mORqg60S8iML6XSmVjqjGHJkINrCGLMj2QvDmFzI9vIlv1RGlyjmw3nrzaINJjkNsYXC41XhhD5pfy7CtuGcbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@peculiar/x509": "^1.11.0", + "asn1js": "^3.0.5", + "axios": "^1.7.2", + "debug": "^4.3.5", + "node-forge": "^1.3.1" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/archiver": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-6.0.2.tgz", + "integrity": "sha512-UQ/2nW7NMl1G+1UnrLypQw1VdT9XZg/ECcKPq7l+STzStrSivFIXIp34D8M5zeNGW5NoOupdYCHv6VySCPNNlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^4.0.1", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^5.0.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/archiver-utils": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-4.0.1.tgz", + "integrity": "sha512-Q4Q99idbvzmgCTEAAhi32BkOyq8iVI5EwdO0PmBDSGIzzjYNdcFn7Q7k3OzbLy4kLUPXfJtG6fO2RjftXbobBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^8.0.0", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/archiver-utils/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/archiver-utils/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/asn1js": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.6.tgz", + "integrity": "sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "dev": true, + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz", + "integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bufferutil": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.9.tgz", + "integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compress-commons": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-5.0.3.tgz", + "integrity": "sha512-/UIcLWvwAQyVibgpQDPtfNM3SvqN7G9elAPAV7GM0L53EbNWwWiCsWtK8Fwed/APEbptPHXs5PuW+y8Bq8lFTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^5.0.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-5.0.1.tgz", + "integrity": "sha512-lO1dFui+CEUh/ztYIpgpKItKW9Bb4NWakCRJrnqAbFIYD+OZAwb2VfD5T5eXMw2FNcsDHkQcNl/Wh3iVXYwU6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.7", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.7.tgz", + "integrity": "sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nostr-deploy-cli": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/nostr-deploy-cli/-/nostr-deploy-cli-0.7.6.tgz", + "integrity": "sha512-iTLMnhGwDD9ZKkCHZiIiIzdvv5X5bEk/sHLy+vi9uh9XrBmJR2foCdsqV543+yWhuLuwGXh4G5ubK/m/crEa8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acme-client": "^5.0.0", + "archiver": "^6.0.1", + "axios": "^1.6.2", + "chalk": "^4.1.2", + "commander": "^11.1.0", + "dotenv": "^16.3.1", + "form-data": "^4.0.0", + "fs-extra": "^11.2.0", + "inquirer": "^8.2.6", + "nostr-tools": "^2.1.0", + "ora": "^5.4.1", + "websocket-polyfill": "^0.0.3" + }, + "bin": { + "nostr-deploy-cli": "dist/cli.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/nostr-deploy-cli/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/nostr-tools": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.17.0.tgz", + "integrity": "sha512-lrvHM7cSaGhz7F0YuBvgHMoU2s8/KuThihDoOYk8w5gpVHTy0DeUCAgCN8uLGeuSl5MAWekJr9Dkfo5HClqO9w==", + "dev": true, + "license": "Unlicense", + "dependencies": { + "@noble/ciphers": "^0.5.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.1", + "@scure/base": "1.1.1", + "@scure/bip32": "1.3.1", + "@scure/bip39": "1.2.1", + "nostr-wasm": "0.1.0" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/nostr-wasm": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/nostr-wasm/-/nostr-wasm-0.1.0.tgz", + "integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", + "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tstl": { + "version": "2.5.16", + "resolved": "https://registry.npmjs.org/tstl/-/tstl-2.5.16.tgz", + "integrity": "sha512-+O2ybLVLKcBwKm4HymCEwZIT0PpwS3gCYnxfSDEjJEKADvIFruaQjd3m7CAKNU1c7N3X3WjVz87re7TA2A5FUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.12.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/websocket": { + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.35.tgz", + "integrity": "sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.63", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket-polyfill": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/websocket-polyfill/-/websocket-polyfill-0.0.3.tgz", + "integrity": "sha512-pF3kR8Uaoau78MpUmFfzbIRxXj9PeQrCuPepGE6JIsfsJ/o/iXr07Q2iQNzKSSblQJ0FiGWlS64N4pVSm+O3Dg==", + "dev": true, + "dependencies": { + "tstl": "^2.0.7", + "websocket": "^1.0.28" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaeti": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", + "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/zip-stream": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-5.0.2.tgz", + "integrity": "sha512-LfOdrUvPB8ZoXtvOBz6DlNClfvi//b5d56mSWyJi7XbH/HfhOHfUhOqxhT/rUiR7yiktlunqRo+jY6y/cWC/5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "archiver-utils": "^4.0.1", + "compress-commons": "^5.0.1", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + } + } +} diff --git a/platform-web/package.json b/platform-web/package.json new file mode 100644 index 0000000..6d8a22a --- /dev/null +++ b/platform-web/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "nostr-deploy-cli": "^0.7.6" + } +} diff --git a/platform-web/src/main/java/org/ngengine/platform/TeaReflectionSupplier.java b/platform-web/src/main/java/org/ngengine/platform/TeaReflectionSupplier.java new file mode 100644 index 0000000..d3f1c0d --- /dev/null +++ b/platform-web/src/main/java/org/ngengine/platform/TeaReflectionSupplier.java @@ -0,0 +1,744 @@ +package org.ngengine.platform; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; + +import org.teavm.classlib.ReflectionContext; +import org.teavm.classlib.ReflectionSupplier; +import org.teavm.model.ClassReader; +import org.teavm.model.FieldReader; + +import org.teavm.model.MethodDescriptor; +import org.teavm.model.MethodReader; +import org.teavm.model.ValueType; + +public class TeaReflectionSupplier implements ReflectionSupplier { + private static ArrayList regexPatterns = new ArrayList<>(); + + private static ArrayList> clazzList = new ArrayList<>(); + private static ArrayList clazzNameList = new ArrayList<>(); + static { + init(); + } + + private static void initGenerated() { + TeaReflectionSupplier.addReflectionClass("com.jcraft.jzlib.Deflate"); + TeaReflectionSupplier.addReflectionClass("com.jcraft.jzlib.GZIPHeader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.AnimClip"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.AnimComposer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.AnimLayer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.AnimTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.Armature"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.ArmatureMask"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.Joint"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.MatrixJointModelTransform"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.MorphControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.MorphTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.SeparateJointModelTransform"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.SingleLayerInfluenceMask"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.SkinningControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.TransformTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.tween.AbstractTween"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.tween.Tween"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.tween.action.Action"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.tween.action.BaseAction"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.tween.action.BlendAction"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.tween.action.BlendableAction"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.tween.action.ClipAction"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.util.HasLocalTransform"); + TeaReflectionSupplier.addReflectionClass("com.jme3.anim.util.JointModelTransform"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.AnimControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.Animation"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.AudioTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.Bone"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.BoneTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.ClonableTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.CompactArray"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.CompactFloatArray"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.CompactQuaternionArray"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.CompactVector3Array"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.EffectTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.Pose"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.PoseTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.Skeleton"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.SkeletonControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.SpatialTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.Track"); + TeaReflectionSupplier.addReflectionClass("com.jme3.animation.TrackInfo"); + TeaReflectionSupplier.addReflectionClass("com.jme3.app.StatsView"); + TeaReflectionSupplier.addReflectionClass("com.jme3.app.state.ScreenshotAppState"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.AssetKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.AssetLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.AssetLocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.AssetProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.CloneableAssetProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.CloneableSmartAsset"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.FilterKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.MaterialKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.ModelKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.ShaderNodeDefinitionKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.TextureKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.cache.AssetCache"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.cache.SimpleAssetCache"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.cache.WeakRefAssetCache"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.cache.WeakRefCloneAssetCache"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.plugins.ClasspathLocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.plugins.FileLocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.plugins.HttpZipLocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.plugins.UrlLocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.asset.plugins.ZipLocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.AudioBuffer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.AudioData"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.AudioKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.AudioNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.AudioStream"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.BandPassFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.Filter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.HighPassFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.LowPassFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.plugins.OGGLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.audio.plugins.WAVLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bounding.BoundingBox"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bounding.BoundingSphere"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bounding.BoundingVolume"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.animation.BoneLink"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.animation.DacConfiguration"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.animation.DacLinks"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.animation.DynamicAnimControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.animation.PhysicsLink"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.animation.RangeOfMotion"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.animation.TorsoLink"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.PhysicsCollisionObject"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.BoxCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.CapsuleCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.CollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.CompoundCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.ConeCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.CylinderCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.GImpactCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.HeightfieldCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.HullCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.MeshCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.PlaneCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.SimplexCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.SphereCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.collision.shapes.infos.ChildCollisionShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.AbstractPhysicsControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.BetterCharacterControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.CharacterControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.GhostControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.KinematicRagdollControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.PhysicsControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.RigidBodyControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.control.VehicleControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.debug.AbstractPhysicsDebugControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.debug.BulletCharacterDebugControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.debug.BulletGhostObjectDebugControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.debug.BulletJointDebugControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.debug.BulletRigidBodyDebugControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.debug.BulletVehicleDebugControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.joints.ConeJoint"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.joints.HingeJoint"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.joints.PhysicsJoint"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.joints.Point2PointJoint"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.joints.SixDofJoint"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.joints.SliderJoint"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.objects.PhysicsCharacter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.objects.PhysicsGhostObject"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.objects.PhysicsRigidBody"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.objects.PhysicsVehicle"); + TeaReflectionSupplier.addReflectionClass("com.jme3.bullet.objects.VehicleWheel"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.Cinematic"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.KeyFrame"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.MotionPath"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.TimeLine"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.AbstractCinematicEvent"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.AnimEvent"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.AnimationEvent"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.AnimationTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.CameraEvent"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.CinematicEvent"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.MotionEvent"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.MotionTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.SoundEvent"); + TeaReflectionSupplier.addReflectionClass("com.jme3.cinematic.events.SoundTrack"); + TeaReflectionSupplier.addReflectionClass("com.jme3.collision.bih.BIHNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.collision.bih.BIHTree"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.ParticleEmitter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.ParticleMesh"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.ParticlePointMesh"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.ParticleTriMesh"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.influencers.DefaultParticleInfluencer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.influencers.EmptyParticleInfluencer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.influencers.NewtonianParticleInfluencer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.influencers.ParticleInfluencer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.influencers.RadialParticleInfluencer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.shapes.EmitterBoxShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.shapes.EmitterMeshConvexHullShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.shapes.EmitterMeshFaceShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.shapes.EmitterMeshVertexShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.shapes.EmitterPointShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.shapes.EmitterShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.effect.shapes.EmitterSphereShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.environment.EnvironmentProbeControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.environment.util.BoundingSphereDebug"); + TeaReflectionSupplier.addReflectionClass("com.jme3.environment.util.Circle"); + TeaReflectionSupplier.addReflectionClass("com.jme3.export.JmeImporter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.export.NullSavable"); + TeaReflectionSupplier.addReflectionClass("com.jme3.export.Savable"); + TeaReflectionSupplier.addReflectionClass("com.jme3.export.binary.BinaryImporter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.export.binary.BinaryLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.export.xml.XMLImporter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.BitmapCharacter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.BitmapCharacterSet"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.BitmapFont"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.BitmapText"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.BitmapTextPage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.GlyphParser"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.Kerning"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.Rectangle"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.StringBlock"); + TeaReflectionSupplier.addReflectionClass("com.jme3.font.plugins.BitmapFontLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.input.ChaseCamera"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.AmbientLight"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.DirectionalLight"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.Light"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.LightList"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.LightProbe"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.OrientedBoxProbeArea"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.PointLight"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.ProbeArea"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.SphereProbeArea"); + TeaReflectionSupplier.addReflectionClass("com.jme3.light.SpotLight"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.MatParam"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.MatParamOverride"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.MatParamTexture"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.Material"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.MaterialList"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.MaterialProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.RenderState"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.ShaderGenerationInfo"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.Technique"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.TechniqueDef"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.logic.DefaultTechniqueDefLogic"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.logic.MultiPassLightingLogic"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.logic.SinglePassAndImageBasedLightingLogic"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.logic.SinglePassLightingLogic"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.logic.StaticPassLightingLogic"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.logic.TechniqueDefLogic"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.plugins.J3MLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.material.plugins.ShaderNodeDefinitionLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.ColorRGBA"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Line"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.LineSegment"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Matrix3f"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Matrix4f"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Plane"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Quaternion"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Ray"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Rectangle"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Ring"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Spline"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Transform"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Triangle"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Vector2f"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Vector3f"); + TeaReflectionSupplier.addReflectionClass("com.jme3.math.Vector4f"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.AbstractMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.Message"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.message.ChannelInfoMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.message.ClientRegistrationMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.message.CompressedMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.message.DisconnectMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.message.GZIPCompressedMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.message.SerializerRegistrationsMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.message.ZIPCompressedMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.rmi.RemoteMethodCallMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.rmi.RemoteMethodReturnMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.rmi.RemoteObjectDefMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.service.rpc.msg.RpcCallMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.network.service.rpc.msg.RpcResponseMessage"); + TeaReflectionSupplier.addReflectionClass("com.jme3.plugins.gson.GsonParser"); + TeaReflectionSupplier.addReflectionClass("com.jme3.plugins.json.JsonParser"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.Filter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.FilterPostProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.HDRRenderer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.PreDepthProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.SceneProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.BloomFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.CartoonEdgeFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.ColorOverlayFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.ComposeFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.ContrastAdjustmentFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.CrossHatchFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.DepthOfFieldFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.FXAAFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.FadeFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.FogFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.GammaCorrectionFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.KHRToneMapFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.LightScatteringFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.PosterizationFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.RadialBlurFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.SoftBloomFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.ToneMapFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.filters.TranslucentBucketFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.post.ssao.SSAOFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.renderer.Camera"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.AssetLinkNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.BatchNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.CameraNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.CollisionData"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.Geometry"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.GeometryGroupNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.LightNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.Mesh"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.Node"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.SimpleBatchNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.Spatial"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.UserData"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.VertexBuffer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.control.AbstractControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.control.BillboardControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.control.CameraControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.control.Control"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.control.LightControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.control.LodControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.control.UpdateControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.Arrow"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.Grid"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.SkeletonDebugger"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.SkeletonInterBoneWire"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.SkeletonPoints"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.SkeletonWire"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.WireBox"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.WireFrustum"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.WireSphere"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.custom.ArmatureDebugger"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.custom.ArmatureInterJointsWire"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.custom.ArmatureNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.debug.custom.JointShape"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.instancing.InstancedGeometry"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.instancing.InstancedNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.mesh.MorphTarget"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.IrBoneWeightIndex"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.IrVertex"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.MTLLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.OBJLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.fbx.ContentTextureKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.fbx.ContentTextureLocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.fbx.FbxLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.fbx.SceneKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.fbx.SceneLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.fbx.SceneWithAnimationLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.gltf.BinDataKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.gltf.BinLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.gltf.GlbLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.gltf.GltfLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.gltf.GltfModelKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.ogre.MaterialLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.ogre.MeshLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.ogre.OgreMeshKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.ogre.SceneLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.ogre.SceneMeshLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.ogre.SkeletonLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.plugins.ogre.matext.OgreMaterialKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.AbstractBox"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Box"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.CenterQuad"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Curve"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Cylinder"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Dome"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Line"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.PQTorus"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Quad"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.RectangleMesh"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Sphere"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.StripBox"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Surface"); + TeaReflectionSupplier.addReflectionClass("com.jme3.scene.shape.Torus"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.Shader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.ShaderNode"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.ShaderNodeDefinition"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.ShaderNodeVariable"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.VariableMapping"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.bufferobject.BufferObject"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.bufferobject.BufferRegion"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.plugins.GLSLLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shader.plugins.ShaderAssetKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.AbstractShadowFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.AbstractShadowRenderer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.BasicShadowRenderer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.DirectionalLightShadowFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.DirectionalLightShadowRenderer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.PointLightShadowFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.PointLightShadowRenderer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.PssmShadowFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.PssmShadowRenderer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.SpotLightShadowFilter"); + TeaReflectionSupplier.addReflectionClass("com.jme3.shadow.SpotLightShadowRenderer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.system.AppSettings"); + TeaReflectionSupplier.addReflectionClass("com.jme3.system.JmeSystem"); + TeaReflectionSupplier.addReflectionClass("com.jme3.system.JmeSystemDelegate"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.GeoMap"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.LODGeomap"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.MultiTerrainLodControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.NormalRecalcControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.TerrainGrid"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.TerrainGridLodControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.TerrainGridTileLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.TerrainLodControl"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.TerrainPatch"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.TerrainQuad"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.grid.AssetTileLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.grid.FractalTileLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.grid.ImageTileLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.lodcalc.LodCalculator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.lodcalc.LodThreshold"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.lodcalc.PerspectiveLodCalculator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.terrain.geomipmap.lodcalc.SimpleLodThreshold"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.FrameBuffer"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.Image"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.Texture"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.Texture2D"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.Texture3D"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.TextureArray"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.TextureCubeMap"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.TextureProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.plugins.DDSLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.plugins.PFMLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.plugins.SVGTextureKey"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.plugins.TGALoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.texture.plugins.ktx.KTXLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.ui.Picture"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.BufferAllocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.IntMap"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.ListMap"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.NativeObject"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.PrimitiveAllocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.ReflectionAllocator"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.SafeArrayList"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.clone.JmeCloneable"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.res.DefaultResourceLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.res.ResourceLoader"); + TeaReflectionSupplier.addReflectionClass("com.jme3.util.struct.StructStd140BufferObject"); + TeaReflectionSupplier.addReflectionClass("com.jme3.water.ReflectionProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.water.SimpleWaterProcessor"); + TeaReflectionSupplier.addReflectionClass("com.jme3.water.WaterFilter"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.ActionButton"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Button"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Checkbox"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Container"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.GridPanel"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Insets3f"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Label"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.ListBox"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.OptionPanel"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Panel"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.PasswordField"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.ProgressBar"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.RollupPanel"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Selector"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Slider"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.Spinner"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.TabbedPanel"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.TextField"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.AbstractGuiComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.BorderLayout"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.BoxLayout"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.DynamicInsetsComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.IconComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.InsetsComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.QuadBackgroundComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.SpringGridLayout"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.TbtQuadBackgroundComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.Text2d"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.TextComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.component.TextEntryComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.AbstractNodeControl"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.CommandMap"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.GuiComponent"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.GuiControl"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.GuiLayout"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.GuiMaterial"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.LightingMaterialAdapter"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.core.UnshadedMaterialAdapter"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.dnd.DragAndDropControl"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.effect.EffectControl"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.event.CursorEventControl"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.event.MouseEventControl"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.focus.DefaultFocusTraversalControl"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.geom.DMesh"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.geom.MBox"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.geom.TbtQuad"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.list.DefaultCellRenderer"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.style.Attributes"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.style.ContainsSelector"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.style.ElementId"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.style.ElementSelector"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.style.Selector"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.style.StyleTree"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.style.Styles"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.text.DefaultDocumentModel"); + TeaReflectionSupplier.addReflectionClass("com.simsilica.lemur.value.DefaultValueRenderer"); + TeaReflectionSupplier.addReflectionClass("de.jarnbjo.vorbis.Floor1"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.ads.ImmersiveAdComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.ads.ImmersiveAdControl"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.Auth"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.AuthConfig"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.AuthSelectionWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.AuthStrategy"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.Nip46AuthStrategy"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.nip07.Nip07Auth"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.nip07.Nip07AuthWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.nip46.Nip46Auth"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.nip46.Nip46AuthWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.nip46.Nip46ChallengeWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.nsec.NsecAuth"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.nsec.NsecAuthWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.auth.stored.StoredAuthSelectionWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.Component"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.StallingComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.AppFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.AssetLoadingFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.AsyncAssetLoadingFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.Fragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.GuiViewPortFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.InputHandlerFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.LogicFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.MainViewPortFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.components.fragments.RenderFragment"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.demo.adc.CharacterComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.demo.adc.HudComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.demo.adc.LoadingScreenComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.demo.adc.MapComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.demo.adc.PhysicsComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.demo.adc.PostprocessingComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.demo.adc.SoundComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.CollectionSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.MapSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.Nip46MetadataSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.Nip46SignerSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.NostrEventSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.NostrKeyPairSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.NostrPrivateKeySavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.NostrPublicKeySavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.NostrRelayInfoSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.NumberSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.SavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.export.StringSavableWrapper"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NAspectPreservingQuadBackground"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NButton"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NIconButton"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NLabel"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NLoadingSpinner"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NQrViewer"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NSVGIcon"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NTextInput"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.NVSpacer"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.containers.NColumn"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.containers.NContainer"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.containers.NMultiPageList"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.containers.NPanel"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.components.containers.NRow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.qr.BitBuffer"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.win.NToast"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.win.NWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.win.NWindowManagerComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.win.std.NConfirmDialogWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.win.std.NErrorWindow"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.gui.win.std.NHud"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.lnurl.LnUrlPayerData"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.Lobby"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.LocalLobby"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.protocol.messages.BinaryMessage"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.protocol.messages.ByteDataMessage"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.protocol.messages.ClassRegistrationAckMessage"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.protocol.messages.CompressedMessage"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.protocol.messages.TextDataMessage"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.network.protocol.messages.TextMessage"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.NostrFilter"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.NostrRelayInfo"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.NostrRelayLifecycleManager"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.NostrRelaySubManager"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.event.NostrEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.event.SignedNostrEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.event.UnsignedNostrEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.keypair.NostrKey"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.keypair.NostrKeyPair"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.keypair.NostrPrivateKey"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.keypair.NostrPublicKey"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.listeners.NostrRelayComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.nip01.Nip01UserMetadataFilter"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.nip05.Nip05Nip46Data"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.nip46.BunkerUrl"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.nip46.Nip46AppMetadata"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.nip46.NostrconnectUrl"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.nip50.NostrSearchFilter"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.rtc.turn.NostrTURNSettings"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.signer.NostrKeyPairSigner"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.signer.NostrNIP07Signer"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.signer.NostrNIP46Signer"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostr4j.signer.NostrSigner"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.AdBidEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.AdBidFilter"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.AdEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.negotiation.AdAcceptOfferEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.negotiation.AdBailEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.negotiation.AdNegotiationEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.negotiation.AdOfferEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.negotiation.AdPaymentRequestEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.negotiation.AdPayoutEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.nostrads.protocol.negotiation.AdPowNegotiationEvent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.platform.RTCSettings"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.player.PlayerManagerComponent"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.web.context.HeapAllocator"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.web.context.WebSystem"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.web.filesystem.WebImageLoader"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.web.filesystem.WebLocator"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.web.filesystem.WebResourceLoader"); + TeaReflectionSupplier.addReflectionClass("org.ngengine.web.json.TeaJSONParser"); + } + + private static void init() { + initGenerated(); + } + + public static void addReflectionClass(Class c) { + clazzList.add(c); + } + + public static void addReflectionClass(String className) { + clazzNameList.add(className); + } + + + public static void addRegex(String regex) { + regexPatterns.add(Pattern.compile(regex)); + } + public TeaReflectionSupplier() { + System.out.println("TeaReflectionSupplier initialized"); + + } + + @Override + public Collection getAccessibleFields(ReflectionContext context, String className) { + Set fields = new HashSet<>(); + ClassReader cls = context.getClassSource().get(className); + if (cls == null) { + return Collections.emptyList(); + } + try { + + Class clazz = context.getClassLoader().loadClass(className); + + if (cls != null) { + if (canHaveReflection(clazz)) { + for (FieldReader field : cls.getFields()) { + String name = field.getName(); + fields.add(name); + } + } + } + } catch (ClassNotFoundException e) { + new RuntimeException(e); + } + + return fields; + } + + private boolean isWhitelistedType(ReflectionContext context, ValueType t) throws ClassNotFoundException{ + boolean canHaveReflection = false; + if (t instanceof ValueType.Void) { + return true; + } + if (t instanceof ValueType.Array) { + ValueType.Array a = (ValueType.Array) t; + t = a.getItemType(); + + } + if (t instanceof ValueType.Object) { + ValueType.Object obj = (ValueType.Object) t; + if(obj.getClassName().startsWith("java.lang")) { + canHaveReflection = true; + } else { + Class sc = context.getClassLoader().loadClass(obj.getClassName()); + canHaveReflection = canHaveReflection(sc); + } + } else if (t instanceof ValueType.Primitive) { + canHaveReflection = true; + } + return canHaveReflection; + + } + + @Override + public Collection getAccessibleMethods(ReflectionContext context, String className) { + Set methods = new HashSet<>(); + + ClassReader cls = context.getClassSource().get(className); + if (cls == null) { + return Collections.emptyList(); + } + try { + Class clazz = context.getClassLoader().loadClass(className); + + if (canHaveReflection(clazz)) { + Collection methods2 = cls.getMethods(); + int constructors = 0; + for (MethodReader method : methods2) { + + boolean isConstructor = method.getName().equals(""); + if(isConstructor) { + constructors++; + } + + boolean canHaveReflection = true; + + + if (canHaveReflection && !isConstructor) { + ValueType t = method.getResultType(); + canHaveReflection = isWhitelistedType(context, t); + } + + if (!canHaveReflection) { + continue; + } + + MethodDescriptor descriptor = method.getDescriptor(); + methods.add(descriptor); + } + } + } catch (ClassNotFoundException e) { + new RuntimeException(e); + } + return methods; + } + + private boolean canHaveReflection(Class clazz) { + for (Class c : clazzList) { + + if (c.isAssignableFrom(clazz) || c.equals(clazz)) { + return true; + } + } + String className = clazz.getName(); + for(String cn : clazzNameList) { + if(cn.equals(className)) { + return true; + } + } + for (Pattern pattern : regexPatterns) { + if (pattern.matcher(className).matches()) { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/platform-web/src/main/java/org/ngengine/platform/WebLauncher.java b/platform-web/src/main/java/org/ngengine/platform/WebLauncher.java new file mode 100644 index 0000000..e1c61cf --- /dev/null +++ b/platform-web/src/main/java/org/ngengine/platform/WebLauncher.java @@ -0,0 +1,21 @@ +package org.ngengine.platform; + +import org.ngengine.NGEApplication.NGEAppRunner; +import org.ngengine.app.Main; +import org.ngengine.platform.teavm.TeaVMPlatform; +import org.ngengine.web.context.WebSystem; +import com.jme3.system.JmeSystem; + + +public class WebLauncher { + + public static void main(String[] args) { + new Thread(()->{ // must be a thread to run in a suspendable context in teavm + NGEPlatform.set(new TeaVMPlatform()); + JmeSystem.setSystemDelegate(new WebSystem()); + + NGEAppRunner runner = Main.main(args); + runner.start(); + }).start(); + } +} \ No newline at end of file diff --git a/platform-web/src/main/resources/META-INF/services/org.teavm.classlib.ReflectionSupplier b/platform-web/src/main/resources/META-INF/services/org.teavm.classlib.ReflectionSupplier new file mode 100644 index 0000000..69e2408 --- /dev/null +++ b/platform-web/src/main/resources/META-INF/services/org.teavm.classlib.ReflectionSupplier @@ -0,0 +1 @@ +org.ngengine.platform.TeaReflectionSupplier diff --git a/platform-web/src/main/resources/manifest.json b/platform-web/src/main/resources/manifest.json new file mode 100644 index 0000000..264545b --- /dev/null +++ b/platform-web/src/main/resources/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "Nostr Game Engine Web App", + "short_name": "ngewebapp", + "start_url": "index.html", + "display": "standalone", + "icons": [{ + "src": "logo.webp", + "sizes": "4096x4096", + "type": "image/webp" + }], + "background_color": "#08020c", + "theme_color": "#08020c" +} diff --git a/release-logging.properties b/release-logging.properties new file mode 100644 index 0000000..4774e96 --- /dev/null +++ b/release-logging.properties @@ -0,0 +1,11 @@ +# Global logging level - set to a higher threshold +.level = INFO + +# Handler (console or file) +handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = INFO +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter + +# Set FINEST logging only for org.ngengine.nostr4j and its children +org.ngengine.nostr4j.level = INFO +org.ngengine.level = INFO \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7eaa4dd..15ac6df 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,9 +5,11 @@ pluginManagement { google() mavenCentral() gradlePluginPortal() + maven { url = uri("https://teavm.org/maven/repository") } + mavenLocal() } plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.9.0' + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" id("com.android.application") version '8.12.2' apply false id("com.android.library") version '8.12.2' apply false id("org.jetbrains.kotlin.android") version "2.1.20" apply false @@ -16,8 +18,19 @@ pluginManagement { +plugins { + id("org.gradle.toolchains.foojay-resolver") version "1.0.0" +} - +toolchainManagement { + jvm { + javaRepositories { + repository("foojay") { + resolverClass = org.gradle.toolchains.foojay.FoojayToolchainResolver + } + } + } +} dependencyResolutionManagement { repositories { @@ -27,18 +40,58 @@ dependencyResolutionManagement { maven { url = uri("https://central.sonatype.com/repository/maven-snapshots") } + maven { url = uri("https://teavm.org/maven/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") + } + } } } - -rootProject.name = settings.projectName -include('app') - -if(withDesktopPlatform) { - include('platform-desktop') +if (!gradle.hasProperty('ext')) { + gradle.ext {} } -// if (withAndroidPlatform) { -// include('platform-android') -// } \ No newline at end of file +gradle.beforeProject { p -> + if (p == p.rootProject) { + p.tasks.register("cleanDist", org.gradle.api.tasks.Delete) { + delete p.layout.projectDirectory.dir("dist") + } + p.gradle.projectsEvaluated { + def cleanTask = p.tasks.findByName("clean") ?: p.tasks.register("clean") + cleanTask.configure { dependsOn("cleanDist") } + } + } +} + +// import json properties +apply from: "${rootDir}/gradle/libs/props.gradle" +def ngeConfig = gradle.ext.loadNgeAppProperties("${rootDir}/app/src/main/resources/ngeapp.json") +gradle.beforeProject { p -> + ngeConfig.each { k, v -> p.ext.set(k, v) } + if (ngeConfig.Version) p.version = ngeConfig.Version.toString() + if (ngeConfig.Namespace) p.group = ngeConfig.Namespace.toString() +} + +print("Build with config: "+ngeConfig) +rootProject.name = ngeConfig.ShortName +include('app') + +// ENABLE DESKTOP BUILD TARGET +include('platform-desktop') + +// ENABLE ANDROID BUILD TARGET +include('platform-android') + +// ENABLE WEB BUILD TARGET +include('platform-web')