Skip to content

Commit a8a718e

Browse files
committed
Reorgranise config yml
1 parent 986e8cc commit a8a718e

19 files changed

Lines changed: 1695 additions & 1732 deletions

SHREDDEDPAPER_YAML.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,29 @@
22

33
```yaml
44

5-
# The number of threads to use for ticking chunks. `-1` defaults to the number
6-
# of available processors subtract one, or 1, whichever is larger.
7-
# Set to `1` to essentially disable multi-threading.
8-
thread-count: -1
5+
# Multithreading settings
6+
multithreading:
97

10-
# The size of a region in chunks. Chunks are grouped into regions when
11-
# ticking, and neighbouring regions are locked so any changes into the
12-
# neighbouring region do not step on other threads.
13-
# The larger the value, the more performant the server will be, but the more
14-
# likely the work is not evenly distributed between threads. Too small, and
15-
# threads may accidentally try accessing chunks of another thread.
16-
# A minimum of 8 chunks is recommended, as lightning rods have the largest
17-
# search radius at 8 chunks.
18-
# Must be a power of 2.
19-
region-size: 8
20-
21-
# Whether to run plugins' code without 'folia-supported: true' in sync. This
22-
# will give unsupported plugins a better chance of working, but is not
23-
# guaranteed. If false, or if the plugin is supported, all the plugin's code
24-
# will run asynchronously in the ticking region worker threads.
25-
run-unsupported-plugins-in-sync: true
8+
# The number of threads to use for ticking chunks. `-1` defaults to the number
9+
# of available processors subtract one, or 1, whichever is larger.
10+
# Set to `1` to essentially disable multi-threading.
11+
thread-count: -1
12+
13+
# The size of a region in chunks. Chunks are grouped into regions when
14+
# ticking, and neighbouring regions are locked so any changes into the
15+
# neighbouring region do not step on other threads.
16+
# The larger the value, the more performant the server will be, but the more
17+
# likely the work is not evenly distributed between threads. Too small, and
18+
# threads may accidentally try accessing chunks of another thread.
19+
# A minimum of 8 chunks is recommended, as lightning rods have the largest
20+
# search radius at 8 chunks.
21+
# Must be a power of 2.
22+
region-size: 8
23+
24+
# Whether to run plugins' code without 'folia-supported: true' in sync. This
25+
# will give unsupported plugins a better chance of working, but is not
26+
# guaranteed. If false, or if the plugin is supported, all the plugin's code
27+
# will run asynchronously in the ticking region worker threads.
28+
run-unsupported-plugins-in-sync: true
2629

2730
```

patches/server/0001-MultiPaper-build-changes.patch renamed to patches/server/0001-ShreddedPaper-build-changes.patch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Subject: [PATCH] ShreddedPaper build changes
55

66

77
diff --git a/build.gradle.kts b/build.gradle.kts
8-
index d23ecfabf6bf1e355fb2efe5abd80236259ce3c4..a3ac4ee572fab52ed8a6af4b69b8ccd3eb555cfb 100644
8+
index d23ecfabf6bf1e355fb2efe5abd80236259ce3c4..bd224e1d9bfc49feca9f0291df839bed9d5842c4 100644
99
--- a/build.gradle.kts
1010
+++ b/build.gradle.kts
1111
@@ -13,7 +13,7 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) {
@@ -38,7 +38,7 @@ index d23ecfabf6bf1e355fb2efe5abd80236259ce3c4..a3ac4ee572fab52ed8a6af4b69b8ccd3
3838
"Build-Time" to Instant.now().toString(),
3939
"Git-Branch" to gitBranch, // Paper
4040
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
41-
index 99597258e8e88cd9e2c901c4ac3ff7faeeabee2b..2fb1e86a62488f54dcdf5144a4911794ceacff0b 100644
41+
index 99597258e8e88cd9e2c901c4ac3ff7faeeabee2b..ed2f3845afed661a5f620efc071cd71c2bc7d613 100644
4242
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
4343
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
4444
@@ -11,7 +11,7 @@ public final class Versioning {
@@ -51,7 +51,7 @@ index 99597258e8e88cd9e2c901c4ac3ff7faeeabee2b..2fb1e86a62488f54dcdf5144a4911794
5151

5252
if (stream != null) {
5353
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
54-
index a353eb9f45af7b7f9bfd92a4a89403335b841840..caa6c45936781fd4e4b03abe1ead8f6bf1230c4c 100644
54+
index a353eb9f45af7b7f9bfd92a4a89403335b841840..a3029da5b80d87158119141608e963196d943db4 100644
5555
--- a/src/main/java/org/spigotmc/WatchdogThread.java
5656
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
5757
@@ -155,14 +155,14 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa

patches/server/0002-MultiPaper-config-file.patch renamed to patches/server/0002-ShreddedPaper-config-file.patch

Lines changed: 80 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,9 @@ Date: Fri, 4 Mar 2022 20:33:33 +1000
44
Subject: [PATCH] ShreddedPaper config file
55

66

7-
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
8-
index 0f7d6da8685716604f0749d4f5b60730a44cde73..c2dc50007572dc4a62830e36531131032d32b1a7 100644
9-
--- a/src/main/java/net/minecraft/server/Main.java
10-
+++ b/src/main/java/net/minecraft/server/Main.java
11-
@@ -23,7 +23,6 @@ import joptsimple.util.PathConverter;
12-
import joptsimple.util.PathProperties;
13-
import net.minecraft.CrashReport;
14-
import net.minecraft.DefaultUncaughtExceptionHandler;
15-
-import net.minecraft.SharedConstants;
16-
import net.minecraft.Util;
17-
import net.minecraft.commands.Commands;
18-
import net.minecraft.core.Registry;
19-
@@ -69,6 +68,9 @@ import net.minecraft.SharedConstants;
20-
import org.bukkit.configuration.file.YamlConfiguration;
21-
// CraftBukkit end
22-
23-
+import io.multipaper.shreddedpaper.config.ShreddedPaperConfiguration;
24-
+import io.multipaper.shreddedpaper.config.ShreddedPaperConfigurationLoader;
25-
+
26-
public class Main {
27-
28-
private static final Logger LOGGER = LogUtils.getLogger();
29-
@@ -119,6 +121,8 @@ public class Main {
30-
JvmProfiler.INSTANCE.start(Environment.SERVER);
31-
}
32-
33-
+ ShreddedPaperConfigurationLoader.init((File) optionset.valueOf("shreddedpaper-settings")); // ShreddedPaper
34-
+
35-
// Purpur start - load config files early
36-
org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("purpur-settings"));
37-
org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels");
38-
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
39-
index 6e78500a6265b0192095379704b1d661ef56ba32..5abd5ced015be7de740d504b5c0b0620822f22ac 100644
40-
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
41-
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
42-
@@ -259,6 +259,7 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
43-
import org.yaml.snakeyaml.error.MarkedYAMLException;
44-
45-
import net.md_5.bungee.api.chat.BaseComponent; // Spigot
46-
+import io.multipaper.shreddedpaper.permissions.ShreddedPaperPermissions;
47-
48-
import javax.annotation.Nullable; // Paper
49-
import javax.annotation.Nonnull; // Paper
50-
@@ -577,6 +578,7 @@ public final class CraftServer implements Server {
51-
this.commandMap.registerServerAliases();
52-
DefaultPermissions.registerCorePermissions();
53-
CraftDefaultPermissions.registerCorePermissions();
54-
+ ShreddedPaperPermissions.registerCorePermissions(); // ShreddedPaper
55-
if (!io.papermc.paper.configuration.GlobalConfiguration.get().misc.loadPermissionsYmlBeforePlugins) this.loadCustomPermissions(); // Paper
56-
this.helpMap.initializeCommands();
57-
this.syncCommands();
58-
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
59-
index 6d8e9cf4ee496b8748654e792ce438f512c3d946..7356f7eebb51832c3455eab749ed27201bb741d2 100644
60-
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
61-
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
62-
@@ -184,6 +184,14 @@ public class Main {
63-
.describedAs("Yml file");
64-
// Purpur end
65-
66-
+ // ShreddedPaper start
67-
+ acceptsAll(asList("shreddedpaper", "shreddedpaper-settings"), "File for shreddedpaper settings")
68-
+ .withRequiredArg()
69-
+ .ofType(File.class)
70-
+ .defaultsTo(new File("shreddedpaper.yml"))
71-
+ .describedAs("Yml file");
72-
+ // ShreddedPaper end
73-
+
74-
// Paper start
75-
acceptsAll(asList("server-name"), "Name of the server")
76-
.withRequiredArg()
777
diff --git a/src/main/java/io/multipaper/shreddedpaper/config/ExceptionableConsumer.java b/src/main/java/io/multipaper/shreddedpaper/config/ExceptionableConsumer.java
788
new file mode 100644
79-
index 0000000000000000000000000000000000000000..7cdf20efd4f220f55d7b86abce19e84f4512191e
9+
index 0000000000000000000000000000000000000000..df97bb240655934b62cfb1647f2dc32707b48a09
8010
--- /dev/null
8111
+++ b/src/main/java/io/multipaper/shreddedpaper/config/ExceptionableConsumer.java
8212
@@ -0,0 +1,8 @@
@@ -90,10 +20,10 @@ index 0000000000000000000000000000000000000000..7cdf20efd4f220f55d7b86abce19e84f
9020
+}
9121
diff --git a/src/main/java/io/multipaper/shreddedpaper/config/ShreddedPaperConfiguration.java b/src/main/java/io/multipaper/shreddedpaper/config/ShreddedPaperConfiguration.java
9222
new file mode 100644
93-
index 0000000000000000000000000000000000000000..a198aadad3acdf431321e05f62b392d408246a4c
23+
index 0000000000000000000000000000000000000000..15057bd8191f3fba9952a5c768f4500924f1031c
9424
--- /dev/null
9525
+++ b/src/main/java/io/multipaper/shreddedpaper/config/ShreddedPaperConfiguration.java
96-
@@ -0,0 +1,67 @@
26+
@@ -0,0 +1,39 @@
9727
+package io.multipaper.shreddedpaper.config;
9828
+
9929
+import io.papermc.paper.configuration.ConfigurationPart;
@@ -121,52 +51,24 @@ index 0000000000000000000000000000000000000000..a198aadad3acdf431321e05f62b392d4
12151
+ ShreddedPaperConfiguration.instance = instance;
12252
+ }
12353
+
124-
+ public VerticalScaling verticalScaling;
54+
+ public Multithreading multithreading;
12555
+
126-
+ public class VerticalScaling extends ConfigurationPart {
56+
+ public class Multithreading extends ConfigurationPart {
12757
+
12858
+ public int threadCount = -1;
12959
+ public int regionSize = 8;
13060
+ public boolean runUnsupportedPluginsInSync = true;
13161
+
13262
+ }
13363
+
134-
+ public HorizontalScaling horizontalScaling;
135-
+
136-
+ public class HorizontalScaling extends ConfigurationPart {
137-
+
138-
+ public DatabaseConnection databaseConnection;
139-
+
140-
+ public class DatabaseConnection extends ConfigurationPart {
141-
+
142-
+ public String databaseAddress = "";
143-
+
144-
+ }
145-
+
146-
+ public SyncSettings syncSettings;
147-
+
148-
+ public class SyncSettings extends ConfigurationPart {
149-
+
150-
+ public Files files;
151-
+
152-
+ public class Files extends ConfigurationPart {
153-
+ public List<String> filesToNotSync = List.of("plugins/bStats");
154-
+ public List<String> filesToOnlyUploadOnServerStop = List.of("plugins/MyPluginDirectory/my_big_database.db");
155-
+ public List<String> filesToSyncInRealTime = List.of("plugins/MyPluginDirectory/userdata");
156-
+ public List<String> filesToSyncOnStartup = List.of("myconfigfile.yml", "plugins/MyPlugin.jar");
157-
+ public boolean logFileSyncs = true;
158-
+ }
159-
+ }
160-
+ }
161-
+
16264
+
16365
+}
16466
diff --git a/src/main/java/io/multipaper/shreddedpaper/config/ShreddedPaperConfigurationLoader.java b/src/main/java/io/multipaper/shreddedpaper/config/ShreddedPaperConfigurationLoader.java
16567
new file mode 100644
166-
index 0000000000000000000000000000000000000000..903f47c87045334f05fae22c48d8dad05897dd08
68+
index 0000000000000000000000000000000000000000..9407d6afa9c13a55be65d4e680f3f1a45ea7da9f
16769
--- /dev/null
16870
+++ b/src/main/java/io/multipaper/shreddedpaper/config/ShreddedPaperConfigurationLoader.java
169-
@@ -0,0 +1,140 @@
71+
@@ -0,0 +1,128 @@
17072
+package io.multipaper.shreddedpaper.config;
17173
+
17274
+import io.papermc.paper.configuration.ConfigurationLoaders;
@@ -259,19 +161,7 @@ index 0000000000000000000000000000000000000000..903f47c87045334f05fae22c48d8dad0
259161
+ }
260162
+
261163
+ private static void transformLegacyConfig(ConfigurationNode node, ShreddedPaperConfiguration config) {
262-
+ getAndRemove(node, "master-connection.master-address", value -> config.horizontalScaling.databaseConnection.databaseAddress = value.getString());
263-
+ getAndRemove(node, "sync-settings.files.log-file-syncs", value -> config.horizontalScaling.syncSettings.files.logFileSyncs = value.getBoolean());
264-
+ getAndRemove(node, "sync-settings.files.files-to-sync-on-startup", value -> config.horizontalScaling.syncSettings.files.filesToSyncOnStartup = value.getList(String.class));
265-
+ getAndRemove(node, "sync-settings.files.files-to-sync-in-real-time", value -> config.horizontalScaling.syncSettings.files.filesToSyncInRealTime = value.getList(String.class));
266-
+ getAndRemove(node, "sync-settings.files.files-to-only-upload-on-server-stop", value -> config.horizontalScaling.syncSettings.files.filesToOnlyUploadOnServerStop = value.getList(String.class));
267-
+ getAndRemove(node, "sync-settings.files.files-to-not-sync", value -> config.horizontalScaling.syncSettings.files.filesToNotSync = value.getList(String.class));
268-
+
269-
+ getAndRemove(node, "shreddedpaperMasterAddress", value -> config.horizontalScaling.databaseConnection.databaseAddress = value.getString());
270-
+ getAndRemove(node, "logFileSyncing", value -> config.horizontalScaling.syncSettings.files.logFileSyncs = value.getBoolean());
271-
+ getAndRemove(node, "filesToSyncOnStartup", value -> config.horizontalScaling.syncSettings.files.filesToSyncOnStartup = value.getList(String.class));
272-
+ getAndRemove(node, "filesToSyncInRealTime", value -> config.horizontalScaling.syncSettings.files.filesToSyncInRealTime = value.getList(String.class));
273-
+ getAndRemove(node, "filesToOnlyUploadOnServerStop", value -> config.horizontalScaling.syncSettings.files.filesToOnlyUploadOnServerStop = value.getList(String.class));
274-
+ getAndRemove(node, "filesToNotSync", value -> config.horizontalScaling.syncSettings.files.filesToNotSync = value.getList(String.class));
164+
+ // getAndRemove(node, "oldValue.oldie", value -> config.newSection.newValue.newie = value.getString());
275165
+ }
276166
+
277167
+ private static void getAndRemove(ConfigurationNode node, String key, ExceptionableConsumer<ConfigurationNode> consumer) {
@@ -309,7 +199,7 @@ index 0000000000000000000000000000000000000000..903f47c87045334f05fae22c48d8dad0
309199
+}
310200
diff --git a/src/main/java/io/multipaper/shreddedpaper/permissions/ShreddedPaperCommandPermissions.java b/src/main/java/io/multipaper/shreddedpaper/permissions/ShreddedPaperCommandPermissions.java
311201
new file mode 100644
312-
index 0000000000000000000000000000000000000000..f7d9a1538ec842e453e5add3f9e33f8c43bfa3d2
202+
index 0000000000000000000000000000000000000000..53dcfbdf38f007fc86064ac1a495288d5f25f598
313203
--- /dev/null
314204
+++ b/src/main/java/io/multipaper/shreddedpaper/permissions/ShreddedPaperCommandPermissions.java
315205
@@ -0,0 +1,17 @@
@@ -332,7 +222,7 @@ index 0000000000000000000000000000000000000000..f7d9a1538ec842e453e5add3f9e33f8c
332222
+}
333223
diff --git a/src/main/java/io/multipaper/shreddedpaper/permissions/ShreddedPaperPermissions.java b/src/main/java/io/multipaper/shreddedpaper/permissions/ShreddedPaperPermissions.java
334224
new file mode 100644
335-
index 0000000000000000000000000000000000000000..91b2e3564d7c737b2006f8c2860ab43846637384
225+
index 0000000000000000000000000000000000000000..4999f297b04d151e8000fdc309081b5cee8b11ae
336226
--- /dev/null
337227
+++ b/src/main/java/io/multipaper/shreddedpaper/permissions/ShreddedPaperPermissions.java
338228
@@ -0,0 +1,16 @@
@@ -352,3 +242,73 @@ index 0000000000000000000000000000000000000000..91b2e3564d7c737b2006f8c2860ab438
352242
+ parent.recalculatePermissibles();
353243
+ }
354244
+}
245+
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
246+
index 0f7d6da8685716604f0749d4f5b60730a44cde73..a7ffbbfd2a9fdeae0953ec8753ce48e93ccce086 100644
247+
--- a/src/main/java/net/minecraft/server/Main.java
248+
+++ b/src/main/java/net/minecraft/server/Main.java
249+
@@ -23,7 +23,6 @@ import joptsimple.util.PathConverter;
250+
import joptsimple.util.PathProperties;
251+
import net.minecraft.CrashReport;
252+
import net.minecraft.DefaultUncaughtExceptionHandler;
253+
-import net.minecraft.SharedConstants;
254+
import net.minecraft.Util;
255+
import net.minecraft.commands.Commands;
256+
import net.minecraft.core.Registry;
257+
@@ -69,6 +68,9 @@ import net.minecraft.SharedConstants;
258+
import org.bukkit.configuration.file.YamlConfiguration;
259+
// CraftBukkit end
260+
261+
+import io.multipaper.shreddedpaper.config.ShreddedPaperConfiguration;
262+
+import io.multipaper.shreddedpaper.config.ShreddedPaperConfigurationLoader;
263+
+
264+
public class Main {
265+
266+
private static final Logger LOGGER = LogUtils.getLogger();
267+
@@ -119,6 +121,8 @@ public class Main {
268+
JvmProfiler.INSTANCE.start(Environment.SERVER);
269+
}
270+
271+
+ ShreddedPaperConfigurationLoader.init((File) optionset.valueOf("shreddedpaper-settings")); // ShreddedPaper
272+
+
273+
// Purpur start - load config files early
274+
org.bukkit.configuration.file.YamlConfiguration purpurConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("purpur-settings"));
275+
org.purpurmc.purpur.PurpurConfig.clampEnchantLevels = purpurConfiguration.getBoolean("settings.enchantment.clamp-levels");
276+
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
277+
index 6e78500a6265b0192095379704b1d661ef56ba32..87ed749633aba04e6b86eb7ddf09f58884b552a4 100644
278+
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
279+
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
280+
@@ -259,6 +259,7 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
281+
import org.yaml.snakeyaml.error.MarkedYAMLException;
282+
283+
import net.md_5.bungee.api.chat.BaseComponent; // Spigot
284+
+import io.multipaper.shreddedpaper.permissions.ShreddedPaperPermissions;
285+
286+
import javax.annotation.Nullable; // Paper
287+
import javax.annotation.Nonnull; // Paper
288+
@@ -577,6 +578,7 @@ public final class CraftServer implements Server {
289+
this.commandMap.registerServerAliases();
290+
DefaultPermissions.registerCorePermissions();
291+
CraftDefaultPermissions.registerCorePermissions();
292+
+ ShreddedPaperPermissions.registerCorePermissions(); // ShreddedPaper
293+
if (!io.papermc.paper.configuration.GlobalConfiguration.get().misc.loadPermissionsYmlBeforePlugins) this.loadCustomPermissions(); // Paper
294+
this.helpMap.initializeCommands();
295+
this.syncCommands();
296+
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
297+
index 6d8e9cf4ee496b8748654e792ce438f512c3d946..41f00f5af479fd48f1e67150c4cfee3049c7feb9 100644
298+
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
299+
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
300+
@@ -184,6 +184,14 @@ public class Main {
301+
.describedAs("Yml file");
302+
// Purpur end
303+
304+
+ // ShreddedPaper start
305+
+ acceptsAll(asList("shreddedpaper", "shreddedpaper-settings"), "File for shreddedpaper settings")
306+
+ .withRequiredArg()
307+
+ .ofType(File.class)
308+
+ .defaultsTo(new File("shreddedpaper.yml"))
309+
+ .describedAs("Yml file");
310+
+ // ShreddedPaper end
311+
+
312+
// Paper start
313+
acceptsAll(asList("server-name"), "Name of the server")
314+
.withRequiredArg()

patches/server/0003-MultiPaper-Metrics.patch renamed to patches/server/0003-ShreddedPaper-Metrics.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Subject: [PATCH] ShreddedPaper Metrics
55

66

77
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
8-
index 8cde30544e14f8fc2dac32966ae3c21f8cf3a551..ead87ad864494358096d59a4dbe2fe2b20e3ae37 100644
8+
index 8cde30544e14f8fc2dac32966ae3c21f8cf3a551..cc152e9a86bcb0dad498d7332f01dcbf44c43995 100644
99
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
1010
+++ b/src/main/java/com/destroystokyo/paper/Metrics.java
1111
@@ -3,6 +3,7 @@ package com.destroystokyo.paper;

0 commit comments

Comments
 (0)