Преглед изворни кода

fix(archives): keep the project name when the wrong-plate guard rejects a 3MF (issue #3126)

    Bambu Studio files a sliced print on the X2D's internal eMMC, which FTPS
    does not serve. The bounded probe found a same-named file on the card --
    an earlier slice of the same project, plate 4, against a running plate 1
    -- and #1204's guard correctly refused it rather than archive another
    plate's thumbnail, filament and cost.

    It then blanked subtask_name because swap_plate_suffix returned None. But
    None also means "this name carries no plate suffix", and such a name holds
    no stale plate number to be wrong about. The project name was dropped, the
    row fell through to the gcode_file path, and the archive was titled
    plate_1.

    Keep the name for the title only. subtask_name itself stays disowned,
    because it is what every lookup here is built from and it keys
    _active_prints, where the cover endpoint's own download of that same name
    would find this archive and hand the contradicted file to
    _recover_fallback_archive -- which checks a candidate is a readable 3MF
    and never which plate it holds. A corrected name is still registered:
    that one points at the plate actually running.

    Also name the X2D alongside H2-series and P2S in the Archives banner, the
    connection diagnostic and the storage-verdict docs -- it stores slicer
    sends the same way, and an X2D owner was told the explanation did not
    apply.
maziggy пре 3 дана
родитељ
комит
fd3efe4a92

+ 2 - 2
backend/app/api/routes/archives.py

@@ -539,8 +539,8 @@ async def no_3mf_warning(
     single-cause wording sent people the wrong way. Historically the only
     known cause was install step 4 ("Store sent files on external storage")
     being off in the slicer, so the banner said so unconditionally. On
-    H2-series and P2S that advice is actively wrong: the setting is already on
-    and turning it on again changes nothing, because the printer keeps the
+    H2-series, P2S and X2D that advice is actively wrong: the setting is already
+    on and turning it on again changes nothing, because the printer keeps the
     sliced file on internal storage that FTPS does not serve at all (#2780).
 
     ``reason`` is the slug from :mod:`print_storage` when we recorded one,

+ 33 - 10
backend/app/main.py

@@ -4098,6 +4098,15 @@ async def on_print_start(printer_id: int, data: dict):
         # transfer, not the file, is what failed, and that does not last (#3063).
         ftp_transfer_failed = False
 
+        # The print's name, for a fallback archive whose `subtask_name` the
+        # plate guard below had to disown. Display only, and deliberately kept
+        # apart from `subtask_name`: that variable is what every file lookup
+        # here is built from, and once a name has been shown to fetch another
+        # plate's 3MF it must not key `_active_prints` either, or the cover
+        # endpoint hands the same contradicted file to
+        # `_recover_fallback_archive` and fills the row in with it (#3126).
+        display_name_after_plate_reject: str | None = None
+
         # Get FTP retry settings
         ftp_retry_enabled, ftp_retry_count, ftp_retry_delay, ftp_timeout = await get_ftp_retry_settings()
 
@@ -4436,13 +4445,24 @@ async def on_print_start(printer_id: int, data: dict):
                     # so the row would be filled in with another plate's
                     # filament and cost, the exact swap #2957 removed (#3063).
                     ftp_transfer_failed = False
-                    # Override the stale subtask_name so the fallback archive's
-                    # print_name reflects the correct plate. Prefer the swapped
-                    # name when we have one; otherwise let filename win.
-                    if corrected_subtask:
-                        subtask_name = corrected_subtask
-                    else:
-                        subtask_name = ""
+                    # Disown the name for *lookups*: it has just been shown to
+                    # fetch another plate's 3MF, and it keys `_active_prints`
+                    # below, where the cover endpoint's own download of that
+                    # same name would find this archive and fill it in with the
+                    # file we are discarding here.
+                    #
+                    # Keep it for the *title*, which is a separate question.
+                    # ``swap_plate_suffix`` returns None both for a name that
+                    # carries no "- Plate N" / "_plate_N" suffix and for no
+                    # name at all, and those are not the same situation: a name
+                    # without a suffix holds no stale plate number to be wrong
+                    # about. Blanking both uses at once dropped the project
+                    # name too, and the row fell through to the gcode_file path
+                    # titled "plate_1" though the real name was in hand.
+                    # #1204's own premise is consecutive plates *of the same
+                    # model*, so the project part is right either way (#3126).
+                    display_name_after_plate_reject = corrected_subtask or subtask_name or None
+                    subtask_name = corrected_subtask or ""
 
         if not downloaded_filename or not temp_path:
             logger.warning("Could not find 3MF file for print: %s", filename or subtask_name)
@@ -4465,8 +4485,11 @@ async def on_print_start(printer_id: int, data: dict):
                 else:
                     no_3mf_reason = storage.reason
 
-                # Derive print name from subtask_name or filename
-                print_name = subtask_name or filename
+                # Derive print name from subtask_name or filename. The
+                # plate guard's disowned name comes second: it is a real name
+                # for a real print, and only the gcode_file path is left
+                # otherwise -- which titles the row "plate_1" (#3126).
+                print_name = subtask_name or display_name_after_plate_reject or filename
                 if print_name:
                     # Clean up the name (remove extensions, path parts)
                     print_name = print_name.split("/")[-1]
@@ -4512,7 +4535,7 @@ async def on_print_start(printer_id: int, data: dict):
                         # switch on a setting that is already on and would not
                         # have helped (#2780).
                         "no_3mf_reason": no_3mf_reason,
-                        "original_subtask": subtask_name,
+                        "original_subtask": subtask_name or display_name_after_plate_reject or "",
                         "_print_data": data,
                     },
                 )

+ 2 - 2
backend/app/services/print_storage.py

@@ -4,8 +4,8 @@ Bambuddy reads a print's 3MF, cover and timelapse off the printer over implicit
 FTPS on port 990. On every Bambu model that port serves **external storage only**
 -- the SD card or USB stick. It is not a view of the printer's filesystem.
 
-H2-series and P2S firmware default to keeping the sliced file on internal eMMC
-instead, and BambuStudio uploads there over a separate service on port 6000
+H2-series, P2S and X2D firmware default to keeping the sliced file on internal
+eMMC instead, and BambuStudio uploads there over a separate service on port 6000
 (the "BambuTunnelLocal" protocol -- see #2762, which tracks implementing it).
 The dispatch says where it went: the ``project_file`` command carries ``url``,
 which is ``ftp://<name>`` for external storage and ``brtc://emmc/<name>`` for

+ 1 - 1
backend/app/services/printer_diagnostic.py

@@ -601,7 +601,7 @@ async def run_connection_diagnostic(
     ):
         # The toggle is on, a card is in, the printer said the last print's file
         # is on internal storage — and a probe confirmed it really is out of
-        # reach. That is what H2-series and P2S firmware does, and no setting
+        # reach. That is what H2-series, P2S and X2D firmware does, and no setting
         # here changes it (#2762 tracks reading that storage). A pass here would
         # be a lie; a fail would be unresolvable.
         #

+ 253 - 0
backend/tests/unit/test_fallback_name_keeps_project_3126.py

@@ -0,0 +1,253 @@
+"""Rejecting the wrong plate must not cost the archive its name (#3126).
+
+The reporter's X2D was sent a print from Bambu Studio, which filed it on
+internal eMMC (``"url": "brtc://emmc/..."``). FTPS cannot serve that, but the
+bounded probe found a *same-named* file at the card's root -- an earlier slice
+of the same project, plate 4, while the running print was plate 1. #1204's
+guard caught the contradiction and refused the file, which is right: archiving
+plate 4's thumbnail, filament and cost against this print is the swap #2957
+removed.
+
+What it then did with the name was not. The guard asks ``swap_plate_suffix``
+for a corrected name and blanked ``subtask_name`` whenever it came back None --
+but None covers two unrelated cases, and only one of them is a name that could
+mislead. ``防雨防虫_模块化_排气口(50_75_80_100管可用)`` carries no
+``- Plate N`` suffix at all, so it holds no stale plate number to be wrong
+about; blanking it dropped the project name too and the row fell through to the
+gcode_file path, titled ``plate_1``. #1204's own premise is consecutive plates
+*of the same model*, so the project part of a lagging name is right either way.
+
+Fixing that is only half of it, and the other half is why the title lives in its
+own variable. The name is kept for *display*; every lookup still disowns it,
+``_active_prints`` included. Key the row under a name the guard just watched
+fetch the wrong plate and the cover endpoint -- which downloads that very name
+for the running print's thumbnail -- hands the bytes to the recovery path, which
+checks a candidate is a readable 3MF and never which plate it holds. The row
+would be filled in with the file this branch had just deleted.
+
+Pinned here: a name without a plate suffix survives the rejection intact as the
+title, a name with a stale one still gets its number corrected, and the rejected
+name keys nothing.
+"""
+
+from unittest.mock import AsyncMock, MagicMock, patch
+
+import pytest
+
+from backend.app.main import (
+    _active_prints,
+    _expected_print_creators,
+    _expected_print_registered_at,
+    _expected_prints,
+    _print_ams_mappings,
+    _timelapse_baselines,
+)
+
+pytestmark = pytest.mark.unit
+
+DISPATCH = "/data/Metadata/plate_1.gcode"
+# The reporter's own subtask_name. Non-ASCII and parenthesised, with no plate
+# suffix anywhere in it -- exactly the shape that used to be thrown away.
+PROJECT = "防雨防虫_模块化_排气口(50_75_80_100管可用)"
+
+
+@pytest.fixture(autouse=True)
+def _clear_dicts():
+    dicts = (
+        _expected_prints,
+        _expected_print_registered_at,
+        _expected_print_creators,
+        _print_ams_mappings,
+        _active_prints,
+        _timelapse_baselines,
+    )
+    for d in dicts:
+        d.clear()
+    yield
+    for d in dicts:
+        d.clear()
+
+
+def _printer():
+    printer = MagicMock()
+    printer.id = 1
+    printer.auto_archive = True
+    printer.external_camera_enabled = False
+    printer.external_camera_url = None
+    # Every unset MagicMock attribute is truthy, and leaving this one implicit
+    # runs the plate-detection camera grab against a printer that is not there.
+    printer.plate_detection_enabled = False
+    printer.name = "X2D"
+    printer.model = "X2D"
+    printer.ip_address = "172.25.12.149"
+    printer.access_code = "12345678"
+    return printer
+
+
+async def _run_print_start(subtask: str):
+    """Drive on_print_start to the wrong-plate rejection and return the row.
+
+    Every download succeeds and every 3MF peeks as plate 4, while the dispatch
+    says plate 1 -- so the initial fetch is rejected and no re-download can
+    satisfy the guard either, which is the reporter's sequence.
+    """
+    printer = _printer()
+
+    def execute_router(stmt, *args, **kwargs):
+        sql = str(stmt).lower()
+        if "from printers" in sql or "from printer " in sql:
+            return MagicMock(
+                scalar_one_or_none=MagicMock(return_value=printer),
+                scalars=MagicMock(return_value=MagicMock(all=MagicMock(return_value=[printer]))),
+            )
+        return MagicMock(
+            scalar_one_or_none=MagicMock(return_value=None),
+            scalars=MagicMock(return_value=MagicMock(all=MagicMock(return_value=[]))),
+        )
+
+    added: list = []
+    session = AsyncMock()
+    session.__aenter__ = AsyncMock(return_value=session)
+    session.__aexit__ = AsyncMock()
+    session.execute = AsyncMock(side_effect=execute_router)
+    session.commit = AsyncMock()
+    session.refresh = AsyncMock()
+    session.add = MagicMock(side_effect=added.append)
+
+    state = MagicMock(
+        current_project_url=f"ftp://{subtask}.gcode.3mf",
+        sdcard=True,
+        sdcard_reported=True,
+    )
+
+    with (
+        patch("backend.app.main.async_session") as session_maker,
+        patch("backend.app.main.notification_service") as notif,
+        patch("backend.app.main.smart_plug_manager") as plug,
+        patch("backend.app.main.ws_manager") as ws,
+        patch("backend.app.main.mqtt_relay") as relay,
+        patch("backend.app.main.printer_manager") as pm,
+        patch("backend.app.main.download_file_async", new=AsyncMock(return_value=True)),
+        patch("backend.app.main.download_file_try_paths_async", new=AsyncMock(return_value=None)),
+        patch("backend.app.main.get_cached_3mf", return_value=None),
+        patch("backend.app.main.cache_3mf_download"),
+        # Plate 4 on the card, plate 1 on the printer -- the mismatch itself.
+        patch("backend.app.main.peek_plate_index_in_3mf", return_value=4),
+        # Imported inside the function, so patching it anywhere else lets the
+        # directory walk open real sockets and the test hangs on connect.
+        patch("backend.app.services.bambu_ftp.list_files_async", new=AsyncMock(return_value=[])),
+        patch("backend.app.main.ftps_handshake_blocked", return_value=False),
+        patch("backend.app.main.get_ftp_retry_settings", new=AsyncMock(return_value=(False, 3, 2.0, 30))),
+        patch("backend.app.main._record_energy_start", new_callable=AsyncMock),
+        patch("backend.app.main._send_print_start_notification", new_callable=AsyncMock),
+        patch("backend.app.main._maybe_start_layer_timelapse"),
+        patch("backend.app.main._capture_timelapse_baseline_at_start", new_callable=AsyncMock),
+        # Real, it would spawn a task that outlives the test by a minute.
+        patch("backend.app.main._schedule_fallback_3mf_retry", new=MagicMock()),
+    ):
+        session_maker.return_value = session
+        notif.on_print_start = AsyncMock()
+        plug.on_print_start = AsyncMock()
+        ws.send_print_start = AsyncMock()
+        ws.send_archive_updated = AsyncMock()
+        # Awaited between creating the fallback row and the rest of the
+        # handler: a plain MagicMock raises, and the handler swallows it.
+        ws.send_archive_created = AsyncMock()
+        relay.on_print_start = AsyncMock()
+        pm.get_status = MagicMock(return_value=state)
+        pm.get_printer = MagicMock(return_value=MagicMock(serial_number="TEST3126"))
+
+        from backend.app.main import on_print_start
+
+        await on_print_start(1, {"filename": DISPATCH, "subtask_name": subtask})
+
+    # Snapshot before the autouse fixture clears it in teardown.
+    keys = {name for (_pid, name) in _active_prints}
+    for row in added:
+        extra = getattr(row, "extra_data", None)
+        if isinstance(extra, dict) and extra.get("no_3mf_available"):
+            return row, keys
+    return None, keys
+
+
+class TestANameWithNoPlateSuffixSurvives:
+    @pytest.mark.asyncio
+    async def test_the_reported_case_keeps_the_project_name(self):
+        """The regression. This row used to be titled ``plate_1``."""
+        row, _keys = await _run_print_start(PROJECT)
+
+        assert row is not None
+        assert row.print_name == PROJECT
+
+    @pytest.mark.asyncio
+    async def test_the_original_subtask_is_still_recorded(self):
+        """Nothing reads this field today -- it is there for support, and a
+        row that records the dispatch path under both its name and its
+        subtask tells whoever reads the bundle nothing about the print."""
+        row, _keys = await _run_print_start(PROJECT)
+
+        assert row.extra_data["original_subtask"] == PROJECT
+
+    @pytest.mark.asyncio
+    async def test_an_ascii_name_too(self):
+        """Nothing here is about the encoding -- any single-plate project name
+        reaches the same branch."""
+        row, _keys = await _run_print_start("Fan_Shroud")
+
+        assert row.print_name == "Fan_Shroud"
+
+
+class TestAStalePlateSuffixIsStillCorrected:
+    """#1204's actual fix, which the change above must not undo."""
+
+    @pytest.mark.asyncio
+    async def test_the_spaced_form_gets_the_running_plate(self):
+        row, _keys = await _run_print_start("Fan_Shroud - Plate 4")
+
+        assert row.print_name == "Fan_Shroud - Plate 1"
+
+    @pytest.mark.asyncio
+    async def test_the_underscored_form_too(self):
+        row, _keys = await _run_print_start("Fan_Shroud_plate_4")
+
+        assert row.print_name == "Fan_Shroud_plate_1"
+
+
+class TestTheDisownedNameStillFindsNoFiles:
+    """The other half, and the reason the name is kept in its own variable.
+
+    A name the guard just watched fetch another plate's 3MF must not key
+    ``_active_prints``. The cover endpoint downloads that same name for the
+    running print's thumbnail and offers the bytes to
+    ``try_recover_fallback_archive``, which matches on those keys and hands
+    whatever it gets to ``_recover_fallback_archive`` -- and that checks a
+    candidate is a readable 3MF, never which plate it holds. Key the row under
+    the rejected name and the cover endpoint fills it in with the exact file
+    this branch just deleted, which is #2957's swap coming back in through a
+    different door.
+    """
+
+    @pytest.mark.asyncio
+    async def test_the_rejected_name_is_not_registered(self):
+        row, keys = await _run_print_start(PROJECT)
+
+        assert row.print_name == PROJECT, "the title is the whole point of the fix"
+        assert PROJECT not in keys
+        assert f"{PROJECT}.3mf" not in keys
+
+    @pytest.mark.asyncio
+    async def test_the_dispatch_path_still_is(self):
+        """Disowning the subtask name must not leave the archive unfindable at
+        print completion -- the gcode_file key is what matches it there."""
+        _row, keys = await _run_print_start(PROJECT)
+
+        assert DISPATCH in keys
+
+    @pytest.mark.asyncio
+    async def test_a_corrected_name_is_registered(self):
+        """#1204's case is different: the swapped name points at the plate that
+        really is running, so a file found under it is the right file."""
+        _row, keys = await _run_print_start("Fan_Shroud - Plate 4")
+
+        assert "Fan_Shroud - Plate 1" in keys
+        assert "Fan_Shroud - Plate 4" not in keys

+ 2 - 2
frontend/src/i18n/locales/de.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: 'Installationsschritt 4 anzeigen',
       docsLinkInternalStorage: 'Warum das passiert',
       titleInternalStorage: 'Einige kürzliche Drucke blieben im internen Speicher des Druckers',
-      bodyInternalStorage: 'Bambu Studio hat die geslicte Datei im internen Speicher des Druckers statt auf der Karte abgelegt, daher gab es für Bambuddy nichts über FTP zu lesen. Bei der H2-Serie und dem P2S macht die Schaltfläche "Drucken" das immer — nur "Senden" bietet eine Auswahl, und auch die steht standardmäßig auf "Cache". Diese Drucke werden weiterhin mit Namen und Zeiten archiviert, nur ohne Vorschaubild und Slicer-Metadaten. Für vollständige Archive den Druck aus Bambuddy starten oder in OrcaSlicer slicen — oder in Bambu Studio "Senden" mit "Extern" verwenden und den Druck danach starten. Alle setzen eine Karte oder einen Stick im Drucker voraus.',
+      bodyInternalStorage: 'Bambu Studio hat die geslicte Datei im internen Speicher des Druckers statt auf der Karte abgelegt, daher gab es für Bambuddy nichts über FTP zu lesen. Bei der H2-Serie, dem P2S und dem X2D macht die Schaltfläche "Drucken" das immer — nur "Senden" bietet eine Auswahl, und auch die steht standardmäßig auf "Cache". Diese Drucke werden weiterhin mit Namen und Zeiten archiviert, nur ohne Vorschaubild und Slicer-Metadaten. Für vollständige Archive den Druck aus Bambuddy starten oder in OrcaSlicer slicen — oder in Bambu Studio "Senden" mit "Extern" verwenden und den Druck danach starten. Alle setzen eine Karte oder einen Stick im Drucker voraus.',
       titleNoExternalStorage: 'Einige kürzliche Drucke konnten nicht archiviert werden — kein Speicher im Drucker',
       bodyNoExternalStorage: 'Der Drucker meldet weder Karte noch Stick im Steckplatz, daher hatte die geslicte Datei keinen Ablageort und Bambuddy nichts zu lesen. Legen Sie einen ein, dann wird der nächste Druck vollständig archiviert.',
       titleInternalHistory: 'Einige kürzliche Drucke wurden aus einer Datei gestartet, die bereits auf dem Drucker lag',
@@ -6980,7 +6980,7 @@ export default {
         skip: 'Nicht geprüft — eine aktive MQTT-Verbindung ist erforderlich. Bei älteren Slicern, in denen diese Einstellung nur im Slicer existiert, meldet sie der Drucker nicht — diese Prüfung besteht auch dann, wenn die Option deaktiviert ist. Prüfen Sie Installationsschritt 4 in diesem Fall manuell.',
         skip_unsupported_model: 'Dieses Modell hat einen SD-Slot, aber keine Möglichkeit, die Option zu aktivieren — die aktuelle P1-Firmware zeigt den Schalter in Bambu Studio nicht an und der Drucker hat kein Display. Hier gibt es nichts zu beheben; archivierten Drucken fehlen möglicherweise Vorschaubilder und Slicer-Metadaten, bis Bambu Lab dies per Firmware unterstützt.',
         fail_no_media: 'Die Option ist aktiviert, aber der Drucker meldet weder Karte noch Stick im Steckplatz, daher können gesendete Dateien nirgends abgelegt werden. Legen Sie einen ein und drucken Sie erneut — bis dahin fehlen jedem archivierten Druck Vorschaubild und Slicer-Metadaten.',
-        warn_internal_storage: 'Die Option ist aktiviert und ein Speicher ist vorhanden, aber der letzte Druck landete dennoch im internen Speicher des Druckers, den Bambuddy nicht lesen kann. Bei der H2-Serie und dem P2S sendet die Schaltfläche "Drucken" in Bambu Studio unabhängig von dieser Option immer dorthin. Drucke werden mit Namen und Zeiten archiviert, aber ohne Vorschaubild und Slicer-Metadaten. Für vollständige Archive den Druck aus Bambuddy starten oder in OrcaSlicer slicen — oder in Bambu Studio "Senden" mit "Extern" verwenden und den Druck danach starten.',
+        warn_internal_storage: 'Die Option ist aktiviert und ein Speicher ist vorhanden, aber der letzte Druck landete dennoch im internen Speicher des Druckers, den Bambuddy nicht lesen kann. Bei der H2-Serie, dem P2S und dem X2D sendet die Schaltfläche "Drucken" in Bambu Studio unabhängig von dieser Option immer dorthin. Drucke werden mit Namen und Zeiten archiviert, aber ohne Vorschaubild und Slicer-Metadaten. Für vollständige Archive den Druck aus Bambuddy starten oder in OrcaSlicer slicen — oder in Bambu Studio "Senden" mit "Extern" verwenden und den Druck danach starten.',
         warn_internal_history: 'Die Option ist aktiv und Speicher vorhanden, aber der letzte Druck lief aus einer Datei, die bereits auf dem Drucker lag — ein erneuter Druck über sein Display, ein Start aus Handy oder eine früher gesendete Datei. Diese Bibliothek liegt im internen Speicher, den Bambuddy nicht lesen kann, und keine Einstellung ändert das, denn für diesen Druck wurde nichts gesendet. Er wird weiterhin mit Namen und Zeiten archiviert, nur ohne Vorschaubild und Slicer-Metadaten. Für vollständige Archive Drucke aus Bambuddy starten oder aus dem Slicer senden.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/en.ts

@@ -909,7 +909,7 @@ export default {
       dismissLabel: 'Dismiss this notice',
       docsLinkInternalStorage: 'Why this happens',
       titleInternalStorage: 'Some recent prints stayed on the printer\'s internal storage',
-      bodyInternalStorage: 'Bambu Studio put the sliced file on the printer\'s internal storage instead of the card, so there was nothing for Bambuddy to read over FTP. On H2-series and P2S its Print button always does that — only Send offers a choice, and that defaults to Cache too. Those prints are still archived with their name and timing, just without a thumbnail or slicer metadata. For complete archives, start the print from Bambuddy, or slice in OrcaSlicer — or in Bambu Studio use Send with External selected and start the print afterwards. All of them need a card or stick in the printer.',
+      bodyInternalStorage: 'Bambu Studio put the sliced file on the printer\'s internal storage instead of the card, so there was nothing for Bambuddy to read over FTP. On H2-series, P2S and X2D its Print button always does that — only Send offers a choice, and that defaults to Cache too. Those prints are still archived with their name and timing, just without a thumbnail or slicer metadata. For complete archives, start the print from Bambuddy, or slice in OrcaSlicer — or in Bambu Studio use Send with External selected and start the print afterwards. All of them need a card or stick in the printer.',
       titleNoExternalStorage: 'Some recent prints couldn\'t be archived — no storage in the printer',
       bodyNoExternalStorage: 'The printer reports no card or stick in its slot, so the sliced file had nowhere to land and Bambuddy had nothing to read. Insert one and the next print will archive in full.',
       titleInternalHistory: 'Some recent prints were started from a file already on the printer',
@@ -7031,7 +7031,7 @@ export default {
         skip: 'Not checked — needs a live MQTT connection. On older slicers where this setting lives only in the slicer the printer never reports it, so this check will pass even when the option is off — verify install step 4 manually.',
         skip_unsupported_model: 'This model has an SD slot but no way to turn the option on — current P1-series firmware doesn\'t expose the toggle in Bambu Studio and the printer has no screen. Nothing to fix here; archived prints may lack thumbnails and slicer metadata until Bambu Lab adds firmware support.',
         fail_no_media: 'The option is on, but the printer reports no card or stick in its slot, so there is nowhere for sent files to go. Insert one and print again — until then every archived print will be missing its thumbnail and slicer metadata.',
-        warn_internal_storage: 'The option is on and storage is present, but the last print still went to the printer\'s internal storage, which Bambuddy cannot read. On H2-series and P2S, Bambu Studio\'s Print button always sends there whatever this option is set to. Prints archive with their name and timing, but without a thumbnail or slicer metadata. For complete archives, start prints from Bambuddy or slice in OrcaSlicer — or in Bambu Studio use Send with External selected, then start the print.',
+        warn_internal_storage: 'The option is on and storage is present, but the last print still went to the printer\'s internal storage, which Bambuddy cannot read. On H2-series, P2S and X2D, Bambu Studio\'s Print button always sends there whatever this option is set to. Prints archive with their name and timing, but without a thumbnail or slicer metadata. For complete archives, start prints from Bambuddy or slice in OrcaSlicer — or in Bambu Studio use Send with External selected, then start the print.',
         warn_internal_history: 'The option is on and storage is present, but the last print ran from a file that was already on the printer — a re-print from its screen, a start from Handy, or a file sent earlier. That library sits on internal storage Bambuddy cannot read, and no setting changes it, because nothing was sent for that print. It still archives with its name and timing, but without a thumbnail or slicer metadata. For complete archives, start prints from Bambuddy or send them from the slicer.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/es.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: 'Ver paso 4 de instalación',
       docsLinkInternalStorage: 'Por qué ocurre',
       titleInternalStorage: 'Algunas impresiones recientes se quedaron en el almacenamiento interno de la impresora',
-      bodyInternalStorage: 'Bambu Studio guardó el archivo laminado en el almacenamiento interno de la impresora en lugar de la tarjeta, así que Bambuddy no tenía nada que leer por FTP. En la serie H2 y la P2S su botón «Imprimir» siempre lo hace: solo «Enviar» ofrece elección, y también viene con «Caché» por defecto. Esas impresiones se siguen archivando con su nombre y sus tiempos, solo que sin miniatura ni metadatos del laminador. Para archivos completos, inicia la impresión desde Bambuddy o lamina en OrcaSlicer, o bien en Bambu Studio usa «Enviar» con «Externo» y luego inicia la impresión. Todas requieren una tarjeta o memoria en la impresora.',
+      bodyInternalStorage: 'Bambu Studio guardó el archivo laminado en el almacenamiento interno de la impresora en lugar de la tarjeta, así que Bambuddy no tenía nada que leer por FTP. En la serie H2, la P2S y la X2D su botón «Imprimir» siempre lo hace: solo «Enviar» ofrece elección, y también viene con «Caché» por defecto. Esas impresiones se siguen archivando con su nombre y sus tiempos, solo que sin miniatura ni metadatos del laminador. Para archivos completos, inicia la impresión desde Bambuddy o lamina en OrcaSlicer, o bien en Bambu Studio usa «Enviar» con «Externo» y luego inicia la impresión. Todas requieren una tarjeta o memoria en la impresora.',
       titleNoExternalStorage: 'Algunas impresiones recientes no se pudieron archivar — no hay almacenamiento en la impresora',
       bodyNoExternalStorage: 'La impresora no detecta ninguna tarjeta ni memoria en su ranura, así que el archivo laminado no tenía dónde aterrizar y Bambuddy nada que leer. Inserte una y la próxima impresión se archivará por completo.',
       titleInternalHistory: 'Algunas impresiones recientes se iniciaron desde un archivo que ya estaba en la impresora',
@@ -6988,7 +6988,7 @@ export default {
         skip: 'No comprobado — se necesita una conexión MQTT activa. En slicers más antiguos donde este ajuste solo existe en el slicer, la impresora no lo reporta, así que esta comprobación pasa aunque la opción esté desactivada — verifique el paso 4 de la instalación manualmente.',
         skip_unsupported_model: 'Este modelo tiene ranura SD pero no hay forma de activar la opción — el firmware actual de la serie P1 no muestra el interruptor en Bambu Studio y la impresora no tiene pantalla. Aquí no hay nada que arreglar; a las impresiones archivadas pueden faltarles miniaturas y metadatos del slicer hasta que Bambu Lab lo admita por firmware.',
         fail_no_media: 'La opción está activada, pero la impresora no detecta ninguna tarjeta ni memoria en su ranura, así que los archivos enviados no tienen dónde ir. Inserte una e imprima de nuevo — hasta entonces, cada impresión archivada carecerá de miniatura y de metadatos del laminador.',
-        warn_internal_storage: 'La opción está activada y hay almacenamiento presente, pero la última impresión aun así fue al almacenamiento interno de la impresora, que Bambuddy no puede leer. En la serie H2 y la P2S, el botón «Imprimir» de Bambu Studio siempre envía ahí, sea cual sea este ajuste. Las impresiones se archivan con su nombre y sus tiempos, pero sin miniatura ni metadatos del laminador. Para archivos completos, inicia las impresiones desde Bambuddy o lamina en OrcaSlicer, o bien en Bambu Studio usa «Enviar» con «Externo» y luego inicia la impresión.',
+        warn_internal_storage: 'La opción está activada y hay almacenamiento presente, pero la última impresión aun así fue al almacenamiento interno de la impresora, que Bambuddy no puede leer. En la serie H2, la P2S y la X2D, el botón «Imprimir» de Bambu Studio siempre envía ahí, sea cual sea este ajuste. Las impresiones se archivan con su nombre y sus tiempos, pero sin miniatura ni metadatos del laminador. Para archivos completos, inicia las impresiones desde Bambuddy o lamina en OrcaSlicer, o bien en Bambu Studio usa «Enviar» con «Externo» y luego inicia la impresión.',
         warn_internal_history: 'La opción está activada y hay almacenamiento, pero la última impresión salió de un archivo que ya estaba en la impresora: una reimpresión desde su pantalla, un inicio desde Handy o un archivo enviado antes. Esa biblioteca reside en el almacenamiento interno, que Bambuddy no puede leer, y ninguna opción lo cambia, porque para esa impresión no se envió nada. Se sigue archivando con su nombre y sus tiempos, pero sin miniatura ni metadatos del laminador. Para archivos completos, inicia las impresiones desde Bambuddy o envíalas desde el laminador.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/fr.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: 'Voir l\'étape 4 de l\'installation',
       docsLinkInternalStorage: 'Pourquoi cela arrive',
       titleInternalStorage: 'Certaines impressions récentes sont restées dans le stockage interne de l\'imprimante',
-      bodyInternalStorage: 'Bambu Studio a placé le fichier tranché dans le stockage interne de l\'imprimante au lieu de la carte, Bambuddy n\'avait donc rien à lire en FTP. Sur les séries H2 et P2S, son bouton « Imprimer » le fait toujours : seul « Envoyer » propose un choix, et il est lui aussi réglé sur « Cache » par défaut. Ces impressions restent archivées avec leur nom et leurs durées, simplement sans miniature ni métadonnées slicer. Pour des archives complètes, lancez l\'impression depuis Bambuddy ou tranchez dans OrcaSlicer, ou bien dans Bambu Studio utilisez « Envoyer » avec « Externe » puis lancez l\'impression. Toutes nécessitent une carte ou une clé dans l\'imprimante.',
+      bodyInternalStorage: 'Bambu Studio a placé le fichier tranché dans le stockage interne de l\'imprimante au lieu de la carte, Bambuddy n\'avait donc rien à lire en FTP. Sur les séries H2, P2S et X2D, son bouton « Imprimer » le fait toujours : seul « Envoyer » propose un choix, et il est lui aussi réglé sur « Cache » par défaut. Ces impressions restent archivées avec leur nom et leurs durées, simplement sans miniature ni métadonnées slicer. Pour des archives complètes, lancez l\'impression depuis Bambuddy ou tranchez dans OrcaSlicer, ou bien dans Bambu Studio utilisez « Envoyer » avec « Externe » puis lancez l\'impression. Toutes nécessitent une carte ou une clé dans l\'imprimante.',
       titleNoExternalStorage: 'Certaines impressions récentes n\'ont pas pu être archivées — aucun stockage dans l\'imprimante',
       bodyNoExternalStorage: 'L\'imprimante ne signale ni carte ni clé dans son emplacement, le fichier tranché n\'avait donc nulle part où atterrir et Bambuddy rien à lire. Insérez-en une et la prochaine impression sera archivée complètement.',
       titleInternalHistory: 'Certaines impressions récentes ont été lancées depuis un fichier déjà présent sur l\'imprimante',
@@ -6970,7 +6970,7 @@ export default {
         skip: 'Non vérifié — une connexion MQTT active est requise. Sur les slicers plus anciens où ce paramètre n\'existe que dans le slicer, l\'imprimante ne le signale pas, donc cette vérification passe même si l\'option est désactivée — vérifiez l\'étape 4 de l\'installation manuellement.',
         skip_unsupported_model: 'Ce modèle a un emplacement SD mais aucun moyen d\'activer l\'option — le firmware actuel de la série P1 n\'affiche pas le bouton dans Bambu Studio et l\'imprimante n\'a pas d\'écran. Il n\'y a rien à corriger ici ; les impressions archivées peuvent manquer de miniatures et de métadonnées du slicer jusqu\'à ce que Bambu Lab l\'ajoute par firmware.',
         fail_no_media: 'L\'option est activée, mais l\'imprimante ne signale ni carte ni clé dans son emplacement : les fichiers envoyés n\'ont nulle part où aller. Insérez-en une et relancez une impression — d\'ici là, chaque impression archivée sera dépourvue de miniature et de métadonnées slicer.',
-        warn_internal_storage: 'L\'option est activée et un stockage est présent, mais la dernière impression est tout de même allée dans le stockage interne de l\'imprimante, que Bambuddy ne peut pas lire. Sur les séries H2 et P2S, le bouton « Imprimer » de Bambu Studio y envoie toujours, quel que soit ce réglage. Les impressions sont archivées avec leur nom et leurs durées, mais sans miniature ni métadonnées slicer. Pour des archives complètes, lancez les impressions depuis Bambuddy ou tranchez dans OrcaSlicer, ou bien dans Bambu Studio utilisez « Envoyer » avec « Externe » puis lancez l\'impression.',
+        warn_internal_storage: 'L\'option est activée et un stockage est présent, mais la dernière impression est tout de même allée dans le stockage interne de l\'imprimante, que Bambuddy ne peut pas lire. Sur les séries H2, P2S et X2D, le bouton « Imprimer » de Bambu Studio y envoie toujours, quel que soit ce réglage. Les impressions sont archivées avec leur nom et leurs durées, mais sans miniature ni métadonnées slicer. Pour des archives complètes, lancez les impressions depuis Bambuddy ou tranchez dans OrcaSlicer, ou bien dans Bambu Studio utilisez « Envoyer » avec « Externe » puis lancez l\'impression.',
         warn_internal_history: 'L\'option est activée et un stockage est présent, mais la dernière impression est partie d\'un fichier déjà présent sur l\'imprimante : une réimpression depuis son écran, un lancement depuis Handy ou un fichier envoyé plus tôt. Cette bibliothèque réside dans le stockage interne, que Bambuddy ne peut pas lire, et aucun réglage n\'y change rien, puisque rien n\'a été envoyé pour cette impression. Elle reste archivée avec son nom et ses durées, mais sans miniature ni métadonnées slicer. Pour des archives complètes, lancez les impressions depuis Bambuddy ou envoyez-les depuis le trancheur.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/it.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: 'Vedi passo 4 dell\'installazione',
       docsLinkInternalStorage: 'Perché succede',
       titleInternalStorage: 'Alcune stampe recenti sono rimaste nella memoria interna della stampante',
-      bodyInternalStorage: 'Bambu Studio ha messo il file elaborato nella memoria interna della stampante anziché sulla scheda, quindi Bambuddy non aveva nulla da leggere via FTP. Sulla serie H2 e sulla P2S il pulsante «Stampa» lo fa sempre: solo «Invia» offre una scelta, e anche quella è impostata su «Cache». Quelle stampe restano archiviate con nome e tempi, solo senza miniatura né metadati dello slicer. Per archivi completi, avvia la stampa da Bambuddy oppure elabora in OrcaSlicer, oppure in Bambu Studio usa «Invia» con «Esterna» e avvia la stampa dopo. Tutte richiedono una scheda o una chiavetta nella stampante.',
+      bodyInternalStorage: 'Bambu Studio ha messo il file elaborato nella memoria interna della stampante anziché sulla scheda, quindi Bambuddy non aveva nulla da leggere via FTP. Sulla serie H2, sulla P2S e sulla X2D il pulsante «Stampa» lo fa sempre: solo «Invia» offre una scelta, e anche quella è impostata su «Cache». Quelle stampe restano archiviate con nome e tempi, solo senza miniatura né metadati dello slicer. Per archivi completi, avvia la stampa da Bambuddy oppure elabora in OrcaSlicer, oppure in Bambu Studio usa «Invia» con «Esterna» e avvia la stampa dopo. Tutte richiedono una scheda o una chiavetta nella stampante.',
       titleNoExternalStorage: 'Alcune stampe recenti non sono state archiviate — nessuna memoria nella stampante',
       bodyNoExternalStorage: 'La stampante non rileva né scheda né chiavetta nel suo slot, quindi il file elaborato non aveva dove finire e Bambuddy nulla da leggere. Inseriscine una e la prossima stampa verrà archiviata per intero.',
       titleInternalHistory: 'Alcune stampe recenti sono partite da un file già presente sulla stampante',
@@ -6969,7 +6969,7 @@ export default {
         skip: 'Non verificato — è necessaria una connessione MQTT attiva. Negli slicer più vecchi dove questa impostazione esiste solo nello slicer, la stampante non la segnala, quindi questo controllo passa anche se l\'opzione è disattivata — verifica manualmente il passo 4 dell\'installazione.',
         skip_unsupported_model: 'Questo modello ha uno slot SD ma nessun modo per attivare l\'opzione — il firmware attuale della serie P1 non mostra l\'interruttore in Bambu Studio e la stampante non ha uno schermo. Non c\'è nulla da correggere qui; alle stampe archiviate potrebbero mancare miniature e metadati dello slicer finché Bambu Lab non aggiungerà il supporto via firmware.',
         fail_no_media: 'L\'opzione è attiva, ma la stampante non rileva né scheda né chiavetta nel suo slot, quindi i file inviati non hanno dove andare. Inseriscine una e stampa di nuovo — fino ad allora ogni stampa archiviata sarà priva di miniatura e metadati dello slicer.',
-        warn_internal_storage: 'L\'opzione è attiva ed è presente una memoria, ma l\'ultima stampa è comunque finita nella memoria interna della stampante, che Bambuddy non può leggere. Sulla serie H2 e sulla P2S il pulsante «Stampa» di Bambu Studio invia sempre lì, a prescindere da questa opzione. Le stampe vengono archiviate con nome e tempi, ma senza miniatura né metadati dello slicer. Per archivi completi, avvia le stampe da Bambuddy oppure elabora in OrcaSlicer, oppure in Bambu Studio usa «Invia» con «Esterna» e avvia la stampa dopo.',
+        warn_internal_storage: 'L\'opzione è attiva ed è presente una memoria, ma l\'ultima stampa è comunque finita nella memoria interna della stampante, che Bambuddy non può leggere. Sulla serie H2, sulla P2S e sulla X2D il pulsante «Stampa» di Bambu Studio invia sempre lì, a prescindere da questa opzione. Le stampe vengono archiviate con nome e tempi, ma senza miniatura né metadati dello slicer. Per archivi completi, avvia le stampe da Bambuddy oppure elabora in OrcaSlicer, oppure in Bambu Studio usa «Invia» con «Esterna» e avvia la stampa dopo.',
         warn_internal_history: 'L\'opzione è attiva e la memoria è presente, ma l\'ultima stampa è partita da un file già presente sulla stampante: una ristampa dal suo schermo, un avvio da Handy o un file inviato prima. Quella libreria si trova nella memoria interna, che Bambuddy non può leggere, e nessuna impostazione lo cambia, perché per quella stampa non è stato inviato nulla. Resta archiviata con nome e tempi, ma senza miniatura né metadati dello slicer. Per archivi completi, avvia le stampe da Bambuddy o inviale dallo slicer.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/ja.ts

@@ -902,7 +902,7 @@ export default {
       docsLink: 'インストール手順4を参照',
       docsLinkInternalStorage: '原因について',
       titleInternalStorage: '最近の一部の印刷はプリンターの内部ストレージに残りました',
-      bodyInternalStorage: 'Bambu Studio がスライス済みファイルをカードではなくプリンターの内部ストレージに保存したため、Bambuddy が FTP で読み取れるものがありませんでした。H2 シリーズと P2S では「印刷」ボタンは常にそうなり、選択できるのは「送信」だけで、そちらも既定は「キャッシュ」です。これらの印刷は名前と時間付きでアーカイブされますが、サムネイルとスライサーのメタデータはありません。完全なアーカイブを残すには、Bambuddy から印刷を開始するか、OrcaSlicer でスライスしてください。Bambu Studio を使う場合は「送信」で「外部ストレージ」を選び、その後に印刷を開始します。いずれもプリンターにカードまたは USB メモリーが必要です。',
+      bodyInternalStorage: 'Bambu Studio がスライス済みファイルをカードではなくプリンターの内部ストレージに保存したため、Bambuddy が FTP で読み取れるものがありませんでした。H2 シリーズ、P2S、X2D では「印刷」ボタンは常にそうなり、選択できるのは「送信」だけで、そちらも既定は「キャッシュ」です。これらの印刷は名前と時間付きでアーカイブされますが、サムネイルとスライサーのメタデータはありません。完全なアーカイブを残すには、Bambuddy から印刷を開始するか、OrcaSlicer でスライスしてください。Bambu Studio を使う場合は「送信」で「外部ストレージ」を選び、その後に印刷を開始します。いずれもプリンターにカードまたは USB メモリーが必要です。',
       titleNoExternalStorage: '最近の一部の印刷をアーカイブできませんでした — プリンターにストレージがありません',
       bodyNoExternalStorage: 'プリンターのスロットにカードもUSBメモリも検出されないため、スライス済みファイルの保存先がなく、Bambuddyが読み取るものもありませんでした。挿入すれば次の印刷は完全にアーカイブされます。',
       titleInternalHistory: '最近の一部の印刷は、すでにプリンター内にあるファイルから開始されました',
@@ -6981,7 +6981,7 @@ export default {
         skip: '未確認 — アクティブなMQTT接続が必要です。古いスライサーでこの設定がスライサー側のみに存在する場合、プリンターはそれを報告しないため、オプションが無効でもこのチェックは通過します — インストール手順4を手動で確認してください。',
         skip_unsupported_model: 'このモデルにはSDスロットがありますが、オプションを有効にする方法がありません — 現在のP1シリーズのファームウェアはBambu Studioにトグルを表示せず、プリンターに画面もありません。ここで修正すべきことはありません。Bambu Labがファームウェアで対応するまで、アーカイブされた印刷にはサムネイルやスライサーのメタデータが欠ける場合があります。',
         fail_no_media: 'オプションは有効ですが、プリンターのスロットにカードもUSBメモリも検出されないため、送信ファイルの保存先がありません。挿入して再度印刷してください。それまでアーカイブされる印刷にはサムネイルとスライサーメタデータがありません。',
-        warn_internal_storage: 'オプションは有効でストレージも装着されていますが、直近の印刷は Bambuddy が読み取れないプリンターの内部ストレージに保存されました。H2 シリーズと P2S では、この設定に関係なく Bambu Studio の「印刷」ボタンは常にそちらへ送信します。印刷は名前と時間付きでアーカイブされますが、サムネイルとスライサーのメタデータはありません。完全なアーカイブを残すには、Bambuddy から印刷を開始するか、OrcaSlicer でスライスするか、Bambu Studio で「送信」から「外部ストレージ」を選んだあとに印刷を開始してください。',
+        warn_internal_storage: 'オプションは有効でストレージも装着されていますが、直近の印刷は Bambuddy が読み取れないプリンターの内部ストレージに保存されました。H2 シリーズ、P2S、X2D では、この設定に関係なく Bambu Studio の「印刷」ボタンは常にそちらへ送信します。印刷は名前と時間付きでアーカイブされますが、サムネイルとスライサーのメタデータはありません。完全なアーカイブを残すには、Bambuddy から印刷を開始するか、OrcaSlicer でスライスするか、Bambu Studio で「送信」から「外部ストレージ」を選んだあとに印刷を開始してください。',
         warn_internal_history: 'オプションは有効でストレージもありますが、直近の印刷はすでにプリンター内にあったファイルから実行されました — 画面からの再印刷、Handy からの開始、または以前に送信したファイルです。そのライブラリは Bambuddy が読めない内部ストレージにあり、この印刷では何も送信されていないため、どの設定を変えても解決しません。名前と時間付きでアーカイブはされますが、サムネイルとスライサーのメタデータはありません。完全なアーカイブにするには、Bambuddy から印刷を開始するか、スライサーから送信してください。',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/ko.ts

@@ -859,7 +859,7 @@ export default {
       docsLink: '설치 단계 4 보기',
       docsLinkInternalStorage: '왜 이런 일이 생기나요',
       titleInternalStorage: '최근 일부 출력물이 프린터 내부 저장소에 남았습니다',
-      bodyInternalStorage: '슬라이싱된 파일을 Bambu Studio가 카드가 아니라 프린터 내부 저장소에 저장해서 Bambuddy가 FTP로 읽을 것이 없었습니다. H2 시리즈와 P2S에서는 «인쇄» 버튼이 항상 그렇게 동작하며, 선택할 수 있는 것은 «보내기»뿐인데 그것도 기본값이 «캐시»입니다. 해당 출력물은 이름과 시간과 함께 계속 보관되지만 썸네일과 슬라이서 메타데이터는 없습니다. 완전한 기록을 남기려면 Bambuddy에서 출력을 시작하거나 OrcaSlicer로 슬라이싱하세요. Bambu Studio를 쓴다면 «보내기»에서 «외부 저장소»를 고른 뒤 출력을 시작하면 됩니다. 모두 프린터에 카드나 USB 메모리가 필요합니다.',
+      bodyInternalStorage: '슬라이싱된 파일을 Bambu Studio가 카드가 아니라 프린터 내부 저장소에 저장해서 Bambuddy가 FTP로 읽을 것이 없었습니다. H2 시리즈, P2S, X2D에서는 «인쇄» 버튼이 항상 그렇게 동작하며, 선택할 수 있는 것은 «보내기»뿐인데 그것도 기본값이 «캐시»입니다. 해당 출력물은 이름과 시간과 함께 계속 보관되지만 썸네일과 슬라이서 메타데이터는 없습니다. 완전한 기록을 남기려면 Bambuddy에서 출력을 시작하거나 OrcaSlicer로 슬라이싱하세요. Bambu Studio를 쓴다면 «보내기»에서 «외부 저장소»를 고른 뒤 출력을 시작하면 됩니다. 모두 프린터에 카드나 USB 메모리가 필요합니다.',
       titleNoExternalStorage: '최근 일부 출력물을 보관하지 못했습니다 — 프린터에 저장소가 없습니다',
       bodyNoExternalStorage: '프린터 슬롯에 카드도 USB도 감지되지 않아 슬라이싱된 파일이 저장될 곳이 없었고 Bambuddy가 읽을 것도 없었습니다. 하나 넣으면 다음 출력물은 온전히 보관됩니다.',
       titleInternalHistory: '최근 일부 출력물은 이미 프린터에 있던 파일에서 시작되었습니다',
@@ -7081,7 +7081,7 @@ export default {
         skip: '확인되지 않음 — 활성 MQTT 연결이 필요합니다. 이 설정이 슬라이서에만 존재하는 이전 슬라이서에서는 프린터가 보고하지 않으므로, 옵션이 꺼져 있어도 이 검사는 통과합니다 — 설치 단계 4를 수동으로 확인하세요.',
         skip_unsupported_model: '이 모델에는 SD 슬롯이 있지만 옵션을 켤 방법이 없습니다 — 현재 P1 시리즈 펌웨어는 Bambu Studio에 토글을 표시하지 않으며 프린터에 화면도 없습니다. 여기서 고칠 것은 없습니다. Bambu Lab이 펌웨어로 지원할 때까지 보관된 출력물에는 썸네일과 슬라이서 메타데이터가 없을 수 있습니다.',
         fail_no_media: '옵션은 켜져 있지만 프린터 슬롯에 카드도 USB도 감지되지 않아 보낸 파일이 갈 곳이 없습니다. 하나 넣고 다시 출력하세요. 그전까지는 보관되는 모든 출력물에 썸네일과 슬라이서 메타데이터가 없습니다.',
-        warn_internal_storage: '옵션이 켜져 있고 저장소도 있지만 마지막 출력물은 Bambuddy가 읽을 수 없는 프린터 내부 저장소에 저장되었습니다. H2 시리즈와 P2S에서는 이 설정과 관계없이 Bambu Studio의 «인쇄» 버튼이 항상 그쪽으로 보냅니다. 출력물은 이름과 시간과 함께 보관되지만 썸네일과 슬라이서 메타데이터는 없습니다. 완전한 기록을 남기려면 Bambuddy에서 출력을 시작하거나, OrcaSlicer로 슬라이싱하거나, Bambu Studio에서 «보내기»로 «외부 저장소»를 고른 뒤 출력을 시작하세요.',
+        warn_internal_storage: '옵션이 켜져 있고 저장소도 있지만 마지막 출력물은 Bambuddy가 읽을 수 없는 프린터 내부 저장소에 저장되었습니다. H2 시리즈, P2S, X2D에서는 이 설정과 관계없이 Bambu Studio의 «인쇄» 버튼이 항상 그쪽으로 보냅니다. 출력물은 이름과 시간과 함께 보관되지만 썸네일과 슬라이서 메타데이터는 없습니다. 완전한 기록을 남기려면 Bambuddy에서 출력을 시작하거나, OrcaSlicer로 슬라이싱하거나, Bambu Studio에서 «보내기»로 «외부 저장소»를 고른 뒤 출력을 시작하세요.',
         warn_internal_history: '옵션은 켜져 있고 저장소도 있지만, 마지막 출력은 이미 프린터에 있던 파일에서 실행되었습니다 — 화면에서의 재출력, Handy에서의 시작, 또는 이전에 보낸 파일입니다. 그 라이브러리는 Bambuddy가 읽을 수 없는 내부 저장소에 있으며, 그 출력에서는 아무것도 전송되지 않았으므로 어떤 설정으로도 바뀌지 않습니다. 이름과 시간과 함께 보관되기는 하지만 썸네일과 슬라이서 메타데이터는 없습니다. 온전한 보관을 원하면 Bambuddy에서 출력을 시작하거나 슬라이서에서 전송하세요.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/nl.ts

@@ -909,7 +909,7 @@ export default {
       dismissLabel: 'Deze melding sluiten',
       docsLinkInternalStorage: 'Waarom dit gebeurt',
       titleInternalStorage: 'Sommige recente afdrukken bleven op de interne opslag van de printer staan',
-      bodyInternalStorage: 'Bambu Studio plaatste het geslicede bestand op de interne opslag van de printer in plaats van op de kaart, waardoor Bambuddy via FTP niets kon uitlezen. Op H2-serie en P2S doet de knop Afdrukken dit altijd — alleen Verzenden biedt een keuze, en ook daar is Cache standaard. Die afdrukken worden nog steeds gearchiveerd met naam en timing, maar zonder miniatuur of slicermetadata. Voor volledige archieven start je de afdruk vanuit Bambuddy, slice je in OrcaSlicer, of gebruik je in Bambu Studio Verzenden met Extern geselecteerd en start je daarna de afdruk. Voor al deze opties is een kaart of USB-stick in de printer nodig.',
+      bodyInternalStorage: 'Bambu Studio plaatste het geslicede bestand op de interne opslag van de printer in plaats van op de kaart, waardoor Bambuddy via FTP niets kon uitlezen. Op H2-serie, P2S en X2D doet de knop Afdrukken dit altijd — alleen Verzenden biedt een keuze, en ook daar is Cache standaard. Die afdrukken worden nog steeds gearchiveerd met naam en timing, maar zonder miniatuur of slicermetadata. Voor volledige archieven start je de afdruk vanuit Bambuddy, slice je in OrcaSlicer, of gebruik je in Bambu Studio Verzenden met Extern geselecteerd en start je daarna de afdruk. Voor al deze opties is een kaart of USB-stick in de printer nodig.',
       titleNoExternalStorage: 'Sommige recente afdrukken konden niet worden gearchiveerd — geen opslag in de printer',
       bodyNoExternalStorage: 'De printer meldt dat er geen kaart of USB-stick in de sleuf zit, waardoor het geslicede bestand nergens kon worden opgeslagen en Bambuddy niets kon uitlezen. Plaats er een en de volgende afdruk wordt volledig gearchiveerd.',
       titleInternalHistory: 'Sommige recente prints zijn gestart vanaf een bestand dat al op de printer stond',
@@ -7031,7 +7031,7 @@ export default {
         skip: 'Niet gecontroleerd — hiervoor is een actieve MQTT-verbinding nodig. Bij oudere slicers, waar deze instelling alleen in de slicer staat, rapporteert de printer hem nooit. Daardoor kan deze controle slagen terwijl de optie uitstaat — controleer installatiestap 4 handmatig.',
         skip_unsupported_model: 'Dit model heeft een SD-slot maar geen manier om de optie in te schakelen — de huidige P1-seriefirmware toont de schakelaar niet in Bambu Studio en de printer heeft geen scherm. Hier is niets te herstellen; gearchiveerde afdrukken kunnen miniaturen en slicermetadata missen totdat Bambu Lab firmwareondersteuning toevoegt.',
         fail_no_media: 'De optie staat aan, maar de printer meldt dat er geen kaart of stick in het slot zit, waardoor verzonden bestanden nergens kunnen worden opgeslagen. Plaats er een en druk opnieuw af — tot die tijd mist elke gearchiveerde afdruk zijn miniatuur en slicermetadata.',
-        warn_internal_storage: 'De optie staat aan en opslag is aanwezig, maar de laatste afdruk ging toch naar de interne opslag van de printer, die Bambuddy niet kan lezen. Bij H2-serie en P2S stuurt de knop Afdrukken van Bambu Studio altijd daarheen, ongeacht deze instelling. Afdrukken worden gearchiveerd met naam en timing, maar zonder miniatuur of slicermetadata. Voor volledige archieven start je afdrukken vanuit Bambuddy of slice je in OrcaSlicer — of gebruik in Bambu Studio Verzenden met Extern geselecteerd en start daarna de afdruk.',
+        warn_internal_storage: 'De optie staat aan en opslag is aanwezig, maar de laatste afdruk ging toch naar de interne opslag van de printer, die Bambuddy niet kan lezen. Bij H2-serie, P2S en X2D stuurt de knop Afdrukken van Bambu Studio altijd daarheen, ongeacht deze instelling. Afdrukken worden gearchiveerd met naam en timing, maar zonder miniatuur of slicermetadata. Voor volledige archieven start je afdrukken vanuit Bambuddy of slice je in OrcaSlicer — of gebruik in Bambu Studio Verzenden met Extern geselecteerd en start daarna de afdruk.',
         warn_internal_history: 'De optie staat aan en er is opslag aanwezig, maar de laatste print liep vanaf een bestand dat al op de printer stond — opnieuw afdrukken via het scherm, starten vanuit Handy, of een eerder verstuurd bestand. Die bibliotheek staat op interne opslag die Bambuddy niet kan lezen, en geen enkele instelling verandert dat, omdat er voor die print niets is verstuurd. Hij wordt nog steeds gearchiveerd met naam en tijden, maar zonder thumbnail of slicer-metadata. Start prints vanuit Bambuddy of verstuur ze vanuit de slicer voor volledige archieven.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/pt-BR.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: 'Ver passo 4 da instalação',
       docsLinkInternalStorage: 'Por que isso acontece',
       titleInternalStorage: 'Algumas impressões recentes ficaram no armazenamento interno da impressora',
-      bodyInternalStorage: 'O Bambu Studio colocou o arquivo fatiado no armazenamento interno da impressora em vez do cartão, então o Bambuddy não tinha nada para ler via FTP. Na série H2 e na P2S o botão «Imprimir» sempre faz isso: só «Enviar» oferece escolha, e ela também vem com «Cache» por padrão. Essas impressões continuam arquivadas com nome e tempos, apenas sem miniatura nem metadados do fatiador. Para arquivos completos, inicie a impressão pelo Bambuddy ou fatie no OrcaSlicer, ou então no Bambu Studio use «Enviar» com «Externo» e inicie a impressão depois. Todos precisam de um cartão ou pendrive na impressora.',
+      bodyInternalStorage: 'O Bambu Studio colocou o arquivo fatiado no armazenamento interno da impressora em vez do cartão, então o Bambuddy não tinha nada para ler via FTP. Na série H2, na P2S e na X2D o botão «Imprimir» sempre faz isso: só «Enviar» oferece escolha, e ela também vem com «Cache» por padrão. Essas impressões continuam arquivadas com nome e tempos, apenas sem miniatura nem metadados do fatiador. Para arquivos completos, inicie a impressão pelo Bambuddy ou fatie no OrcaSlicer, ou então no Bambu Studio use «Enviar» com «Externo» e inicie a impressão depois. Todos precisam de um cartão ou pendrive na impressora.',
       titleNoExternalStorage: 'Algumas impressões recentes não puderam ser arquivadas — sem armazenamento na impressora',
       bodyNoExternalStorage: 'A impressora não detecta cartão nem pendrive no slot, então o arquivo fatiado não tinha onde ficar e o Bambuddy nada para ler. Insira um e a próxima impressão será arquivada por completo.',
       titleInternalHistory: 'Algumas impressões recentes começaram a partir de um arquivo que já estava na impressora',
@@ -6969,7 +6969,7 @@ export default {
         skip: 'Não verificado — é necessária uma conexão MQTT ativa. Em fatiadores mais antigos onde essa configuração existe apenas no fatiador, a impressora não a reporta, então esta verificação passa mesmo com a opção desligada — verifique o passo 4 da instalação manualmente.',
         skip_unsupported_model: 'Este modelo tem slot SD mas nenhuma forma de ativar a opção — o firmware atual da série P1 não mostra o botão no Bambu Studio e a impressora não tem tela. Não há nada a corrigir aqui; as impressões arquivadas podem ficar sem miniaturas e metadados do fatiador até que a Bambu Lab adicione suporte por firmware.',
         fail_no_media: 'A opção está ligada, mas a impressora não detecta cartão nem pendrive no slot, então os arquivos enviados não têm para onde ir. Insira um e imprima novamente — até lá, toda impressão arquivada ficará sem miniatura e sem metadados do fatiador.',
-        warn_internal_storage: 'A opção está ligada e há armazenamento presente, mas a última impressão ainda assim foi para o armazenamento interno da impressora, que o Bambuddy não consegue ler. Na série H2 e na P2S o botão «Imprimir» do Bambu Studio sempre envia para lá, independentemente desta opção. As impressões são arquivadas com nome e tempos, mas sem miniatura nem metadados do fatiador. Para arquivos completos, inicie as impressões pelo Bambuddy ou fatie no OrcaSlicer, ou então no Bambu Studio use «Enviar» com «Externo» e inicie a impressão depois.',
+        warn_internal_storage: 'A opção está ligada e há armazenamento presente, mas a última impressão ainda assim foi para o armazenamento interno da impressora, que o Bambuddy não consegue ler. Na série H2, na P2S e na X2D o botão «Imprimir» do Bambu Studio sempre envia para lá, independentemente desta opção. As impressões são arquivadas com nome e tempos, mas sem miniatura nem metadados do fatiador. Para arquivos completos, inicie as impressões pelo Bambuddy ou fatie no OrcaSlicer, ou então no Bambu Studio use «Enviar» com «Externo» e inicie a impressão depois.',
         warn_internal_history: 'A opção está ligada e há armazenamento, mas a última impressão saiu de um arquivo que já estava na impressora: uma reimpressão pela tela dela, um início pelo Handy ou um arquivo enviado antes. Essa biblioteca fica no armazenamento interno, que o Bambuddy não consegue ler, e nenhuma opção muda isso, porque nada foi enviado para essa impressão. Ela continua arquivada com nome e tempos, mas sem miniatura nem metadados do fatiador. Para arquivos completos, inicie as impressões pelo Bambuddy ou envie-as pelo fatiador.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/ru.ts

@@ -858,7 +858,7 @@ export default {
       docsLink: "См. шаг 4 установки",
       docsLinkInternalStorage: 'Почему так происходит',
       titleInternalStorage: 'Некоторые недавние печати остались во внутренней памяти принтера',
-      bodyInternalStorage: 'Bambu Studio сохранил нарезанный файл во внутренней памяти принтера, а не на карте, поэтому Bambuddy было нечего читать по FTP. На серии H2 и P2S кнопка «Печать» всегда делает так: выбор есть только в «Отправить», и там по умолчанию тоже «Кэш». Эти печати по-прежнему архивируются с именем и временем, только без миниатюры и метаданных слайсера. Чтобы архивы были полными, запускайте печать из Bambuddy или нарезайте в OrcaSlicer, либо в Bambu Studio используйте «Отправить» с «Внешним накопителем», а печать запускайте после этого. Во всех случаях в принтере нужна карта или флешка.',
+      bodyInternalStorage: 'Bambu Studio сохранил нарезанный файл во внутренней памяти принтера, а не на карте, поэтому Bambuddy было нечего читать по FTP. На серии H2, P2S и X2D кнопка «Печать» всегда делает так: выбор есть только в «Отправить», и там по умолчанию тоже «Кэш». Эти печати по-прежнему архивируются с именем и временем, только без миниатюры и метаданных слайсера. Чтобы архивы были полными, запускайте печать из Bambuddy или нарезайте в OrcaSlicer, либо в Bambu Studio используйте «Отправить» с «Внешним накопителем», а печать запускайте после этого. Во всех случаях в принтере нужна карта или флешка.',
       titleNoExternalStorage: 'Некоторые недавние печати не удалось архивировать — в принтере нет накопителя',
       bodyNoExternalStorage: 'Принтер не видит ни карты, ни флешки в слоте, поэтому нарезанному файлу некуда было попасть, а Bambuddy нечего читать. Вставьте накопитель, и следующая печать будет заархивирована полностью.',
       titleInternalHistory: 'Некоторые недавние печати запущены из файла, который уже был на принтере',
@@ -6609,7 +6609,7 @@ export default {
         skip: "Не проверено — требуется активное подключение MQTT. В старых версиях слайсеров этот параметр существует только в слайсере и принтер его не сообщает, поэтому проверка может пройти даже при выключенном параметре. Проверьте шаг 4 установки вручную.",
         skip_unsupported_model: "В этой модели есть слот SD-карты, но включить соответствующую функцию невозможно: текущая прошивка серии P1 не предоставляет переключатель в Bambu Studio, а у принтера нет экрана. Исправлять здесь нечего. Пока Bambu Lab не добавит поддержку в прошивку, архивные задания могут сохраняться без миниатюр и метаданных слайсера.",
         fail_no_media: 'Параметр включён, но принтер не видит ни карты, ни флешки в слоте, поэтому отправленным файлам некуда деваться. Вставьте накопитель и напечатайте снова — до тех пор у каждой архивной печати не будет ни миниатюры, ни метаданных слайсера.',
-        warn_internal_storage: 'Параметр включён и накопитель на месте, но последняя печать всё равно ушла во внутреннюю память принтера, которую Bambuddy не может прочитать. На серии H2 и P2S кнопка «Печать» в Bambu Studio всегда отправляет туда, независимо от этого параметра. Печати архивируются с именем и временем, но без миниатюры и метаданных слайсера. Чтобы архивы были полными, запускайте печать из Bambuddy, нарезайте в OrcaSlicer или в Bambu Studio используйте «Отправить» с «Внешним накопителем», а затем запускайте печать.',
+        warn_internal_storage: 'Параметр включён и накопитель на месте, но последняя печать всё равно ушла во внутреннюю память принтера, которую Bambuddy не может прочитать. На серии H2, P2S и X2D кнопка «Печать» в Bambu Studio всегда отправляет туда, независимо от этого параметра. Печати архивируются с именем и временем, но без миниатюры и метаданных слайсера. Чтобы архивы были полными, запускайте печать из Bambuddy, нарезайте в OrcaSlicer или в Bambu Studio используйте «Отправить» с «Внешним накопителем», а затем запускайте печать.',
         warn_internal_history: 'Опция включена и накопитель на месте, но последняя печать шла из файла, который уже был на принтере, — повторная печать с его экрана, запуск из Handy или файл, отправленный раньше. Эта библиотека лежит во внутренней памяти, которую Bambuddy не читает, и никакие настройки этого не меняют: для той печати ничего не отправлялось. Она по-прежнему архивируется с именем и временем, но без миниатюры и метаданных слайсера. Чтобы архивы были полными, запускайте печать из Bambuddy или отправляйте её из слайсера.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/tr.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: 'Kurulum adımı 4\'ü görüntüle',
       docsLinkInternalStorage: 'Bu neden oluyor',
       titleInternalStorage: 'Bazı son baskılar yazıcının dahili depolamasında kaldı',
-      bodyInternalStorage: 'Bambu Studio dilimlenmiş dosyayı karta değil yazıcının dahili depolamasına yazdı, bu yüzden Bambuddy\'nin FTP üzerinden okuyacağı bir şey yoktu. H2 serisi ve P2S\'de «Yazdır» düğmesi bunu her zaman yapar; seçim yalnızca «Gönder» ile mümkündür ve orada da varsayılan «Önbellek»tir. Bu baskılar adları ve süreleriyle yine arşivlenir, yalnızca küçük resim ve dilimleyici meta verileri olmadan. Eksiksiz arşivler için baskıyı Bambuddy üzerinden başlatın ya da OrcaSlicer ile dilimleyin; Bambu Studio kullanacaksanız «Gönder» ile «Harici» seçip baskıyı sonrasında başlatın. Hepsi yazıcıda kart ya da bellek gerektirir.',
+      bodyInternalStorage: 'Bambu Studio dilimlenmiş dosyayı karta değil yazıcının dahili depolamasına yazdı, bu yüzden Bambuddy\'nin FTP üzerinden okuyacağı bir şey yoktu. H2 serisi, P2S ve X2D\'de «Yazdır» düğmesi bunu her zaman yapar; seçim yalnızca «Gönder» ile mümkündür ve orada da varsayılan «Önbellek»tir. Bu baskılar adları ve süreleriyle yine arşivlenir, yalnızca küçük resim ve dilimleyici meta verileri olmadan. Eksiksiz arşivler için baskıyı Bambuddy üzerinden başlatın ya da OrcaSlicer ile dilimleyin; Bambu Studio kullanacaksanız «Gönder» ile «Harici» seçip baskıyı sonrasında başlatın. Hepsi yazıcıda kart ya da bellek gerektirir.',
       titleNoExternalStorage: 'Bazı son baskılar arşivlenemedi — yazıcıda depolama yok',
       bodyNoExternalStorage: 'Yazıcı yuvasında kart veya bellek bildirmiyor, bu yüzden dilimlenmiş dosyanın ineceği bir yer ve Bambuddy\'nin okuyacağı bir şey yoktu. Bir tane takın, sonraki baskı eksiksiz arşivlenecek.',
       titleInternalHistory: 'Bazı son baskılar yazıcıda zaten bulunan bir dosyadan başlatıldı',
@@ -6919,7 +6919,7 @@ export default {
         skip: 'Kontrol edilmedi — etkin bir MQTT bağlantısı gerekli. Bu ayarın yalnızca dilimleyicide bulunduğu eski dilimleyicilerde yazıcı bunu bildirmez, bu nedenle seçenek kapalı olsa bile bu kontrol geçer — kurulum adımı 4\'ü manuel olarak doğrulayın.',
         skip_unsupported_model: 'Bu modelde SD yuvası var ancak seçeneği açmanın bir yolu yok — mevcut P1 serisi bellenim, Bambu Studio\'da bu anahtarı göstermiyor ve yazıcının ekranı yok. Burada düzeltilecek bir şey yok; Bambu Lab bellenim desteği ekleyene kadar arşivlenen baskılarda küçük resimler ve dilimleyici meta verileri eksik olabilir.',
         fail_no_media: 'Seçenek açık, ancak yazıcı yuvasında kart veya bellek bildirmiyor, dolayısıyla gönderilen dosyaların gideceği bir yer yok. Bir tane takıp yeniden yazdırın — o zamana kadar arşivlenen her baskıda küçük resim ve dilimleyici meta verileri eksik olacak.',
-        warn_internal_storage: 'Seçenek açık ve depolama takılı, ancak son baskı yine de Bambuddy\'nin okuyamadığı dahili depolamaya gitti. H2 serisi ve P2S\'de Bambu Studio\'nun «Yazdır» düğmesi bu ayardan bağımsız olarak her zaman oraya gönderir. Baskılar adları ve süreleriyle arşivlenir, ancak küçük resim ve dilimleyici meta verileri olmadan. Eksiksiz arşivler için baskıları Bambuddy üzerinden başlatın, OrcaSlicer ile dilimleyin ya da Bambu Studio\'da «Gönder» ile «Harici» seçip baskıyı sonrasında başlatın.',
+        warn_internal_storage: 'Seçenek açık ve depolama takılı, ancak son baskı yine de Bambuddy\'nin okuyamadığı dahili depolamaya gitti. H2 serisi, P2S ve X2D\'de Bambu Studio\'nun «Yazdır» düğmesi bu ayardan bağımsız olarak her zaman oraya gönderir. Baskılar adları ve süreleriyle arşivlenir, ancak küçük resim ve dilimleyici meta verileri olmadan. Eksiksiz arşivler için baskıları Bambuddy üzerinden başlatın, OrcaSlicer ile dilimleyin ya da Bambu Studio\'da «Gönder» ile «Harici» seçip baskıyı sonrasında başlatın.',
         warn_internal_history: 'Seçenek açık ve depolama takılı, ancak son baskı yazıcıda zaten bulunan bir dosyadan çalıştı — ekranından yeniden baskı, Handy üzerinden başlatma ya da daha önce gönderilmiş bir dosya. Bu kitaplık, Bambuddy\'nin okuyamadığı dahili depolamada durur ve o baskı için hiçbir şey gönderilmediğinden hiçbir ayar bunu değiştirmez. Adı ve süreleriyle yine arşivlenir, ama küçük resim ve dilimleyici meta verileri olmadan. Eksiksiz arşivler için baskıları Bambuddy\'den başlatın ya da dilimleyiciden gönderin.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/uk.ts

@@ -907,7 +907,7 @@ export default {
       docsLink: "Переглянути крок 4 встановлення",
       docsLinkInternalStorage: 'Чому так стається',
       titleInternalStorage: 'Деякі нещодавні друки залишилися у внутрішній пам\'яті принтера',
-      bodyInternalStorage: 'Bambu Studio зберіг нарізаний файл у внутрішній пам\'яті принтера, а не на картці, тож Bambuddy не мав чого читати через FTP. На серії H2 та P2S кнопка «Друк» завжди робить саме так: вибір є лише в «Надіслати», і там за замовчуванням теж «Кеш». Ці друки й далі архівуються з назвою та часом, лише без мініатюри та метаданих слайсера. Щоб архіви були повними, запускайте друк із Bambuddy або нарізайте в OrcaSlicer, або в Bambu Studio скористайтеся «Надіслати» із «Зовнішнім носієм», а друк запускайте потім. Усі варіанти потребують картки або флешки в принтері.',
+      bodyInternalStorage: 'Bambu Studio зберіг нарізаний файл у внутрішній пам\'яті принтера, а не на картці, тож Bambuddy не мав чого читати через FTP. На серії H2, P2S та X2D кнопка «Друк» завжди робить саме так: вибір є лише в «Надіслати», і там за замовчуванням теж «Кеш». Ці друки й далі архівуються з назвою та часом, лише без мініатюри та метаданих слайсера. Щоб архіви були повними, запускайте друк із Bambuddy або нарізайте в OrcaSlicer, або в Bambu Studio скористайтеся «Надіслати» із «Зовнішнім носієм», а друк запускайте потім. Усі варіанти потребують картки або флешки в принтері.',
       titleNoExternalStorage: 'Деякі нещодавні друки не вдалося заархівувати — у принтері немає носія',
       bodyNoExternalStorage: 'Принтер не бачить ані картки, ані флешки у слоті, тож нарізаному файлу не було куди потрапити, а Bambuddy — що читати. Вставте носій, і наступний друк заархівується повністю.',
       titleInternalHistory: 'Деякі нещодавні друки запущено з файлу, який уже був на принтері',
@@ -7023,7 +7023,7 @@ export default {
         skip: "Не перевірено — потрібне активне MQTT-з’єднання. У старіших слайсерах, де цей параметр існує лише в самому слайсері, принтер його не повідомляє. Тому перевірка може бути успішною навіть за вимкненого параметра — перевірте крок установлення 4 вручну.",
         skip_unsupported_model: "Ця модель має слот для SD-картки, але не дає змоги ввімкнути цей параметр: поточна прошивка принтерів серії P1 не показує перемикач у Bambu Studio, а сам принтер не має екрана. Виправляти нічого не потрібно; доки Bambu Lab не додасть підтримку в прошивці, в архівованих друках можуть бути відсутні мініатюри та метадані слайсера.",
         fail_no_media: 'Параметр увімкнено, але принтер не бачить ані картки, ані флешки у слоті, тож надісланим файлам немає куди подітися. Вставте носій і надрукуйте ще раз — доти кожен заархівований друк буде без мініатюри та метаданих слайсера.',
-        warn_internal_storage: 'Параметр увімкнено і носій на місці, але останній друк усе одно потрапив у внутрішню пам\'ять принтера, яку Bambuddy не може прочитати. На серії H2 та P2S кнопка «Друк» у Bambu Studio завжди надсилає туди, незалежно від цього параметра. Друки архівуються з назвою та часом, але без мініатюри та метаданих слайсера. Щоб архіви були повними, запускайте друк із Bambuddy, нарізайте в OrcaSlicer або в Bambu Studio скористайтеся «Надіслати» із «Зовнішнім носієм», а потім запускайте друк.',
+        warn_internal_storage: 'Параметр увімкнено і носій на місці, але останній друк усе одно потрапив у внутрішню пам\'ять принтера, яку Bambuddy не може прочитати. На серії H2, P2S та X2D кнопка «Друк» у Bambu Studio завжди надсилає туди, незалежно від цього параметра. Друки архівуються з назвою та часом, але без мініатюри та метаданих слайсера. Щоб архіви були повними, запускайте друк із Bambuddy, нарізайте в OrcaSlicer або в Bambu Studio скористайтеся «Надіслати» із «Зовнішнім носієм», а потім запускайте друк.',
         warn_internal_history: 'Опція увімкнена й носій на місці, але останній друк ішов із файлу, який уже був на принтері, — повторний друк з його екрана, запуск із Handy або файл, надісланий раніше. Ця бібліотека лежить у внутрішній пам\'яті, яку Bambuddy не читає, і жодні налаштування цього не змінюють: для того друку нічого не надсилалося. Він і далі архівується з назвою та часом, але без мініатюри та метаданих слайсера. Щоб архіви були повними, запускайте друк із Bambuddy або надсилайте його зі слайсера.',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/zh-CN.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: '查看安装步骤 4',
       docsLinkInternalStorage: '为什么会这样',
       titleInternalStorage: '最近有些打印留在了打印机的内部存储中',
-      bodyInternalStorage: 'Bambu Studio 把切片文件保存到了打印机的内部存储而不是存储卡上,因此 Bambuddy 通过 FTP 读不到任何东西。在 H2 系列和 P2S 上,「打印」按钮总是这样做,只有「发送」才提供选择,而它的默认值也是「缓存」。这些打印仍会带着名称和时间归档,只是没有缩略图和切片元数据。要获得完整归档,请从 Bambuddy 启动打印,或改用 OrcaSlicer 切片;若要继续用 Bambu Studio,请用「发送」并选择「外部存储」,之后再启动打印。以上都需要打印机中插有存储卡或 U 盘。',
+      bodyInternalStorage: 'Bambu Studio 把切片文件保存到了打印机的内部存储而不是存储卡上,因此 Bambuddy 通过 FTP 读不到任何东西。在 H2 系列、P2S 和 X2D 上,「打印」按钮总是这样做,只有「发送」才提供选择,而它的默认值也是「缓存」。这些打印仍会带着名称和时间归档,只是没有缩略图和切片元数据。要获得完整归档,请从 Bambuddy 启动打印,或改用 OrcaSlicer 切片;若要继续用 Bambu Studio,请用「发送」并选择「外部存储」,之后再启动打印。以上都需要打印机中插有存储卡或 U 盘。',
       titleNoExternalStorage: '最近有些打印无法归档 — 打印机中没有存储介质',
       bodyNoExternalStorage: '打印机的插槽中未检测到存储卡或U盘,切片文件无处存放,Bambuddy 也无从读取。插入一个,下次打印就会完整归档。',
       titleInternalHistory: '最近有些打印是从打印机里已有的文件启动的',
@@ -6967,7 +6967,7 @@ export default {
         skip: '未检查 — 需要有效的 MQTT 连接。在该设置仅存在于切片机中的较旧切片机上,打印机不会报告此设置,因此即使选项已关闭,此检查也会通过 — 请手动验证安装步骤 4。',
         skip_unsupported_model: '此型号有 SD 卡槽,但无法开启该选项 — 当前 P1 系列固件不会在 Bambu Studio 中显示此开关,且打印机没有屏幕。这里无需修复;在 Bambu Lab 通过固件添加支持之前,存档的打印可能缺少缩略图和切片元数据。',
         fail_no_media: '该选项已开启,但打印机的插槽中未检测到存储卡或U盘,发送的文件无处存放。插入一个再打印一次 — 在此之前,每一次归档的打印都会缺少缩略图和切片元数据。',
-        warn_internal_storage: '该选项已开启且存储介质在位,但上一次打印仍进入了 Bambuddy 无法读取的打印机内部存储。在 H2 系列和 P2S 上,无论此选项如何设置,Bambu Studio 的「打印」按钮总是发送到那里。打印会带着名称和时间归档,但没有缩略图和切片元数据。要获得完整归档,请从 Bambuddy 启动打印、改用 OrcaSlicer 切片,或在 Bambu Studio 中用「发送」选择「外部存储」后再启动打印。',
+        warn_internal_storage: '该选项已开启且存储介质在位,但上一次打印仍进入了 Bambuddy 无法读取的打印机内部存储。在 H2 系列、P2S 和 X2D 上,无论此选项如何设置,Bambu Studio 的「打印」按钮总是发送到那里。打印会带着名称和时间归档,但没有缩略图和切片元数据。要获得完整归档,请从 Bambuddy 启动打印、改用 OrcaSlicer 切片,或在 Bambu Studio 中用「发送」选择「外部存储」后再启动打印。',
         warn_internal_history: '该选项已开启,存储介质也在,但最近一次打印来自打印机里已有的文件 — 从它的屏幕重新打印、从 Handy 启动,或是先前发送过的文件。这个文件库位于 Bambuddy 读不到的内部存储中,而且任何设置都改变不了,因为那次打印根本没有发送过文件。它仍会带着名称和时间归档,但没有缩略图和切片元数据。要获得完整归档,请从 Bambuddy 启动打印,或从切片软件发送。',
       },
       port_rtsps: {

+ 2 - 2
frontend/src/i18n/locales/zh-TW.ts

@@ -903,7 +903,7 @@ export default {
       docsLink: '檢視安裝步驟 4',
       docsLinkInternalStorage: '為什麼會這樣',
       titleInternalStorage: '最近有些列印留在了印表機的內部儲存中',
-      bodyInternalStorage: 'Bambu Studio 把切片檔案儲存到了印表機的內部儲存而不是記憶卡上,因此 Bambuddy 透過 FTP 讀不到任何東西。在 H2 系列與 P2S 上,「列印」按鈕總是這樣做,只有「傳送」才提供選擇,而它的預設值也是「快取」。這些列印仍會帶著名稱與時間歸檔,只是沒有縮圖與切片中繼資料。要取得完整歸檔,請從 Bambuddy 啟動列印,或改用 OrcaSlicer 切片;若要繼續用 Bambu Studio,請用「傳送」並選擇「外部儲存」,之後再啟動列印。以上都需要印表機中插有記憶卡或 USB 隨身碟。',
+      bodyInternalStorage: 'Bambu Studio 把切片檔案儲存到了印表機的內部儲存而不是記憶卡上,因此 Bambuddy 透過 FTP 讀不到任何東西。在 H2 系列、P2S 與 X2D 上,「列印」按鈕總是這樣做,只有「傳送」才提供選擇,而它的預設值也是「快取」。這些列印仍會帶著名稱與時間歸檔,只是沒有縮圖與切片中繼資料。要取得完整歸檔,請從 Bambuddy 啟動列印,或改用 OrcaSlicer 切片;若要繼續用 Bambu Studio,請用「傳送」並選擇「外部儲存」,之後再啟動列印。以上都需要印表機中插有記憶卡或 USB 隨身碟。',
       titleNoExternalStorage: '最近有些列印無法歸檔 — 印表機中沒有儲存媒體',
       bodyNoExternalStorage: '印表機的插槽中未偵測到記憶卡或隨身碟,切片檔案無處存放,Bambuddy 也無從讀取。插入一個,下次列印就會完整歸檔。',
       titleInternalHistory: '最近有些列印是從印表機裡既有的檔案啟動的',
@@ -6967,7 +6967,7 @@ export default {
         skip: '未檢查 — 需要有效的 MQTT 連線。在該設定僅存在於切片機中的較舊切片機上,印表機不會回報此設定,因此即使選項已關閉,此檢查也會通過 — 請手動驗證安裝步驟 4。',
         skip_unsupported_model: '此型號有 SD 卡槽,但無法開啟該選項 — 目前 P1 系列韌體不會在 Bambu Studio 中顯示此開關,且印表機沒有螢幕。這裡無需修復;在 Bambu Lab 透過韌體加入支援之前,封存的列印可能缺少縮圖和切片中繼資料。',
         fail_no_media: '該選項已開啟,但印表機的插槽中未偵測到記憶卡或隨身碟,傳送的檔案無處存放。插入一個再列印一次 — 在此之前,每一次歸檔的列印都會缺少縮圖與切片中繼資料。',
-        warn_internal_storage: '該選項已開啟且儲存媒體在位,但上一次列印仍進入了 Bambuddy 無法讀取的印表機內部儲存。在 H2 系列與 P2S 上,無論此選項如何設定,Bambu Studio 的「列印」按鈕總是傳送到那裡。列印會帶著名稱與時間歸檔,但沒有縮圖與切片中繼資料。要取得完整歸檔,請從 Bambuddy 啟動列印、改用 OrcaSlicer 切片,或在 Bambu Studio 中用「傳送」選擇「外部儲存」後再啟動列印。',
+        warn_internal_storage: '該選項已開啟且儲存媒體在位,但上一次列印仍進入了 Bambuddy 無法讀取的印表機內部儲存。在 H2 系列、P2S 與 X2D 上,無論此選項如何設定,Bambu Studio 的「列印」按鈕總是傳送到那裡。列印會帶著名稱與時間歸檔,但沒有縮圖與切片中繼資料。要取得完整歸檔,請從 Bambuddy 啟動列印、改用 OrcaSlicer 切片,或在 Bambu Studio 中用「傳送」選擇「外部儲存」後再啟動列印。',
         warn_internal_history: '該選項已開啟,儲存媒體也在,但最近一次列印來自印表機裡既有的檔案 — 從它的螢幕重新列印、從 Handy 啟動,或是先前傳送過的檔案。這個檔案庫位於 Bambuddy 讀不到的內部儲存中,而且任何設定都改變不了,因為那次列印根本沒有傳送過檔案。它仍會帶著名稱與時間歸檔,但沒有縮圖與切片中繼資料。要獲得完整歸檔,請從 Bambuddy 啟動列印,或從切片軟體傳送。',
       },
       port_rtsps: {

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
static/assets/index-CuU0coVt.js


+ 1 - 1
static/index.html

@@ -26,7 +26,7 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="/assets/index-BlnLA2nI.js"></script>
+    <script type="module" crossorigin src="/assets/index-CuU0coVt.js"></script>
     <link rel="stylesheet" crossorigin href="/assets/index-ChscM3lF.css">
   </head>
   <body>

Неке датотеке нису приказане због велике количине промена