This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new fada070a5ec2 CAMEL-23237: camel-jbang catalog tables fill the terminal 
width
fada070a5ec2 is described below

commit fada070a5ec233b18398269de9e50f0a3e715ef4
Author: Adriano Machado <[email protected]>
AuthorDate: Tue Jul 7 03:56:24 2026 -0400

    CAMEL-23237: camel-jbang catalog tables fill the terminal width
    
    Standardize catalog table column definitions via a new CamelTableColumns
    toolkit and expand the last free-text column (DESCRIPTION) to fill the
    detected terminal width instead of capping at 80 characters. Fix
    noBorderOverhead formula from (n-1)*2 to n*2 to match AsciiTable
    NO_BORDERS padding. Add Windows terminal width detection via mode con.
    Migrate CatalogBaseCommand, CatalogTransformer, CatalogKamelet,
    UpdateList, and InfraBaseCommand onto the toolkit.
    
    Closes #24386
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
---
 .../ROOT/pages/camel-4x-upgrade-guide-4_22.adoc    |  18 ++++
 .../core/commands/catalog/CatalogBaseCommand.java  |  40 ++++----
 .../core/commands/catalog/CatalogKamelet.java      |  18 ++--
 .../core/commands/catalog/CatalogTransformer.java  |   5 -
 .../core/commands/infra/InfraBaseCommand.java      |  57 +++++++----
 .../dsl/jbang/core/commands/update/UpdateList.java |  21 ++--
 .../dsl/jbang/core/common/CamelTableColumns.java   | 107 ++++++++++++++++++++
 .../dsl/jbang/core/common/TerminalWidthHelper.java |  97 ++++++++++++++----
 .../dsl/jbang/core/commands/infra/InfraTest.java   |  30 ++++++
 .../jbang/core/common/CamelTableColumnsTest.java   | 110 +++++++++++++++++++++
 .../jbang/core/common/TerminalWidthHelperTest.java |  77 +++++++++++++--
 11 files changed, 486 insertions(+), 94 deletions(-)

diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
index 5a9fc917b966..e22ff8fd638d 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_22.adoc
@@ -128,3 +128,21 @@ discarding the message with no exception or log.
 Scalar value nodes are now sent as a single record. Only container nodes 
(`ArrayNode`, `ObjectNode`)
 are still split, which is unchanged. Any `convertBodyTo(...)` previously used 
as a workaround is no
 longer required.
+
+=== camel-jbang catalog tables fill the terminal width
+
+The `camel catalog` commands (`camel catalog component`, `camel catalog 
dataformat`,
+`camel catalog language`, `camel catalog transformer`, `camel catalog 
kamelet`, ...) now size the
+`DESCRIPTION` column to the detected terminal width instead of the previous 
fixed 80-character cap,
+so wide terminals show more of the description before it is truncated with an 
ellipsis. The `NAME`
+column width is also standardized across these commands (it previously 
differed per command, for
+example 60 for `transformer` and 30 elsewhere).
+
+Terminal width is now detected on Windows (`cmd` / PowerShell) via `mode con`, 
in addition to the
+existing `COLUMNS` / `stty size` detection. When no terminal can be detected 
(for example when the
+output is piped or redirected), the width falls back to 120 columns. For full, 
untruncated output
+suitable for scripting, use the `--json` option.
+
+The `camel infra list` table now sizes its `DESCRIPTION` column to the 
terminal width, and truncates
+the `IMPLEMENTATION` and `SERVICE_DATA` columns with an ellipsis instead of 
letting the raw service
+data overflow the terminal. The complete, structured service data remains 
available via `--json`.
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java
index a83f99aa1113..b8ac84ee7605 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogBaseCommand.java
@@ -20,18 +20,19 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import com.github.freva.asciitable.AsciiTable;
 import com.github.freva.asciitable.Column;
 import com.github.freva.asciitable.HorizontalAlign;
-import com.github.freva.asciitable.OverflowBehaviour;
 import org.apache.camel.catalog.CamelCatalog;
 import org.apache.camel.catalog.DefaultCamelCatalog;
 import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
 import org.apache.camel.dsl.jbang.core.commands.MavenResolverMixin;
 import org.apache.camel.dsl.jbang.core.commands.QuarkusPlatformMixin;
+import org.apache.camel.dsl.jbang.core.common.CamelTableColumns;
 import org.apache.camel.dsl.jbang.core.common.CatalogLoader;
 import org.apache.camel.dsl.jbang.core.common.RuntimeCompletionCandidates;
 import org.apache.camel.dsl.jbang.core.common.RuntimeType;
@@ -159,27 +160,28 @@ public abstract class CatalogBaseCommand extends 
CamelCommand {
                                         .map(CatalogBaseDTO::toMap)
                                         .collect(Collectors.toList())));
             } else {
-                // Compute description width: terminal minus fixed columns and 
border overhead
-                int fixedWidth = nameWidth() + 12 + 8; // LEVEL ~12 chars, 
SINCE ~8 chars
-                if (RuntimeType.quarkus == runtime) {
-                    fixedWidth += 8; // NATIVE column
-                }
-                int descWidth = TerminalWidthHelper.flexWidth(
-                        terminalWidth(), fixedWidth, 
TerminalWidthHelper.noBorderOverhead(
-                                RuntimeType.quarkus == runtime ? 5 : 4),
-                        20, 80);
+                // Size the DESCRIPTION column to fill the terminal: measure 
the actual width of the other
+                // visible columns and give the remainder to DESCRIPTION 
(floored on narrow terminals).
+                boolean quarkus = RuntimeType.quarkus == runtime;
+                Function<Row, String> nameGetter = displayGav ? this::shortGav 
: r -> r.name;
+                int nameW = CamelTableColumns.measure(displayGav ? 
"ARTIFACT-ID" : "NAME",
+                        displayGav ? Integer.MAX_VALUE : 
CamelTableColumns.NAME_MAX, rows, nameGetter);
+                int levelW = CamelTableColumns.measure("LEVEL", 
Integer.MAX_VALUE, rows, this::level);
+                int sinceW = CamelTableColumns.measure("SINCE", 
Integer.MAX_VALUE, rows, r -> r.since);
+                int overhead = TerminalWidthHelper.noBorderOverhead(quarkus ? 
5 : 4);
+                int descWidth = quarkus
+                        ? CamelTableColumns.lastColumnWidth(terminalWidth(), 
overhead, nameW, levelW, sinceW,
+                                CamelTableColumns.measure("NATIVE", 
Integer.MAX_VALUE, rows, this::nativeSupported))
+                        : CamelTableColumns.lastColumnWidth(terminalWidth(), 
overhead, nameW, levelW, sinceW);
                 printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, 
rows, Arrays.asList(
-                        new 
Column().header("NAME").visible(!displayGav).dataAlign(HorizontalAlign.LEFT).maxWidth(nameWidth())
-                                .with(r -> r.name),
+                        CamelTableColumns.name().visible(!displayGav).with(r 
-> r.name),
                         new 
Column().header("ARTIFACT-ID").visible(displayGav).dataAlign(HorizontalAlign.LEFT)
                                 .with(this::shortGav),
                         new 
Column().header("LEVEL").dataAlign(HorizontalAlign.LEFT).with(this::level),
                         new 
Column().header("NATIVE").dataAlign(HorizontalAlign.CENTER)
-                                .visible(RuntimeType.quarkus == 
runtime).with(this::nativeSupported),
-                        new 
Column().header("SINCE").dataAlign(HorizontalAlign.RIGHT).with(r -> r.since),
-                        new 
Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT)
-                                .maxWidth(descWidth, 
OverflowBehaviour.ELLIPSIS_RIGHT)
-                                .with(this::shortDescription))));
+                                .visible(quarkus).with(this::nativeSupported),
+                        CamelTableColumns.since().with(r -> r.since),
+                        CamelTableColumns.lastText("DESCRIPTION", 
descWidth).with(this::shortDescription))));
             }
         } else if (filterName != null) {
             // suggest similar names when filter returns no results
@@ -196,10 +198,6 @@ public abstract class CatalogBaseCommand extends 
CamelCommand {
         return 0;
     }
 
-    int nameWidth() {
-        return 30;
-    }
-
     int sortRow(Row o1, Row o2) {
         String s = sort;
         int negate = 1;
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java
index bc00499e416e..18cae77dd45c 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogKamelet.java
@@ -29,6 +29,7 @@ import com.github.freva.asciitable.Column;
 import com.github.freva.asciitable.HorizontalAlign;
 import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CamelTableColumns;
 import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper;
 import org.apache.camel.dsl.jbang.core.common.VersionHelper;
 import org.apache.camel.main.download.DependencyDownloaderClassLoader;
@@ -113,18 +114,17 @@ public class CatalogKamelet extends CamelCommand {
         rows.sort(this::sortRow);
 
         if (!rows.isEmpty()) {
-            int tw = terminalWidth();
-            // Fixed columns: NAME (~30), TYPE (10), LEVEL (12)
-            int fixedWidth = 30 + 10 + 12;
-            int descWidth = TerminalWidthHelper.flexWidth(
-                    tw, fixedWidth, TerminalWidthHelper.noBorderOverhead(4),
-                    20, 80);
+            // Size the DESCRIPTION column to fill the terminal from the 
measured width of the other columns.
+            int nameW = CamelTableColumns.measure("NAME", 
CamelTableColumns.NAME_MAX, rows, r -> r.name);
+            int typeW = Math.max(10, CamelTableColumns.measure("TYPE", 
Integer.MAX_VALUE, rows, r -> r.type));
+            int levelW = Math.max(12, CamelTableColumns.measure("LEVEL", 
Integer.MAX_VALUE, rows, r -> r.supportLevel));
+            int descWidth = CamelTableColumns.lastColumnWidth(
+                    terminalWidth(), TerminalWidthHelper.noBorderOverhead(4), 
nameW, typeW, levelW);
             printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, 
Arrays.asList(
-                    new 
Column().header("NAME").dataAlign(HorizontalAlign.LEFT).with(r -> r.name),
+                    CamelTableColumns.name().with(r -> r.name),
                     new 
Column().header("TYPE").dataAlign(HorizontalAlign.LEFT).minWidth(10).with(r -> 
r.type),
                     new 
Column().header("LEVEL").dataAlign(HorizontalAlign.LEFT).minWidth(12).with(r -> 
r.supportLevel),
-                    new 
Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).maxWidth(descWidth)
-                            .with(this::getDescription))));
+                    CamelTableColumns.lastText("DESCRIPTION", 
descWidth).with(this::getDescription))));
         }
 
         return 0;
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogTransformer.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogTransformer.java
index 0d44412ff816..317538e1c127 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogTransformer.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/catalog/CatalogTransformer.java
@@ -35,11 +35,6 @@ public class CatalogTransformer extends CatalogBaseCommand {
         super(main);
     }
 
-    @Override
-    int nameWidth() {
-        return 60;
-    }
-
     @Override
     List<Row> collectRows() {
         List<Row> rows = new ArrayList<>();
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
index 474cdb266f6a..e59bfd51653a 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraBaseCommand.java
@@ -48,6 +48,7 @@ import org.apache.camel.catalog.CamelCatalog;
 import org.apache.camel.catalog.DefaultCamelCatalog;
 import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CamelTableColumns;
 import org.apache.camel.dsl.jbang.core.common.CommandLineHelper;
 import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper;
 import org.apache.camel.dsl.jbang.core.model.InfraBaseDTO;
@@ -192,40 +193,54 @@ public abstract class InfraBaseCommand extends 
CamelCommand {
         if (jsonOutput) {
             printer().println(
                     Jsoner.serialize(
-                            rows.stream().map(row -> {
-                                Object serviceDataObj = null;
-                                try {
-                                    serviceDataObj = 
Jsoner.deserialize(row.serviceData());
-                                } catch (DeserializationException e) {
-                                    // ignore
-                                }
-                                return new InfraBaseDTO(row.alias, 
row.aliasImplementation, row.description, serviceDataObj);
-                            })
+                            rows.stream().map(row -> new InfraBaseDTO(
+                                    row.alias, row.aliasImplementation, 
row.description,
+                                    parseServiceData(row.serviceData())))
                                     .map(InfraBaseDTO::toMap)
                                     .collect(Collectors.toList())));
         } else {
             int tw = terminalWidth();
-            // Fixed columns: PID (~8), ALIAS (width+2), SERVICE_DATA (~30), 
DESCRIPTION (~30)
-            int fixedWidth = (width + 2) + 30 + 30;
-            if (showPidColumn()) {
-                fixedWidth += 8;
-            }
-            int implWidth = TerminalWidthHelper.flexWidth(
-                    tw, fixedWidth, 
TerminalWidthHelper.noBorderOverhead(showPidColumn() ? 5 : 4),
-                    20, 35);
+            // Size DESCRIPTION to fill the terminal: measure the other 
columns so it gets the exact remainder.
+            // IMPLEMENTATION is capped and SERVICE_DATA keeps a compact fixed 
width; both truncate with an ellipsis
+            // instead of overflowing the terminal (the full, structured 
service data is available via --json).
+            int serviceDataWidth = 30;
+            int aliasWidth = width + 2;
+            int pidWidth = showPidColumn()
+                    ? CamelTableColumns.measure("PID", Integer.MAX_VALUE, 
rows, r -> r.pid) : 0;
+            int implWidth = CamelTableColumns.measure("IMPLEMENTATION", 35, 
rows, Row::aliasImplementation);
+            int overhead = 
TerminalWidthHelper.noBorderOverhead(showPidColumn() ? 5 : 4);
+            int descWidth = CamelTableColumns.lastColumnWidth(
+                    tw, overhead, pidWidth, aliasWidth, implWidth, 
serviceDataWidth);
             printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, 
Arrays.asList(
                     new 
Column().header("PID").visible(showPidColumn()).headerAlign(HorizontalAlign.CENTER).with(r
 -> r.pid),
-                    new Column().header("ALIAS").minWidth(width + 
2).dataAlign(HorizontalAlign.LEFT)
+                    new 
Column().header("ALIAS").minWidth(aliasWidth).dataAlign(HorizontalAlign.LEFT)
                             .with(Row::alias),
-                    new Column().header("IMPLEMENTATION").maxWidth(implWidth, 
OverflowBehaviour.NEWLINE)
+                    new Column().header("IMPLEMENTATION").maxWidth(implWidth, 
OverflowBehaviour.ELLIPSIS_RIGHT)
                             
.dataAlign(HorizontalAlign.LEFT).with(Row::aliasImplementation),
-                    new 
Column().header("DESCRIPTION").dataAlign(HorizontalAlign.LEFT).with(Row::description),
-                    new 
Column().header("SERVICE_DATA").dataAlign(HorizontalAlign.LEFT).with(Row::serviceData))));
+                    CamelTableColumns.lastText("DESCRIPTION", 
descWidth).with(Row::description),
+                    new 
Column().header("SERVICE_DATA").maxWidth(serviceDataWidth, 
OverflowBehaviour.ELLIPSIS_RIGHT)
+                            
.dataAlign(HorizontalAlign.LEFT).with(Row::serviceData))));
         }
 
         return 0;
     }
 
+    /**
+     * Parses the raw service-data JSON string (read from the infra {@code 
.json} file) into a structured object so it
+     * is emitted as nested JSON by {@code --json}, rather than as an escaped 
string. Returns {@code null} (so the
+     * {@code serviceData} field is omitted) when there is no data or the 
stored content is not valid JSON.
+     */
+    static Object parseServiceData(String serviceData) {
+        if (serviceData == null) {
+            return null;
+        }
+        try {
+            return Jsoner.deserialize(serviceData);
+        } catch (DeserializationException e) {
+            return null;
+        }
+    }
+
     private String getServiceData(String key, String pid) {
         Path jsonFilePath = 
CommandLineHelper.getCamelDir().resolve(getJsonFileName(key, pid));
         if (jsonFilePath.toFile().exists()) {
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java
index 57a9182715ec..739aafdce5ca 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/update/UpdateList.java
@@ -37,6 +37,7 @@ import com.github.freva.asciitable.Column;
 import com.github.freva.asciitable.HorizontalAlign;
 import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CamelTableColumns;
 import org.apache.camel.dsl.jbang.core.common.RuntimeType;
 import org.apache.camel.dsl.jbang.core.common.TerminalWidthHelper;
 import org.apache.camel.dsl.jbang.core.common.VersionHelper;
@@ -183,21 +184,23 @@ public class UpdateList extends CamelCommand {
                                     .map(UpdateListDTO::toMap)
                                     .collect(Collectors.toList())));
         } else {
-            int tw = terminalWidth();
-            // Fixed columns: VERSION (10), RUNTIME (~18), RUNTIME VERSION 
(~17)
-            int fixedWidth = 10 + 18 + 17;
-            int descWidth = TerminalWidthHelper.flexWidth(
-                    tw, fixedWidth, TerminalWidthHelper.noBorderOverhead(4),
-                    20, 80);
+            // Size the DESCRIPTION column to fill the terminal: measure the 
actual rendered width of the
+            // other columns so the remainder handed to the last column is 
exact (see CamelTableColumns).
+            int versionW = CamelTableColumns.measure("VERSION", 
Integer.MAX_VALUE, rows, r -> r.version().toString());
+            int runtimeW = CamelTableColumns.measure("RUNTIME", 
Integer.MAX_VALUE, rows, r -> r.runtime());
+            int runtimeVersionW
+                    = CamelTableColumns.measure("RUNTIME VERSION", 
Integer.MAX_VALUE, rows, r -> r.runtimeVersion());
+            int overhead = TerminalWidthHelper.noBorderOverhead(4);
+            int descWidth
+                    = CamelTableColumns.lastColumnWidth(terminalWidth(), 
overhead, versionW, runtimeW, runtimeVersionW);
             printer().println(AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, 
Arrays.asList(
-                    new 
Column().header("VERSION").minWidth(10).dataAlign(HorizontalAlign.LEFT)
+                    new 
Column().header("VERSION").dataAlign(HorizontalAlign.LEFT)
                             .with(r -> r.version().toString()),
                     new Column().header("RUNTIME")
                             .dataAlign(HorizontalAlign.LEFT).with(r -> 
r.runtime()),
                     new Column().header("RUNTIME VERSION")
                             .dataAlign(HorizontalAlign.LEFT).with(r -> 
r.runtimeVersion()),
-                    new Column().header("DESCRIPTION").maxWidth(descWidth)
-                            .dataAlign(HorizontalAlign.LEFT).with(r -> 
r.description()))));
+                    CamelTableColumns.lastText("DESCRIPTION", 
descWidth).with(r -> r.description()))));
         }
 
         return 0;
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelTableColumns.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelTableColumns.java
new file mode 100644
index 000000000000..838ff1b78ab8
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/CamelTableColumns.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.common;
+
+import java.util.Collection;
+import java.util.function.Function;
+import java.util.stream.IntStream;
+
+import com.github.freva.asciitable.Column;
+import com.github.freva.asciitable.HorizontalAlign;
+import com.github.freva.asciitable.OverflowBehaviour;
+
+/**
+ * Standardized {@link Column} definitions for camel-jbang table output.
+ *
+ * <p>
+ * The same logical column (NAME, DESCRIPTION, ...) was previously hand-rolled 
in every command with differing widths
+ * and overflow behaviour. These factories give a single source of truth so 
tables render consistently, and so the last
+ * (rightmost) free-text column can be sized to fill the terminal width.
+ *
+ * <p>
+ * Each factory returns a pre-configured {@link Column}; the caller chains 
{@code .with(getter)} (which returns the
+ * opaque {@code ColumnData}), so all configuration must happen before {@code 
with}.
+ */
+public final class CamelTableColumns {
+
+    /**
+     * Maximum width for a NAME column. A name longer than this is the rare 
case; short names render at their content
+     * width regardless, so this only acts as a ceiling.
+     */
+    public static final int NAME_MAX = 60;
+
+    /** Minimum width for the last free-text column on narrow terminals. */
+    public static final int LAST_MIN = 20;
+
+    private CamelTableColumns() {
+    }
+
+    /** Standard NAME column: left aligned, capped at {@link #NAME_MAX}. */
+    public static Column name() {
+        return new 
Column().header("NAME").dataAlign(HorizontalAlign.LEFT).maxWidth(NAME_MAX);
+    }
+
+    /** Standard SINCE column: right aligned. */
+    public static Column since() {
+        return new Column().header("SINCE").dataAlign(HorizontalAlign.RIGHT);
+    }
+
+    /**
+     * The rightmost free-text column. Grows up to {@code width} and truncates 
with an ellipsis so each row stays on a
+     * single line (use this for flat list/status tables; detail views may 
keep {@code NEWLINE} wrapping).
+     *
+     * @param header the column header
+     * @param width  the maximum width, typically from {@link 
#lastColumnWidth(int, int, int...)}
+     */
+    public static Column lastText(String header, int width) {
+        return new Column().header(header).dataAlign(HorizontalAlign.LEFT)
+                .maxWidth(width, OverflowBehaviour.ELLIPSIS_RIGHT);
+    }
+
+    /**
+     * Actual rendered width of a structured column: the longest of the header 
and any cell value, capped at
+     * {@code maxWidth}. Pass {@link Integer#MAX_VALUE} for an unbounded 
column.
+     *
+     * @param header   the column header (may be {@code null})
+     * @param maxWidth the column's maximum width (ceiling)
+     * @param rows     the rows being rendered
+     * @param getter   accessor returning the cell value for a row
+     */
+    public static <T> int measure(String header, int maxWidth, Collection<T> 
rows, Function<T, String> getter) {
+        int width = header != null ? header.length() : 0;
+        for (T row : rows) {
+            String value = getter.apply(row);
+            if (value != null) {
+                width = Math.max(width, value.length());
+            }
+        }
+        return Math.min(width, maxWidth);
+    }
+
+    /**
+     * Width for the last column so the table reaches the terminal edge: the 
terminal width minus the (actual) widths of
+     * the other columns and the border overhead, floored at {@link #LAST_MIN}.
+     *
+     * @param terminalWidth  total terminal width in columns
+     * @param borderOverhead overhead from borders/padding (see {@link 
TerminalWidthHelper#noBorderOverhead(int)})
+     * @param otherWidths    the measured widths of every other (visible) 
column
+     */
+    public static int lastColumnWidth(int terminalWidth, int borderOverhead, 
int... otherWidths) {
+        int others = IntStream.of(otherWidths).sum();
+        return TerminalWidthHelper.fillWidth(terminalWidth, others, 
borderOverhead, LAST_MIN);
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelper.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelper.java
index e096f8f96150..24e1e7e3ff04 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelper.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelper.java
@@ -16,12 +16,17 @@
  */
 package org.apache.camel.dsl.jbang.core.common;
 
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * Helper for detecting the terminal width to adapt table and command output.
  *
  * <p>
- * Uses the {@code COLUMNS} environment variable or {@code stty size} to 
detect the terminal width. Falls back to a
- * default width when the terminal size cannot be determined (e.g., when 
output is piped or redirected).
+ * Uses the {@code COLUMNS} environment variable, {@code stty size} (POSIX) or 
{@code mode con} (Windows) to detect the
+ * terminal width. Falls back to a default width when the terminal size cannot 
be determined (e.g., when output is piped
+ * or redirected).
  *
  * <p>
  * Avoids using JLine's {@code TerminalBuilder} for width detection because it 
sends escape sequence queries (DA1, CPR)
@@ -32,6 +37,8 @@ public final class TerminalWidthHelper {
     private static final int DEFAULT_WIDTH = 120;
     private static final int MIN_WIDTH = 40;
 
+    private static final Pattern INTEGER = Pattern.compile("\\d+");
+
     private TerminalWidthHelper() {
     }
 
@@ -39,8 +46,8 @@ public final class TerminalWidthHelper {
      * Returns the current terminal width in columns.
      *
      * <p>
-     * Tries {@code COLUMNS} environment variable first, then {@code stty 
size}. Returns {@value #DEFAULT_WIDTH} if
-     * detection fails or if the output is not connected to a terminal.
+     * Tries the {@code COLUMNS} environment variable first, then {@code stty 
size} on POSIX or {@code mode con} on
+     * Windows. Returns {@value #DEFAULT_WIDTH} if detection fails or if the 
output is not connected to a terminal.
      */
     public static int getTerminalWidth() {
         // Try COLUMNS env var first (set by most shells)
@@ -55,26 +62,58 @@ public final class TerminalWidthHelper {
                 // ignore
             }
         }
-        // Fall back to stty which reads the terminal size without escape 
sequences
+        // Fall back to an OS native command that reads the terminal size 
without escape sequences
+        int w = isWindows()
+                ? readWidthFromCommand("cmd", "/c", "mode", "con")
+                : readWidthFromCommand("stty", "size");
+        if (w > 0) {
+            return Math.max(w, MIN_WIDTH);
+        }
+        return DEFAULT_WIDTH;
+    }
+
+    private static boolean isWindows() {
+        return System.getProperty("os.name", 
"").toLowerCase(Locale.ROOT).startsWith("windows");
+    }
+
+    private static int readWidthFromCommand(String... command) {
         try {
-            Process p = new ProcessBuilder("stty", "size")
+            Process p = new ProcessBuilder(command)
                     .redirectInput(ProcessBuilder.Redirect.INHERIT)
                     .start();
-            String output = new 
String(p.getInputStream().readAllBytes()).trim();
+            String output = new String(p.getInputStream().readAllBytes());
             p.waitFor();
-            if (!output.isEmpty()) {
-                String[] parts = output.split("\\s+");
-                if (parts.length >= 2) {
-                    int w = Integer.parseInt(parts[1]);
-                    if (w > 0) {
-                        return Math.max(w, MIN_WIDTH);
-                    }
-                }
-            }
+            return parseColumns(output);
         } catch (Exception e) {
-            // ignore — stty not available (e.g. Windows)
+            // ignore — command not available (e.g. stty/mode missing)
+            return -1;
         }
-        return DEFAULT_WIDTH;
+    }
+
+    /**
+     * Parses the column count from the output of {@code stty size} ("rows 
cols") or Windows {@code mode con} (a
+     * multi-line "Lines: N / Columns: N" block). Both place the column count 
as the <b>second</b> integer in the
+     * output, so it is parsed positionally rather than by label to survive 
localized Windows output where the
+     * {@code Columns:} label is translated.
+     *
+     * @param  output the raw command output
+     * @return        the column count, or {@code -1} if it cannot be 
determined
+     */
+    static int parseColumns(String output) {
+        if (output == null) {
+            return -1;
+        }
+        Matcher m = INTEGER.matcher(output);
+        Integer first = null;
+        while (m.find()) {
+            int value = Integer.parseInt(m.group());
+            if (first == null) {
+                first = value;
+            } else {
+                return value;
+            }
+        }
+        return -1;
     }
 
     /**
@@ -96,6 +135,23 @@ public final class TerminalWidthHelper {
         return Math.max(minFlexWidth, Math.min(maxFlexWidth, available));
     }
 
+    /**
+     * Computes the width for the last column so the table fills the terminal 
width. Unlike
+     * {@link #flexWidth(int, int, int, int, int)} there is no upper cap: the 
column grows all the way to the terminal
+     * edge.
+     *
+     * @param  terminalWidth     total terminal width in columns
+     * @param  fixedColumnsWidth sum of the (actual) widths of all other 
columns
+     * @param  borderOverhead    overhead from table borders and padding (use 
{@link #noBorderOverhead(int)} or
+     *                           {@link #fancyBorderOverhead(int)})
+     * @param  minWidth          minimum width for the last column (used when 
terminal is narrow)
+     * @return                   the computed width for the last column
+     */
+    public static int fillWidth(
+            int terminalWidth, int fixedColumnsWidth, int borderOverhead, int 
minWidth) {
+        return Math.max(minWidth, terminalWidth - fixedColumnsWidth - 
borderOverhead);
+    }
+
     /**
      * Scales a column width proportionally based on available terminal width. 
All columns with the given preferred
      * widths are scaled proportionally to fit within the terminal.
@@ -119,10 +175,11 @@ public final class TerminalWidthHelper {
     }
 
     /**
-     * Border overhead for NO_BORDERS tables: 2 spaces between each column 
pair.
+     * Border overhead for NO_BORDERS tables. AsciiTable pads every column 
with one leading and one trailing space (no
+     * separator characters), so the overhead is exactly {@code 2 * 
columnCount} regardless of the number of columns.
      */
     public static int noBorderOverhead(int columnCount) {
-        return (columnCount - 1) * 2;
+        return columnCount * 2;
     }
 
     /**
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
index f82c23ac25f3..e8983b74be70 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/infra/InfraTest.java
@@ -21,6 +21,8 @@ import java.util.stream.Collectors;
 
 import org.apache.camel.dsl.jbang.core.commands.CamelCommandBaseTestSupport;
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.model.InfraBaseDTO;
+import org.apache.camel.util.json.Jsoner;
 import org.assertj.core.api.Assertions;
 import org.awaitility.Awaitility;
 import org.junit.jupiter.api.Test;
@@ -69,4 +71,32 @@ public class InfraTest extends CamelCommandBaseTestSupport {
         Assertions.assertThat(output).contains("amqp");
         Assertions.assertThat(output).contains("minio");
     }
+
+    @Test
+    public void serviceDataInJsonIsNestedNotEscaped() {
+        String rawServiceData = "{\"host\":\"localhost\",\"port\":61616}";
+        Object serviceData = InfraBaseCommand.parseServiceData(rawServiceData);
+
+        InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", 
serviceData);
+        String json = Jsoner.serialize(List.of(dto.toMap()));
+
+        // serviceData is embedded as a nested JSON object (so --json is 
machine-parseable), not a string-escaped blob
+        Assertions.assertThat(json).contains("\"serviceData\":{");
+        Assertions.assertThat(json).contains("\"host\":\"localhost\"");
+        Assertions.assertThat(json).doesNotContain("\\\"host\\\"");
+    }
+
+    @Test
+    public void malformedServiceDataIsOmittedFromJson() {
+        Object serviceData = InfraBaseCommand.parseServiceData("{not valid 
json");
+
+        // unparseable content is dropped rather than emitted as an escaped 
string
+        Assertions.assertThat(serviceData).isNull();
+
+        InfraBaseDTO dto = new InfraBaseDTO("artemis", "amqp", "AMQP broker", 
serviceData);
+        String json = Jsoner.serialize(List.of(dto.toMap()));
+
+        Assertions.assertThat(json).contains("\"alias\":\"artemis\"");
+        Assertions.assertThat(json).doesNotContain("serviceData");
+    }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/CamelTableColumnsTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/CamelTableColumnsTest.java
new file mode 100644
index 000000000000..7c15ae7687c1
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/CamelTableColumnsTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.common;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+
+import com.github.freva.asciitable.AsciiTable;
+import com.github.freva.asciitable.Column;
+import com.github.freva.asciitable.HorizontalAlign;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class CamelTableColumnsTest {
+
+    private static final Function<String, String> IDENTITY = s -> s;
+
+    // --- measure ---
+
+    @Test
+    void measureUsesLongestCellWhenWiderThanHeader() {
+        List<String> rows = List.of("ftp", "salesforce", "kafka");
+        // longest value "salesforce" = 10, header "NAME" = 4
+        assertEquals(10, CamelTableColumns.measure("NAME", 
CamelTableColumns.NAME_MAX, rows, IDENTITY));
+    }
+
+    @Test
+    void measureUsesHeaderWhenWiderThanCells() {
+        List<String> rows = List.of("x", "y");
+        // header "DESCRIPTION" = 11 is wider than any 1-char value
+        assertEquals(11, CamelTableColumns.measure("DESCRIPTION", 
Integer.MAX_VALUE, rows, IDENTITY));
+    }
+
+    @Test
+    void measureCapsAtMaxWidth() {
+        List<String> rows = 
List.of("a-very-long-component-name-that-exceeds-the-cap-by-a-lot-indeed");
+        // value length is > NAME_MAX, so it is capped at NAME_MAX
+        assertEquals(CamelTableColumns.NAME_MAX,
+                CamelTableColumns.measure("NAME", CamelTableColumns.NAME_MAX, 
rows, IDENTITY));
+    }
+
+    @Test
+    void measureIgnoresNullCells() {
+        List<String> rows = Arrays.asList("ok", null, "fine");
+        assertEquals(4, CamelTableColumns.measure("N", Integer.MAX_VALUE, 
rows, IDENTITY));
+    }
+
+    // --- lastColumnWidth ---
+
+    @Test
+    void lastColumnWidthConsumesExactRemainder() {
+        // 200 terminal - (20 + 10 + 8) others - 6 borders = 156 for the last 
column
+        assertEquals(156, CamelTableColumns.lastColumnWidth(200, 6, 20, 10, 
8));
+    }
+
+    @Test
+    void lastColumnWidthFloorsAtLastMinOnNarrowTerminal() {
+        // remainder would be negative, so it is floored at LAST_MIN
+        assertEquals(CamelTableColumns.LAST_MIN, 
CamelTableColumns.lastColumnWidth(40, 6, 30, 12, 10));
+    }
+
+    // --- rendering: a table sized with lastColumnWidth must fit the terminal 
---
+
+    @Test
+    void lastColumnWidthKeepsRenderedTableWithinTerminal() {
+        // The whole point of filling the terminal is that the rendered line 
still fits inside it. A single-line
+        // description longer than the last column exercises the exact-fit 
case where an off-by-one in the border
+        // overhead would overflow the terminal by a couple of columns.
+        int terminalWidth = 100;
+        List<String[]> rows = List.of(
+                new String[] {
+                        "ftp", "Stable", "4.0",
+                        "A very long component description that definitely 
exceeds the remaining width and must be truncated" },
+                new String[] { "salesforce-streaming", "Preview", "3.1", 
"short" });
+
+        int nameW = CamelTableColumns.measure("NAME", 
CamelTableColumns.NAME_MAX, rows, r -> r[0]);
+        int levelW = CamelTableColumns.measure("LEVEL", Integer.MAX_VALUE, 
rows, r -> r[1]);
+        int sinceW = CamelTableColumns.measure("SINCE", Integer.MAX_VALUE, 
rows, r -> r[2]);
+        int descWidth = CamelTableColumns.lastColumnWidth(
+                terminalWidth, TerminalWidthHelper.noBorderOverhead(4), nameW, 
levelW, sinceW);
+
+        String table = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, 
Arrays.asList(
+                CamelTableColumns.name().with(r -> r[0]),
+                new 
Column().header("LEVEL").dataAlign(HorizontalAlign.LEFT).with(r -> r[1]),
+                CamelTableColumns.since().with(r -> r[2]),
+                CamelTableColumns.lastText("DESCRIPTION", descWidth).with(r -> 
r[3])));
+
+        for (String line : table.split("\n")) {
+            assertTrue(line.length() <= terminalWidth,
+                    "Rendered line width %d exceeds terminal %d: 
[%s]".formatted(line.length(), terminalWidth, line));
+        }
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelperTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelperTest.java
index af8e5da22c3e..3b331cf0dcfb 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelperTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/common/TerminalWidthHelperTest.java
@@ -31,6 +31,63 @@ class TerminalWidthHelperTest {
         assertTrue(width >= 40, "Terminal width should be at least 40, got: " 
+ width);
     }
 
+    // --- fillWidth ---
+
+    @Test
+    void fillWidthFillsRemainingSpaceWithoutCap() {
+        // 200 cols - 80 others - 6 borders = 114 available; no upper cap, so 
the last column keeps all 114
+        assertEquals(114, TerminalWidthHelper.fillWidth(200, 80, 6, 20));
+    }
+
+    @Test
+    void fillWidthFloorsAtMinOnNarrowTerminal() {
+        // 60 cols - 86 others - 6 borders = -32 available; floored at min 20
+        assertEquals(20, TerminalWidthHelper.fillWidth(60, 86, 6, 20));
+    }
+
+    // --- parseColumns (shared by stty size and Windows mode con) ---
+
+    @Test
+    void parseColumnsFromStty() {
+        // stty size prints "rows cols"; the column count is the second integer
+        assertEquals(80, TerminalWidthHelper.parseColumns("24 80"));
+        assertEquals(211, TerminalWidthHelper.parseColumns("51 211\n"));
+    }
+
+    @Test
+    void parseColumnsFromWindowsModeCon() {
+        String output = """
+                Status for device CON:
+                ----------------------
+                    Lines:          30
+                    Columns:        120
+                    Keyboard rate:  31
+                    Keyboard delay: 1
+                    Code page:      850
+                """;
+        assertEquals(120, TerminalWidthHelper.parseColumns(output));
+    }
+
+    @Test
+    void parseColumnsFromLocalizedModeCon() {
+        // Non-English Windows translates the labels; parsing the second 
integer positionally still works
+        String output = """
+                État du périphérique CON :
+                --------------------------
+                    Lignes :        30
+                    Colonnes :      120
+                """;
+        assertEquals(120, TerminalWidthHelper.parseColumns(output));
+    }
+
+    @Test
+    void parseColumnsReturnsNegativeWhenUndetermined() {
+        assertEquals(-1, TerminalWidthHelper.parseColumns(null));
+        assertEquals(-1, TerminalWidthHelper.parseColumns(""));
+        assertEquals(-1, TerminalWidthHelper.parseColumns("no numbers here"));
+        assertEquals(-1, TerminalWidthHelper.parseColumns("42")); // only one 
integer, no column value
+    }
+
     // --- flexWidth ---
 
     @Test
@@ -101,14 +158,16 @@ class TerminalWidthHelperTest {
 
     @Test
     void noBorderOverheadSingleColumn() {
-        assertEquals(0, TerminalWidthHelper.noBorderOverhead(1));
+        // one leading + one trailing padding space around the single column
+        assertEquals(2, TerminalWidthHelper.noBorderOverhead(1));
     }
 
     @Test
     void noBorderOverheadMultipleColumns() {
-        assertEquals(2, TerminalWidthHelper.noBorderOverhead(2));
-        assertEquals(6, TerminalWidthHelper.noBorderOverhead(4));
-        assertEquals(16, TerminalWidthHelper.noBorderOverhead(9));
+        // each column contributes 2 padding spaces (one on each side)
+        assertEquals(4, TerminalWidthHelper.noBorderOverhead(2));
+        assertEquals(8, TerminalWidthHelper.noBorderOverhead(4));
+        assertEquals(18, TerminalWidthHelper.noBorderOverhead(9));
     }
 
     // --- fancyBorderOverhead ---
@@ -168,19 +227,19 @@ class TerminalWidthHelperTest {
     void flexWidthForNoBordersProcessCommand() {
         // Simulate ListProcess: 9 columns, fixed ~56 chars, NAME flex (max 
40), error flex (max 70)
         int tw = 80;
-        int borders = TerminalWidthHelper.noBorderOverhead(9); // 16
+        int borders = TerminalWidthHelper.noBorderOverhead(9); // 18
         int nameW = TerminalWidthHelper.flexWidth(tw, 56, borders, 15, 40);
-        // 80 - 56 - 16 = 8, but min is 15
+        // 80 - 56 - 18 = 6, but min is 15
         assertEquals(15, nameW);
 
         tw = 120;
         nameW = TerminalWidthHelper.flexWidth(tw, 56, borders, 15, 40);
-        // 120 - 56 - 16 = 48, capped at max 40
+        // 120 - 56 - 18 = 46, capped at max 40
         assertEquals(40, nameW);
 
         tw = 100;
         nameW = TerminalWidthHelper.flexWidth(tw, 56, borders, 15, 40);
-        // 100 - 56 - 16 = 28
-        assertEquals(28, nameW);
+        // 100 - 56 - 18 = 26
+        assertEquals(26, nameW);
     }
 }


Reply via email to