### Full Plugin Installation Path (Windows) Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This provides the complete, user-specific path on Windows for installing Hytale plugins. Replace 'YourUsername' with the actual user's login name. ```bash C:\Users\YourUsername\AppData\Roaming\Hytale\UserData\Mods\ ``` -------------------------------- ### Review Gradle Properties for Hytale Plugin Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins Demonstrates example properties found in the `gradle.properties` file. These properties, such as Hytale and plugin versions, are essential for configuring the build environment and defining plugin metadata. ```properties # Example properties (actual values may vary) hytale_version=latest plugin_version=1.0.0 # ... other properties ``` -------------------------------- ### Hytale Plugin Installation Path Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This snippet shows the directory path where Hytale plugin JAR files should be placed for the game to load them. It is specific to Windows operating systems. ```bash %appdata%/Hytale/UserData/Mods/ ``` -------------------------------- ### Troubleshooting Gradle Sync Failures Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This snippet provides commands and checks to resolve common Gradle synchronization issues. It suggests verifying internet connectivity, Java installation, and running a clean build. ```bash ./gradlew clean build ``` -------------------------------- ### Build Plugin with Gradle Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This snippet shows how to build a Hytale plugin using Gradle. It can be executed directly from the terminal or through the IDEA Gradle panel. Ensure Gradle is set up correctly in your project. ```bash ./gradlew build ``` -------------------------------- ### Hytale Plugin Project Structure Overview Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins Illustrates the standard directory layout for a Hytale plugin project. Understanding this structure is key to organizing your plugin's code, assets, and configuration files effectively. ```directory your-plugin-name/ |-- src/ | `-- main/ | |-- java/ | | `-- com/ | | `-- yourname/ | | `-- yourplugin/ | | `-- YourPlugin.java | `-- resources/ | |-- manifest.json | |-- Common/ # Assets (models, textures) | `-- Server/ # Server-side data |-- build.gradle |-- settings.gradle |-- gradle.properties `-- README.md ``` -------------------------------- ### Java Configuration Example for Hytale Modding Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/08-custom-config-files Demonstrates a complete Java example for handling plugin configurations in Hytale modding. It includes a `MyPluginConfig` class for defining configuration options and a `MyPlugin` class that utilizes `withConfig()` to load and access these settings. This example showcases how to define codecs for double and boolean types and how to log the loaded configuration values. ```java // Config class public class MyPluginConfig { public static final BuilderCodec CODEC = BuilderCodec.builder(MyPluginConfig.class, MyPluginConfig::new) .append(new KeyedCodec("DropRateMultiplier", Codec.DOUBLE), (cfg, val, info) -> cfg.dropRateMultiplier = val, (cfg, info) -> cfg.dropRateMultiplier) .add() .append(new KeyedCodec("EnableDebugMode", Codec.BOOL), (cfg, val, info) -> cfg.enableDebugMode = val, (cfg, info) -> cfg.enableDebugMode) .add() .build(); private double dropRateMultiplier = 1.0; private boolean enableDebugMode = false; public MyPluginConfig() { } public double getDropRateMultiplier() { return dropRateMultiplier; } public boolean isDebugMode() { return enableDebugMode; } } // Plugin class public class MyPlugin extends JavaPlugin { private final Config config; public MyPlugin(@Nonnull JavaPluginInit init) { super(init); this.config = this.withConfig("MyPlugin", MyPluginConfig.CODEC); // Log loaded values getLogger().info("Drop rate multiplier: " + config.get().getDropRateMultiplier()); getLogger().info("Debug mode: " + config.get().isDebugMode()); } } ``` -------------------------------- ### Run Hytale Server for Testing Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Starts the Hytale server with the compiled plugin automatically deployed and ready for testing. This command facilitates the development cycle by allowing quick verification of plugin functionality. ```bash # Windows gradlew.bat runServer # Linux/Mac ./gradlew runServer # With debug mode: # ./gradlew runServer -Pdebug ``` -------------------------------- ### Create Hytale Pack Folder Structure Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/packs-content-creation/02-getting-started-with-packs This snippet shows the basic directory structure required for a Hytale Pack. It includes the main pack folder, a manifest file, and the 'Common' and 'Server' subfolders for assets and game logic respectively. ```bash C:\Users\YourUsername\AppData\Roaming\Hytale\UserData\Packs\MyFirstPack | |-- manifest.json |-- Common/ `-- Server/ ``` -------------------------------- ### Basic Hytale Plugin Structure (Java) Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This Java code demonstrates the fundamental structure of a Hytale plugin. It extends the `JavaPlugin` class and includes methods for initialization, enabling, and disabling the plugin. ```java package com.yourname.yourplugin; import com.hypixel.hytale.plugin.JavaPlugin; import com.hypixel.hytale.plugin.JavaPluginInit; import javax.annotation.Nonnull; public class YourPlugin extends JavaPlugin { public YourPlugin(@Nonnull JavaPluginInit init) { super(init); // Plugin initialization code getLogger().info("YourPlugin has been loaded!"); } @Override public void onEnable() { // Called when plugin is enabled getLogger().info("YourPlugin enabled!"); } @Override public void onDisable() { // Called when plugin is disabled getLogger().info("YourPlugin disabled!"); } } ``` -------------------------------- ### Manage Plugin Dependencies in Gradle Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Example `build.gradle.kts` snippet showing how to declare dependencies for Hytale plugins. Includes Hytale API, implementation dependencies, and test dependencies. ```kotlin dependencies { // Hytale API (provided by server) compileOnly(files("libs/hytale-server.jar")) // Your dependencies (will be bundled) implementation("com.google.code.gson:gson:2.10.1") implementation("org.jetbrains:annotations:24.1.0") // Test dependencies testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") testRuntimeOnly("org.junit.platform:junit-platform-launcher") } ``` -------------------------------- ### Hytale Localization Files Example Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/packs-content-creation/03-adding-a-block This demonstrates how to set up language files for Hytale mods. It shows the naming convention for different language codes and the structure within the `Languages` directory, specifically for the `server.lang` file. ```plaintext es-ES/server.lang - Spanish fr-FR/server.lang - French de-DE/server.lang - German etc. ``` -------------------------------- ### Chat Configuration Example (JSON) Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/14-common-plugin-features Defines messages for player joins, first joins, and leaves, utilizing placeholders like %player_name%. ```json { "joinMessage": "§e%player_name% joined the server", "firstJoinMessage": "§6Welcome %player_name% to the server for the first time!", "leaveMessage": "§e%player_name% left the server" } ``` -------------------------------- ### Hytale Plugin File Structure Example Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/index This example demonstrates the file path for Hytale plugins, which are typically distributed as Java Archive (JAR) files. These are used for extending game functionality beyond what packs can offer. ```plaintext %AppData%/Roaming/Hytale/UserData/Mods/ `-- your-plugin-1.0.0.jar ``` -------------------------------- ### Hytale Early Plugin File Structure Example Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/index This example shows the directory for early Hytale plugins, which are used for low-level modifications. These plugins often involve bytecode manipulation and require advanced Java development skills. ```plaintext /path/to/hytale/earlyplugins/ `-- your-early-plugin-1.0.0.jar ``` -------------------------------- ### Translate Interaction Hints Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/packs-content-creation/04-block-state-changing This is an example of a language file used for translating interaction hints in Hytale mods. It maps internal hint keys (like 'turnon', 'turnoff') to user-facing text. The file path indicates its location within the mod's server language directory. ```properties turnon = Turn On turnoff = Turn Off ``` -------------------------------- ### Clone and Build Hytale Plugin Project Template Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/index This snippet demonstrates how to clone the official Hytale plugin project template and build it using Gradle. This is the recommended starting point for Java plugin development. ```bash git clone https://github.com/realBritakee/hytale-template-plugin.git cd hytale-template-plugin ./gradlew shadowJar # Builds immediately! ``` -------------------------------- ### Run Hytale Server Task via Gradle Wrapper (Bash/Batch) Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/13-gradle-automation-testing Demonstrates how to execute the custom 'runServer' task using the Gradle wrapper script. This command builds the plugin and starts the Hytale server. ```bash # Build and run server with your plugin ./gradlew runServer # On Windows: gradlew.bat runServer ``` -------------------------------- ### Hytale Pack File Structure Example Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/index This example shows the directory structure for Hytale packs, including common assets like textures, models, blocks, items, and language files. It is used for organizing game content created through the Asset Editor. ```plaintext %AppData%/Roaming/Hytale/UserData/Packs/YourPackName/ |-- manifest.json |-- Common/ | |-- BlockTextures/ | |-- Icons/ | |-- Models/ | `-- Blocks/ | `-- Animations/ `-- Server/ |-- Item/ | |-- Items/ | `-- Category/ `-- Languages/ `-- en-US/ ``` -------------------------------- ### Custom Gradle Task to Copy Plugin to Server Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Example of a custom Gradle task written in Kotlin DSL that copies the built plugin JAR to a specified server directory, overwriting if it exists. ```kotlin tasks.register("copyToServer") { group = "deployment" description = "Copy plugin to local server" doLast { val serverDir = File("C:/HytaleServer/plugins") val pluginJar = tasks.shadowJar.get().outputs.files.singleFile pluginJar.copyTo(File(serverDir, pluginJar.name), overwrite = true) println("Plugin copied to server!") } } ``` -------------------------------- ### Clone Hytale Plugin Template Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Clones the Hytale plugin template repository and navigates into the project directory. This is the first step to start developing a new Hytale plugin using the provided template. ```bash git clone https://github.com/realBritakee/hytale-template-plugin.git cd hytale-template-plugin ``` -------------------------------- ### Run Server and Tests with Gradle Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Gradle commands for running the Hytale server with your plugin and executing unit tests. Also includes a command to clean the test server environment. ```bash # Run server with your plugin ./gradlew runServer # Run unit tests ./gradlew test # Clean test server rm -rf run/ ``` -------------------------------- ### Hytale Early Plugin Loading Commands Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/09-bootstrap-early-plugins These bash commands illustrate how to specify the loading locations for Hytale early plugins. It shows the default directory and how to use a custom path via a launch argument. ```bash # Default location earlyplugins/ # Custom location --early-plugins="C:/path/to/custom/earlyplugins" # Auto-skip early plugin warning --accept-early-plugins ``` -------------------------------- ### Registering Event Listeners in Hytale (Java) Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This Java code shows how to register an event listener for your Hytale plugin. Replace `MyListener` with your actual listener class. ```java getServer().getPluginManager().registerEvents(new MyListener(), this); ``` -------------------------------- ### Build Plugin JAR with Gradle Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Commands to build a plugin JAR using Gradle. Includes options for compiling, creating a shadow JAR (which bundles dependencies), and cleaning the project before rebuilding. ```bash # Compile only ./gradlew compileJava # Build plugin JAR ./gradlew shadowJar # Clean and rebuild ./gradlew clean shadowJar ``` -------------------------------- ### Configure Project Name in Gradle Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This snippet shows how to set the project's root name within the `settings.gradle` file. This is a crucial step for identifying your plugin project in IntelliJ IDEA. ```gradle rootProject.name = 'your-plugin-name' ``` -------------------------------- ### Hytale Plugin Logger Usage (Java) Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This Java snippet illustrates how to use the built-in logger within a Hytale plugin to output messages at different severity levels (info, warning, error). ```java getLogger().info("Information message"); getLogger().warn("Warning message"); getLogger().error("Error message"); ``` -------------------------------- ### Plugin JAR Output Location Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This snippet indicates the default location where the compiled plugin JAR file will be generated after a successful Gradle build. The exact filename will include your plugin's name and version. ```bash build/libs/your-plugin-name-1.0.0.jar ``` -------------------------------- ### Manage Gradle Daemon and Build Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Provides commands to stop all running Gradle daemons and perform a clean rebuild of the project, including creating a shadow JAR. This is useful for resolving build issues or ensuring a fresh build environment. ```bash # Stop all Gradle daemons ./gradlew --stop # Rebuild ./gradlew clean shadowJar ``` -------------------------------- ### Update Plugin Manifest JSON Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/07-getting-started-with-plugins This JSON structure defines the metadata for your Hytale plugin, including its group, name, version, description, authors, and dependencies. This file is critical for the game to recognize and load your plugin correctly. ```json { "Group": "com.yourname", "Name": "YourPluginName", "Version": "1.0.0", "Description": "Description of your plugin", "Authors": [ { "Name": "Your Name", "Email": "your.email@example.com", "Url": "https://your-website.com" } ], "Website": "https://your-plugin-website.com", "ServerVersion": "*", "Dependencies": {}, "OptionalDependencies": {}, "DisabledByDefault": false } ``` -------------------------------- ### Troubleshooting Build Failures in Gradle Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Bash commands to troubleshoot build failures in Gradle. Includes options to clean and rebuild with dependency refreshing and to check the Gradle version. ```bash # Clean and rebuild ./gradlew clean build --refresh-dependencies # Check Gradle version ./gradlew --version ``` -------------------------------- ### Using ASM for Bytecode Transformation in Hytale Plugins Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/09-bootstrap-early-plugins Demonstrates the correct method for performing bytecode transformations within Hytale early plugins by utilizing the ASM library. This approach ensures that bytecode is manipulated correctly, preventing corruption and maintaining class integrity. ```java // DO: Use ASM or similar tools ClassReader reader = new ClassReader(bytes); // ... proper transformation return writer.toByteArray(); ``` -------------------------------- ### Hytale Pack Manifest File Template Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/packs-content-creation/02-getting-started-with-packs This JSON template defines the metadata for a Hytale Pack. It includes essential fields like Group, Name, Version, Description, Authors, and ServerVersion. Optional fields for website and dependencies are also included. ```json { "Group": "YourGroupName", "Name": "PackName", "Version": "1.0.0", "Description": "Add the pack description here", "Authors": [ { "Name": "AuthorName", "Email": "example@example.com", "Url": "https://your-url.com" } ], "Website": "https://your-website.com", "ServerVersion": "*", "Dependencies": {}, "OptionalDependencies": {}, "DisabledByDefault": false } ``` -------------------------------- ### JSON: Complete Block Definition with State Changing Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/packs-content-creation/04-block-state-changing A comprehensive JSON example of a Hytale block with state-changing capabilities. It includes basic block properties, interaction logic for state changes, and definitions for the 'On' and 'Off' states. ```json { "TranslationProperties": { "Name": "server.Toggle_Block.name" }, "MaxStack": 100, "Icon": "Icons/ItemsGenerated/Toggle_Block.png", "Categories": [ "Blocks.Decoration" ], "BlockType": { "DrawType": "Model", "CustomModel": "Blocks/model_one.blockymodel", "CustomModelTexture": [ { "Texture": "Blocks/your_texture.png" } ], "Interactions": { "Use": { "Interactions": [ { "Type": "ChangeState", "Changes": { "default": "Off", "On": "Off", "Off": "On" } } ] } }, "State": { "Definitions": { "On": { "InteractionHint": "interactionHints.turnoff", "CustomModel": "Blocks/model_one.blockymodel", "CustomModelTexture": [ { "Texture": "Blocks/Texture/textureone.png" } ] }, "Off": { "InteractionHint": "interactionHints.turnon", "CustomModel": "Blocks/model_two.blockymodel", "CustomModelTexture": [ { "Texture": "Blocks/Texture/textureone.png" } ] } } } } } ``` -------------------------------- ### Example ASM Transformer for Hytale Early Plugins Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/09-bootstrap-early-plugins Demonstrates how to create a custom ASM transformer to modify Java bytecode at runtime for Hytale early plugins. This involves using the ASM library to read, visit, and write class files, allowing for targeted method modifications. It requires the Hytale early plugin API and ASM libraries. ```java import com.hypixel.hytale.plugin.early.ClassTransformer; import org.objectweb.asm.*; public class AsmTransformer implements ClassTransformer { @Override public byte[] transform(String name, String path, byte[] bytes) { if (name.equals("com.example.TargetClass")) { ClassReader reader = new ClassReader(bytes); ClassWriter writer = new ClassWriter(reader, 0); ClassVisitor visitor = new MyClassVisitor(Opcodes.ASM9, writer); reader.accept(visitor, 0); return writer.toByteArray(); } return bytes; } private static class MyClassVisitor extends ClassVisitor { public MyClassVisitor(int api, ClassVisitor cv) { super(api, cv); } @Override public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions); // Modify specific method if (name.equals("targetMethod")) { return new MethodModifier(api, mv); } return mv; } } private static class MethodModifier extends MethodVisitor { public MethodModifier(int api, MethodVisitor mv) { super(api, mv); } @Override public void visitCode() { // Inject code at method start super.visitCode(); // Add your bytecode instructions here } } } ``` -------------------------------- ### Java Example of Using Translations Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/14-common-plugin-features This Java code snippet demonstrates how to use the Message class and TranslationService to retrieve and send translated messages to a player. It shows retrieving a message, replacing placeholders, and sending it to the player or getting the parsed string. ```java // Get message and replace placeholders Message msg = translationService.getMessage("welcome") .replace("player_name", player.getUsername()); // Send to player msg.sendTo(player); // Or get as string String text = msg.getParsedMessage(); ``` -------------------------------- ### Create Git Tag for Release Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/15-plugin-project-template Bash commands to create a Git tag and push it to the remote repository, which can trigger a GitHub Actions release workflow. ```bash git tag v1.0.0 git push origin v1.0.0 ``` -------------------------------- ### Complete Hytale Plugin Template in Java Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/plugins-java-development/12-advanced-plugin-patterns This Java code represents a complete Hytale plugin template. It initializes core services like logging, configuration, and a thread pool, along with feature services for player data management. It demonstrates the plugin lifecycle (onEnable, onDisable) and includes placeholders for registering listeners and commands. Dependencies include Hytale's plugin API. ```java package com.example.myplugin; import com.hypixel.hytale.plugin.JavaPlugin; import com.hypixel.hytale.plugin.JavaPluginInit; import javax.annotation.Nonnull; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class MyPlugin extends JavaPlugin { // Singleton instance private static MyPlugin instance; // Core services private PluginLogger logger; private PluginConfig config; private ScheduledExecutorService threadPool; private EventService eventService; // Feature services private PlayerStorage playerStorage; private PlayerService playerService; // Scheduled tasks private AutoSaveTask autoSaveTask; private CacheCleanupTask cacheCleanupTask; public MyPlugin(@Nonnull JavaPluginInit init) { super(init); instance = this; // Initialize core services this.logger = new PluginLogger("MyPlugin", getDataFolder()); this.config = new PluginConfig(getDataFolder()); // Set log level from config if (config.isDebugMode()) { logger.setLogLevel(PluginLogger.LogLevel.DEBUG); } // Create thread pool this.threadPool = Executors.newScheduledThreadPool(4, r -> { Thread thread = new Thread(r); thread.setName("MyPlugin-Thread-" + thread.threadId()); return thread; }); // Initialize event system this.eventService = new EventService(); // Initialize feature services this.playerStorage = new PlayerJsonStorage(getDataFolder()); this.playerService = new PlayerService(playerStorage); // Initialize scheduled tasks this.autoSaveTask = new AutoSaveTask(playerService, logger); this.cacheCleanupTask = new CacheCleanupTask( playerService.getCache(), 30, logger ); logger.info("MyPlugin initialized"); } @Override public void onEnable() { logger.info("MyPlugin is enabling..."); // Load configuration config.load(); // Schedule periodic tasks autoSaveTask.schedule(threadPool); cacheCleanupTask.schedule(threadPool); // Register event listeners registerListeners(); // Register commands registerCommands(); logger.info("MyPlugin has been enabled"); } @Override public void onDisable() { logger.info("MyPlugin is disabling..."); // Shutdown thread pool threadPool.shutdown(); try { if (!threadPool.awaitTermination(10, TimeUnit.SECONDS)) { threadPool.shutdownNow(); } } catch (InterruptedException e) { threadPool.shutdownNow(); } // Save all data playerService.saveAll(); logger.info("MyPlugin has been disabled"); } private void registerListeners() { // Register event listeners here } private void registerCommands() { // Register commands here } // Public API public static MyPlugin getInstance() { return instance; } public PluginLogger getPluginLogger() { return logger; } public PluginConfig getPluginConfig() { return config; } public ScheduledExecutorService getThreadPool() { return threadPool; } public EventService getEventService() { return eventService; } public PlayerService getPlayerService() { return playerService; } } ``` -------------------------------- ### Complete Rising Water Animation Example (JSON) Source: https://britakee-studios.gitbook.io/hytale-modding-documentation/packs-content-creation/06-block-animations A full example of a `.blockyanim` file that creates a rising water effect by animating the 'Water' group's position over 50 ticks. ```json { "formatVersion": 1, "duration": 50, "holdLastKeyframe": true, "nodeAnimations": { "Water": { "position": [ { "time": 0, "delta": { "x": 0, "y": 0, "z": 0 }, "interpolationType": "smooth" }, { "time": 50, "delta": { "x": 0, "y": 8.5, "z": 0 }, "interpolationType": "smooth" } ], "orientation": [], "shapeStretch": [], "shapeVisible": [], "shapeUvOffset": [] } } } ```