diff --git a/.claude/skills/orca-translations/SKILL.md b/.claude/skills/orca-translations/SKILL.md index ea2932fb27..ef0eae504d 100644 --- a/.claude/skills/orca-translations/SKILL.md +++ b/.claude/skills/orca-translations/SKILL.md @@ -1,6 +1,6 @@ --- name: orca-translations -description: Use when updating, filling, reviewing or fixing OrcaSlicer translations in localization/i18n — running scripts/run_gettext --full, translating empty or new msgids in the .po catalogs, AI translation passes and their "# AI Translated" / "# Needs human review" comments, plural forms, msgctxt homonyms, and keeping catalogs consistent with the localization glossary (OrcaSlicer_WIKI localization_glossary.tsv), including adding new glossary terms. Also use for msgfmt or run_gettext failures, placeholder or line-break mismatches, and reviewing a translation PR against the glossary. +description: Use when updating, filling, reviewing or fixing OrcaSlicer translations in localization/i18n — running scripts/run_gettext --full, translating empty or new msgids in the .po catalogs, AI translation passes and their "# AI Translated" / "# Needs human review" comments, plural forms, msgctxt homonyms, and keeping catalogs consistent with the localization glossary (OrcaSlicer_WIKI developer_reference/glossary), including adding new glossary terms. Also use for msgfmt or run_gettext failures, placeholder or line-break mismatches, and reviewing a translation PR against the glossary. --- # OrcaSlicer translations @@ -9,7 +9,7 @@ The UI strings live in gettext catalogs: `localization/i18n/OrcaSlicer.pot` is t `localization/i18n//OrcaSlicer_.po` holds each language. The `en` catalog is empty on purpose, so skip it. Recurring terms are fixed by the [localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/localization_glossary.md), -whose source is `developer_reference/localization_glossary.tsv` in the **OrcaSlicer_WIKI** repository. +whose source is the per-language files in `developer_reference/glossary/` (`terms.tsv`, `languages.txt` and one `.tsv`) in the **OrcaSlicer_WIKI** repository. A translation pass therefore touches two repositories: the catalogs here, and the glossary there. All catalog editing goes through [`scripts/po_tool.py`](scripts/po_tool.py) (standard library only). @@ -153,7 +153,7 @@ Report: - anything left empty, and why; - the glossary rows added or filled. -The catalogs (and `OrcaSlicer.pot`) and the glossary (`localization_glossary.tsv` and `.md`) are +The catalogs (and `OrcaSlicer.pot`) and the glossary (`developer_reference/glossary/*.tsv` and `localization_glossary.md`) are separate changes in separate repositories. The wiki change should land with, or before, the catalog change. Commit or open PRs only when asked. @@ -210,7 +210,7 @@ with the translators, followed by the catalogs. When this skill and the checkouts disagree, the checkouts win: - `scripts/run_gettext.sh` / `.bat` for extraction and merging; - `localization/i18n/list.txt` for the scanned sources; -- the wiki's `localization_guide.md` and `localization_glossary.md` / `.tsv` for the rules and terms; +- the wiki's `localization_guide.md` and `localization_glossary.md` and `glossary/*.tsv` for the rules and terms; - `AGENTS.md` (Localization & translations) for the repository's conventions. ## Editing this skill diff --git a/.claude/skills/orca-translations/scripts/po_tool.py b/.claude/skills/orca-translations/scripts/po_tool.py index 218eaf3db7..e8ca2e5b7a 100644 --- a/.claude/skills/orca-translations/scripts/po_tool.py +++ b/.claude/skills/orca-translations/scripts/po_tool.py @@ -28,13 +28,14 @@ import sys import tempfile import time import unicodedata +import urllib.error import urllib.request from pathlib import Path REPO = Path(__file__).resolve().parents[4] I18N = REPO / "localization" / "i18n" SKIP_LANGS = {"en"} # the English catalog is intentionally empty -GLOSSARY_TSV = Path("developer_reference") / "localization_glossary.tsv" +GLOSSARY_DIR = Path("developer_reference") / "glossary" # terms.tsv, languages.txt and one .tsv per language GLOSSARY_MD = Path("developer_reference") / "localization_glossary.md" MISSING = {"", "—"} RAW_URL = "https://raw.githubusercontent.com/OrcaSlicer/OrcaSlicer_WIKI/main/" @@ -252,30 +253,40 @@ def all_langs(): def find_wiki(arg): for cand in [arg, os.environ.get("ORCA_WIKI_DIR"), REPO.parent / "OrcaSlicer_WIKI", REPO.parent / "OrcaSlicer.wiki"]: - if cand and (Path(cand) / GLOSSARY_TSV).exists(): + if cand and (Path(cand) / GLOSSARY_DIR / "terms.tsv").exists(): return Path(cand) return None -def _download(rel): - cache = Path(tempfile.gettempdir()) / ("orca_glossary_" + rel.name) +def _download(rel, required=True): + cache = Path(tempfile.gettempdir()) / "orca_glossary" / rel if not cache.exists() or time.time() - cache.stat().st_mtime > 3600: - with urllib.request.urlopen(RAW_URL + rel.as_posix(), timeout=30) as r: - cache.write_bytes(r.read()) + try: + with urllib.request.urlopen(RAW_URL + rel.as_posix(), timeout=30) as r: + data = r.read() + except urllib.error.HTTPError: + if required: + raise + return None + cache.parent.mkdir(parents=True, exist_ok=True) + cache.write_bytes(data) return cache class Glossary: - def __init__(self, wiki_arg=None, quiet=False): + """The glossary: rows of [English, Description, ].""" + + def __init__(self, wiki_arg=None, quiet=False, langs=None): self.wiki = find_wiki(wiki_arg) + self.langs = langs # only these languages' files are read (and downloaded); None means all if self.wiki: - self.tsv, self.md = self.wiki / GLOSSARY_TSV, self.wiki / GLOSSARY_MD + self.dir, self.md = self.wiki / GLOSSARY_DIR, self.wiki / GLOSSARY_MD if not quiet: self.report_clone_state() else: if not quiet: print("note: no OrcaSlicer_WIKI clone found; using the published glossary read-only", file=sys.stderr) - self.tsv, self.md = _download(GLOSSARY_TSV), _download(GLOSSARY_MD) + self.dir, self.md = _download(GLOSSARY_DIR / "terms.tsv").parent, _download(GLOSSARY_MD) self.load() def report_clone_state(self): @@ -290,11 +301,23 @@ class Glossary: if behind and behind != "0": print(f"note: the wiki clone is {behind} commits behind origin/main (as of its last fetch)", file=sys.stderr) + def _read(self, name, required=True): + path = self.dir / name if self.wiki else _download(GLOSSARY_DIR / name, required) + return path.read_text(encoding="utf-8-sig").splitlines() if path and path.exists() else None + def load(self): - rows = [l.split("\t") for l in self.tsv.read_text(encoding="utf-8-sig").splitlines() if l.strip()] - self.header = rows[0] - # "—" marks a language with no established rendering yet - self.rows = [[c if c.strip() not in MISSING else "" for c in r] + [""] * (len(rows[0]) - len(r)) for r in rows[1:]] + terms = [l.split(" ") for l in self._read("terms.tsv")[1:] if l.strip()] + langs = [l.strip() for l in self._read("languages.txt") if l.strip()] + langs = [l for l in langs if self.langs is None or l in self.langs] + self.header = ["English", "Description"] + langs + self.rows = [[r[0], r[1] if len(r) > 1 else ""] + [""] * len(langs) for r in terms] + index = {r[0]: r for r in self.rows} + for col, lang in enumerate(langs, start=2): + for line in (self._read(f"{lang}.tsv", required=False) or [])[1:]: + cells = line.split(" ") + # "—" marks a language with no established rendering yet + if len(cells) > 2 and cells[0] in index and cells[2].strip() not in MISSING: + index[cells[0]][col] = cells[2].strip() self.matchers = [] for row in self.rows: base = re.sub(r"\s*\([^)]*\)\s*$", "", row[0]).strip() @@ -494,7 +517,7 @@ def similar_entries(c, e, pool, cutoff=0.72): def cmd_pending(a): c = Catalog(catalog_path(a.lang)) - g = Glossary(a.wiki) + g = Glossary(a.wiki, langs=[a.lang]) todo = [e for e in c.active() if needs_translation(e, c.nplurals, a.include_fuzzy)] batch = todo[a.offset:a.offset + a.limit] if a.limit else todo[a.offset:] pool = [(x.msgid, x.msgstrs()[0], x.obsolete) for x in c.entries @@ -533,7 +556,7 @@ def cmd_pending(a): def cmd_apply(a): c = Catalog(catalog_path(a.lang)) - g = None if a.no_glossary else Glossary(a.wiki, quiet=True) + g = None if a.no_glossary else Glossary(a.wiki, quiet=True, langs=[a.lang]) data = json.loads(Path(a.input).read_text(encoding="utf-8")) items = data["entries"] if isinstance(data, dict) else data idx = c.index() @@ -588,7 +611,7 @@ def find_msgfmt(): def cmd_check(a): - g = None if a.no_glossary else Glossary(a.wiki, quiet=True) + g = None if a.no_glossary else Glossary(a.wiki, quiet=True, langs=a.lang or None) msgfmt = find_msgfmt() status = 0 for lang in a.lang or all_langs(): @@ -646,7 +669,7 @@ def cmd_lookup(a): def cmd_glossary(a): - g = Glossary(a.wiki) + g = Glossary(a.wiki, langs=[a.lang]) col = g.column(a.lang) if col is None: print(f"'{a.lang}' has no glossary column yet; add one with glossary-set --set {a.lang}=...") @@ -733,6 +756,17 @@ def cmd_candidates(a): print(f"{cnt:7} {langs:6} {text}{' [label]' if k in labels else ''} e.g. {ex[:70]}{'…' if len(ex) > 70 else ''}") +def _edit_tsv(path, edit): + """Apply edit(lines) to a glossary TSV, keeping its BOM and line endings.""" + data = path.read_bytes() + bom = data.startswith(b"\xef\xbb\xbf") + text = data.decode("utf-8-sig") + nl = "\r\n" if "\r\n" in text else "\n" + lines = text.splitlines() + edit(lines) + path.write_bytes((b"\xef\xbb\xbf" if bom else b"") + (nl.join(lines) + nl).encode("utf-8")) + + def cmd_glossary_set(a): wiki = find_wiki(a.wiki) if not wiki: @@ -741,8 +775,21 @@ def cmd_glossary_set(a): f" {a.term}: " + ", ".join(a.set) + "\n" "Clone https://github.com/OrcaSlicer/OrcaSlicer_WIKI next to this repository, or pass --wiki.", file=sys.stderr) return 2 - tsv = wiki / GLOSSARY_TSV - lock = tsv.with_suffix(".lock") + gdir = wiki / GLOSSARY_DIR + gen = wiki / "generate_glossary.py" + if not gen.exists(): + sys.exit(f"{gen} not found") + run_gen = lambda *args: subprocess.run([sys.executable, str(gen), *args], cwd=wiki, capture_output=True, text=True) + langs = [l.strip() for l in (gdir / "languages.txt").read_text(encoding="utf-8-sig").splitlines() if l.strip()] + values = {} + for s in a.set: + lang, _, val = s.partition("=") + if lang not in langs: + sys.exit(f"no glossary language '{lang}' (add it to {GLOSSARY_DIR.as_posix()}/languages.txt)") + if "\t" in val or "\n" in val: + sys.exit("values cannot contain tabs or line breaks") + values[lang] = val.strip() + lock = gdir / ".lock" for _ in range(100): try: fd = os.open(lock, os.O_CREAT | os.O_EXCL) @@ -752,50 +799,51 @@ def cmd_glossary_set(a): else: sys.exit(f"could not lock {lock}; remove it if no other run is active") try: - data = tsv.read_bytes() - bom = data.startswith(b"\xef\xbb\xbf") - text = data.decode("utf-8-sig") - nl = "\r\n" if "\r\n" in text else "\n" - lines = text.splitlines() - header = lines[0].split("\t") - values = {} - for s in a.set: - lang, _, val = s.partition("=") - if lang not in header: - sys.exit(f"no glossary column '{lang}'") - if "\t" in val or "\n" in val: - sys.exit("values cannot contain tabs or line breaks") - values[header.index(lang)] = val.strip() - row_i = next((i for i, l in enumerate(lines[1:], 1) if l.split("\t")[0] == a.term), None) - new = row_i is None - if new: - if not a.description: - sys.exit("a new term needs --description (one sentence saying what it is)") - row = [a.term, a.description] + [""] * (len(header) - 2) - lines.append("") - row_i = len(lines) - 1 - else: - row = lines[row_i].split("\t") - row += [""] * (len(header) - len(row)) - if a.description: - row[1] = a.description - conflicts = [f"{header[i]}: '{row[i]}' -> '{v}'" for i, v in values.items() if row[i].strip() not in MISSING and row[i] != v] + terms = (gdir / "terms.tsv").read_text(encoding="utf-8-sig").splitlines() + new = not any(l.split("\t")[0] == a.term for l in terms[1:]) + if new and not a.description: + sys.exit("a new term needs --description (one sentence saying what it is)") + # an established translation is only replaced on request + conflicts = [] + for lang, v in values.items(): + for line in (gdir / f"{lang}.tsv").read_text(encoding="utf-8-sig").splitlines()[1:]: + cells = line.split("\t") + if cells[0] == a.term and len(cells) > 2 and cells[2].strip() not in MISSING and cells[2] != v: + conflicts.append(f"{lang}: '{cells[2]}' -> '{v}'") if conflicts and not a.replace: sys.exit("established translations differ (pass --replace, and update the catalogs to match):\n " + "\n ".join(conflicts)) - for i, v in values.items(): - row[i] = v - lines[row_i] = "\t".join(row) - tsv.write_bytes((b"\xef\xbb\xbf" if bom else b"") + (nl.join(lines) + nl).encode("utf-8")) + + def edit_terms(lines): + for i, l in enumerate(lines): + if i and l.split("\t")[0] == a.term: + if a.description: + lines[i] = f"{a.term}\t{a.description}" + return + lines.append(f"{a.term}\t{a.description}") + if new or a.description: + _edit_tsv(gdir / "terms.tsv", edit_terms) + r = run_gen("--sync") # copies the term and description into every language file + if r.returncode: + sys.exit((r.stdout + r.stderr).strip()) + + def setter(lang, v): + def edit(lines): + for i, l in enumerate(lines): + cells = l.split("\t") + if i and cells[0] == a.term: + lines[i] = "\t".join(cells[:2] + [v]) + return + sys.exit(f"{lang}.tsv has no row for '{a.term}'") + return edit + for lang, v in values.items(): + _edit_tsv(gdir / f"{lang}.tsv", setter(lang, v)) finally: os.close(fd) os.unlink(lock) print(f"glossary: {'added' if new else 'updated'} '{a.term}'") - gen = wiki / "generate_glossary.py" - if gen.exists(): - r = subprocess.run([sys.executable, str(gen), "--update"], cwd=wiki, capture_output=True, text=True) - print((r.stdout + r.stderr).strip()) - return r.returncode - return 0 + r = run_gen("--update") + print((r.stdout + r.stderr).strip()) + return r.returncode def main(): diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index ff07d1efb7..1918c009db 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -19,6 +19,8 @@ on: - 'build_linux.sh' - 'build_win.bat' - 'scripts/test_build_win.ps1' + - 'scripts/check_exception_throw_info.ps1' + - 'scripts/test_check_exception_throw_info.ps1' - 'build_release_macos.sh' - 'scripts/build_preset_cache.*' - 'scripts/flatpak/**' @@ -41,6 +43,8 @@ on: - 'build_linux.sh' - 'build_win.bat' - 'scripts/test_build_win.ps1' + - 'scripts/check_exception_throw_info.ps1' + - 'scripts/test_check_exception_throw_info.ps1' - 'build_release_macos.sh' - 'scripts/build_preset_cache.*' - 'scripts/flatpak/**' @@ -84,6 +88,10 @@ jobs: shell: powershell run: .\scripts\test_build_win.ps1 + - name: Run the exception throw info check tests + shell: powershell + run: .\scripts\test_check_exception_throw_info.ps1 + build_linux: strategy: fail-fast: false diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index 60456ad171..e9c4603bc8 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -65,15 +65,6 @@ jobs: shell: bash run: | leg="${{ runner.os }}-${{ inputs.arch || 'amd64' }}${{ runner.os == 'Windows' && format('-{0}', inputs.compiler) || '' }}" - # clang-cl refuses a precompiled header from another cl.exe build and ccache - # does not hash that build, so each one gets its own cache. The build number - # is read from cl.exe itself; the toolset directory keeps its name across patches. - if [ "${{ runner.os }}" = Windows ]; then - vswhere='/c/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe' - toolset=$(tr -d '\r\n' < "$("$vswhere" -latest -products '*' -find 'VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt' | tr -d '\r')") - cl=$("$vswhere" -latest -products '*' -find 'VC\Tools\MSVC\'"$toolset"'\**\cl.exe' | tr -d '\r' | head -1) - leg="$leg-vc$("$cl" 2>&1 | grep -o -E 'Version [0-9.]+' | cut -d' ' -f2)" - fi echo "CCACHE_LEG=$leg" >> "$GITHUB_ENV" echo "CCACHE_ENTRY=ccache-$leg-${{ github.run_id }}-${{ github.run_attempt }}" >> "$GITHUB_ENV" @@ -552,6 +543,13 @@ jobs: name: OrcaSlicer_profile_validator_Windows_${{ env.ver }} path: ${{ github.workspace }}/build/src/Release/OrcaSlicer_profile_validator.exe + - name: Check exception throw info Win + if: runner.os == 'Windows' && inputs.compiler == 'clang' + working-directory: ${{ github.workspace }} + # After the uploads, so a failure still leaves the build and its PDB to inspect, and before any deploy. + shell: pwsh + run: scripts\check_exception_throw_info.ps1 -BuildDir $env:BUILD_DIR + - name: Deploy Windows release portable if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED uses: ./.github/actions/deploy-nightly diff --git a/AGENTS.md b/AGENTS.md index 8dc4cf601e..b682caa1ba 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -91,7 +91,7 @@ See `.claude/skills/orca-translations/references/source-audit.md` for the full c ### Terminology - Use the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/developer_reference/localization_glossary.md) as the source of truth for recurring terms, so the same English term is always rendered the same way within a language, and terms that must stay in English (brand/product names, acronyms, materials, file formats, G-code tokens, macros/variables/identifiers) are not translated. -- If a term's established translation changes, update both the affected `.po` files and the glossary (`localization_glossary.tsv`, then regenerate) so they stay in sync. +- If a term's established translation changes, update both the affected `.po` files and the glossary (`developer_reference/glossary/.tsv` in the wiki, then regenerate) so they stay in sync. - Translate the *meaning*, not the words. Check what the string actually controls before translating it — English reuses one word for different things. `Flow ratio` (multiplier), `Flow Rate` (throughput) and `Flow Dynamics` (pressure compensation) are three different terms; `extruder` may mean the toolhead, the feeder motor, or the nozzle depending on the string. - Reuse one template per recurring message shape (`Failed to connect to …`, `Are you sure you want to …?`), even where the English wording varies. diff --git a/CMakeLists.txt b/CMakeLists.txt index 06ea0dbd6f..62798ebfc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -321,6 +321,14 @@ if (IS_CROSS_COMPILE) set(BUILD_TESTS OFF CACHE BOOL "" FORCE) endif () +# With a precompiled header, clang-cl can omit an exception type's copy constructor from its throw info, +# so copies of the exception share and double-free their data: https://github.com/llvm/llvm-project/issues/53486 +if (MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + message(STATUS "clang-cl: building without the precompiled header (llvm/llvm-project#53486)") + set_property(CACHE SLIC3R_PCH PROPERTY HELPSTRING "Use precompiled headers (ignored with clang-cl, llvm/llvm-project#53486)") + set(SLIC3R_PCH OFF) +endif () + # Print out the SLIC3R_* cache options get_cmake_property(_cache_vars CACHE_VARIABLES) list (SORT _cache_vars) diff --git a/build_linux.sh b/build_linux.sh index cf07d7e9df..b4c03e52ec 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -473,8 +473,8 @@ fi # cmake 4.x compatibility workaround export CMAKE_POLICY_VERSION_MINIMUM=3.5 -DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release | tr -d '"') -DISTRIBUTION_LIKE=$(awk -F= '/^ID_LIKE=/ {print $2}' /etc/os-release | tr -d '"') +DISTRIBUTION=$(awk -F= '/^ID=/ {print $2}' /etc/os-release | tr -d "'\"") +DISTRIBUTION_LIKE=$(awk -F= '/^ID_LIKE=/ {print $2}' /etc/os-release | tr -d "'\"") # Check for direct distribution match to Ubuntu/Debian if [ "${DISTRIBUTION}" == "ubuntu" ] || [ "${DISTRIBUTION}" == "linuxmint" ] ; then DISTRIBUTION="debian" diff --git a/build_release_macos.sh b/build_release_macos.sh index cdc5dbbe3c..9eca2e7f40 100755 --- a/build_release_macos.sh +++ b/build_release_macos.sh @@ -47,7 +47,7 @@ while getopts ":dpa:snt:xbc:i:j:Tuh" opt; do u ) export BUILD_TARGET="universal" ;; - h ) echo "Usage: ./build_release_macos.sh [-d]" + h ) echo "Usage: ./build_release_macos.sh [-d] [-- CMAKE_ARGS...]" echo " -d: Build deps only" echo " -a: Set ARCHITECTURE (arm64 or x86_64 or universal)" echo " -s: Build slicer only" @@ -60,13 +60,33 @@ while getopts ":dpa:snt:xbc:i:j:Tuh" opt; do echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew" echo " -j: Set the number of parallel build jobs (CMAKE_BUILD_PARALLEL_LEVEL)" echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)" + echo " -- CMAKE_ARGS...: pass everything after '--' to the cmake configure step of the deps (-d) and slicer (-s) builds," + echo " e.g. -DDESTDIR= for the deps, -DCMAKE_PREFIX_PATH=/usr/local -DSLIC3R_PCH=OFF for the slicer, --fresh." + echo " They come last on the cmake command line. Use absolute paths: cmake runs in the build directory." exit 0 ;; + : ) + echo "Option -${OPTARG} requires an argument, aborting." + exit 1 + ;; * ) + echo "Unknown option -${OPTARG}, aborting. CMake arguments must follow '--'." + exit 1 ;; esac done +# getopts stops at '--'; whatever follows is handed to cmake unchanged. +if [[ ${OPTIND} -le $# ]] ; then + separator_index=$((OPTIND-1)) + if [[ "${!separator_index}" != "--" ]] ; then + echo "Unexpected argument '${!OPTIND}': cmake arguments must follow '--', aborting." + exit 1 + fi +fi +shift $((OPTIND-1)) +EXTRA_CMAKE_ARGS=("$@") + # Set defaults if [ -z "$ARCH" ]; then @@ -211,7 +231,8 @@ function build_deps() { -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \ -DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \ "${CMAKE_CCACHE_ARGS[@]}" \ - ${CMAKE_POLICY_COMPAT} + ${CMAKE_POLICY_COMPAT} \ + "${EXTRA_CMAKE_ARGS[@]}" fi cmake --build . --config "$BUILD_CONFIG" --target deps ) @@ -314,7 +335,8 @@ function build_slicer() { -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_DEPLOYMENT_TARGET}" \ -DCMAKE_IGNORE_PREFIX_PATH="${CMAKE_IGNORE_PREFIX_PATH}" \ "${CMAKE_CCACHE_ARGS[@]}" \ - ${CMAKE_POLICY_COMPAT} + ${CMAKE_POLICY_COMPAT} \ + "${EXTRA_CMAKE_ARGS[@]}" fi cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET" ) diff --git a/build_win.bat b/build_win.bat index dc19df06bc..8af3581abf 100644 --- a/build_win.bat +++ b/build_win.bat @@ -53,7 +53,7 @@ call :add_section "Build configuration" call :add_arg config string "" config "release, debug, relwithdebinfo or minsizerel (default: release)" call :add_arg target_arch string "" arch "x64 or arm64 (default: the host architecture)" call :add_arg slicer_asan bool a asan "Build the slicer with ASAN enabled" -call :add_arg no_pch bool "" no-pch "Build without the precompiled header, implied by --cache" +call :add_arg no_pch bool "" no-pch "Build without the precompiled header, implied by -l and --cache" call :add_section "Toolchain" call :add_arg use_clang_cl bool l clang-cl "Use clang-cl as the compiler" @@ -388,6 +388,9 @@ if "%use_ninja%" == "ON" if "%use_msbuild%" == "ON" ( exit /b 1 ) +REM CMakeLists turns the precompiled header off for clang-cl (llvm/llvm-project#53486). +if "%use_clang_cl%" == "ON" set "no_pch=ON" + set "generator=!vs_gen_%vs_version%!" if "%use_ninja%" == "ON" ( set "generator=Ninja Multi-Config" @@ -543,7 +546,7 @@ REM real path rather than one glued onto the repository root. for %%p in ("!build_dir!") do set "build_full=%%~fp" echo Configuration: %build_type%, %arch% if not "%clang_exe%" == "" echo Compiler: %clang_exe% -if "%no_pch%" == "ON" echo Precompiled header: off +if "%build_slicer%" == "ON" if "%no_pch%" == "ON" echo Precompiled header: off if not "%cache_args%" == "" echo Compiler cache: %cache_exe% set "SIG_FLAG=" @@ -716,8 +719,8 @@ if "%build_slicer%" == "ON" ( set "slicer_args=!slicer_args! -DSLIC3R_ASAN=ON" ) - REM A later -DSLIC3R_PCH=ON in ORCA_SLICER_CMAKE_ARGS still wins, because - REM CMake takes the last definition on the command line. + REM Under cl, a later -DSLIC3R_PCH=ON in ORCA_SLICER_CMAKE_ARGS still wins, + REM because CMake takes the last definition on the command line. if "%no_pch%" == "ON" ( set "slicer_args=!slicer_args! -DSLIC3R_PCH=OFF" ) diff --git a/deps/OpenCV/OpenCV.cmake b/deps/OpenCV/OpenCV.cmake index 0290b3f47a..d465e6129d 100644 --- a/deps/OpenCV/OpenCV.cmake +++ b/deps/OpenCV/OpenCV.cmake @@ -26,6 +26,7 @@ orcaslicer_add_cmake_project(OpenCV URL https://github.com/opencv/opencv/archive/refs/tags/4.6.0.tar.gz URL_HASH SHA256=1ec1cba65f9f20fe5a41fda1586e01c70ea0c9a6d7b67c9e13edf0cfe2239277 PATCH_COMMAND git apply ${OpenCV_DIRECTORY_FLAG} --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-vs.patch ${CMAKE_CURRENT_LIST_DIR}/0002-clang19-macos.patch + DEPENDS ${JPEG_PKG} CMAKE_ARGS -DBUILD_SHARED_LIBS=0 -DBUILD_PERE_TESTS=OFF @@ -34,7 +35,8 @@ orcaslicer_add_cmake_project(OpenCV -DBUILD_EXAMPLES=OFF -DBUILD_JASPER=OFF -DBUILD_JAVA=OFF - -DBUILD_JPEG=ON + # Share Orca's libjpeg to avoid conflicting codec symbols in the application. + -DBUILD_JPEG=OFF -DBUILD_APPS_LIST=version -DBUILD_opencv_apps=OFF -DBUILD_opencv_java=OFF @@ -67,7 +69,8 @@ orcaslicer_add_cmake_project(OpenCV -DWITH_OPENJPEG=OFF -DWITH_QUIRC=OFF -DWITH_VTK=OFF - -DWITH_JPEG=OFF + # Textured GLB/OBJ imports decode embedded and external JPEGs with cv::imdecode. + -DWITH_JPEG=ON -DWITH_WEBP=OFF -DWITH_TIFF=OFF -DBUILD_TIFF=OFF diff --git a/deps/OpenSSL/OpenSSL.cmake b/deps/OpenSSL/OpenSSL.cmake index 35b17ed50e..971e2f1ad8 100644 --- a/deps/OpenSSL/OpenSSL.cmake +++ b/deps/OpenSSL/OpenSSL.cmake @@ -16,6 +16,8 @@ else() endif() endif() +set(_openssl_dir ${DESTDIR}) + if(WIN32) set(_openssl_msvc_env CC=cl CXX=cl RC=rc CL=/FS) # OpenSSL's perl Configure honors the CC environment variable, but the @@ -43,6 +45,14 @@ if(WIN32) else() if(APPLE) set(_conf_cmd export MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} && ./Configure -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) + # OPENSSLDIR is only where OpenSSL looks at runtime for cert.pem, certs/ + # and openssl.cnf; install_sw installs nothing there. Point it at the + # system CA bundle, the one libcurl already uses here, so the bundled + # Python's ssl module can verify HTTPS. Elsewhere it stays the prefix: + # Windows Python reads the system certificate store, and on Linux, where + # the bundle's location differs by distro, CurlGlobalInit points + # SSL_CERT_FILE at it at startup. + set(_openssl_dir /etc/ssl) else() # A static library that is embedded into a shared object must not export # its symbols. On Linux the running process also loads the system OpenSSL @@ -81,7 +91,7 @@ ExternalProject_Add(dep_OpenSSL # URL_HASH SHA256=8c776993154652d0bb393f506d850b811517c8bd8d24b1008aef57fbe55d3f31 DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/OpenSSL CONFIGURE_COMMAND ${_conf_cmd} ${_cross_arch} - "--openssldir=${DESTDIR}" + "--openssldir=${_openssl_dir}" "--prefix=${DESTDIR}" # OpenSSL's linux-x86_64 target sets multilib=64, so it installs to # /lib64 while every other dep uses /lib. CPython's @@ -115,12 +125,12 @@ ExternalProject_Add_Step(dep_OpenSSL install_cmake_files WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" ) -if (NOT WIN32 AND NOT APPLE) - # OpenSSL's object rules do not depend on CFLAGS, so reconfiguring it (for - # example to add -fvisibility=hidden) relinks the archives from stale - # objects instead of recompiling them, and the change silently has no - # effect. Drop the objects whenever this recipe changes so the next build - # actually recompiles them. +if (NOT WIN32) + # OpenSSL's object rules do not depend on the configured flags or paths, so + # reconfiguring it (a new compiler flag, a different --openssldir) relinks + # the archives from stale objects instead of recompiling them, and the + # change silently has no effect. Drop the objects whenever this recipe + # changes so the next build actually recompiles them. ExternalProject_Get_Property(dep_OpenSSL SOURCE_DIR) ExternalProject_Add_Step(dep_OpenSSL clean_objects DEPENDEES configure diff --git a/deps/python3/python3.cmake b/deps/python3/python3.cmake index f520c536d5..4f60bb1b14 100644 --- a/deps/python3/python3.cmake +++ b/deps/python3/python3.cmake @@ -365,10 +365,11 @@ if(TARGET dep_ZLIB) add_dependencies(dep_python3 dep_ZLIB) endif() -if (NOT WIN32 AND NOT APPLE) - # CPython's Makefile rules for _ssl and _hashlib depend only on their own - # sources, not on the OpenSSL archives, so a rebuilt OpenSSL does not make - # them relink and they keep the previous symbols. On an incremental tree, +if (NOT WIN32) + # _ssl and _hashlib embed the static OpenSSL built in deps/ (Windows uses + # CPython's prebuilt OpenSSL instead). Their Makefile rules depend only on + # their own sources, not on the OpenSSL archives, so a rebuilt OpenSSL does + # not make them relink and they keep the previous one. On an incremental tree, # drop the built modules and relink them against the current OpenSSL; a # fresh build is left alone (its PGO target builds them). "make" alone is a # no-op once PGO has run, so sharedmods is invoked explicitly. diff --git a/deps/wxWidgets/wxWidgets.cmake b/deps/wxWidgets/wxWidgets.cmake index e57e82f3e9..605fad2f0b 100644 --- a/deps/wxWidgets/wxWidgets.cmake +++ b/deps/wxWidgets/wxWidgets.cmake @@ -21,6 +21,14 @@ else () set(_wx_edge "-DwxUSE_WEBVIEW_EDGE=OFF") endif () +# With a precompiled header, clang-cl can omit an exception type's copy constructor from its throw info, +# so copies of the exception share and double-free their data: https://github.com/llvm/llvm-project/issues/53486 +if (MSVC AND CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(_wx_precomp OFF) +else () + set(_wx_precomp ON) +endif () + set(_wx_patch_command "") if (APPLE) set(_wx_patch_command @@ -39,7 +47,7 @@ orcaslicer_add_cmake_project( PATCH_COMMAND ${_wx_patch_command} DEPENDS ${PNG_PKG} ${ZLIB_PKG} ${EXPAT_PKG} ${JPEG_PKG} CMAKE_ARGS - -DwxBUILD_PRECOMP=ON + -DwxBUILD_PRECOMP=${_wx_precomp} ${_wx_toolkit} "-DCMAKE_DEBUG_POSTFIX:STRING=${_wx_debug_postfix}" -DwxBUILD_DEBUG_LEVEL=0 diff --git a/docs/HLSD/adaptive-tpms-infill.md b/docs/HLSD/adaptive-infill.md similarity index 96% rename from docs/HLSD/adaptive-tpms-infill.md rename to docs/HLSD/adaptive-infill.md index 5fc578f7e2..30eb364753 100644 --- a/docs/HLSD/adaptive-tpms-infill.md +++ b/docs/HLSD/adaptive-infill.md @@ -1,8 +1,8 @@ -# Adaptive TPMS infill — High Level Design +# Adaptive infill — High Level Design ## Purpose and scope -`tpms_adaptive` grades the sparse infill of the Gyroid, TPMS-D and TPMS-FK +`adaptive_infill_mode` grades the sparse infill of the Gyroid, TPMS-D and TPMS-FK patterns inside the object: the cells grow continuously from the surface towards the center of the object. `distance_warp`, `smooth_blend` and `stepped_shells` follow the distance to the nearest surface, including the top @@ -10,8 +10,8 @@ and bottom, like concentric shells; `lobes` follows the whole 3D shape towards the center of each lobe of the object; `normal_z`, `normal_y` and `normal_x` follow each section of the object normal to that axis, so the grading does not change along the axis, as suits a profile extruded along it. -`sparse_infill_density` is the density at the surface, `tpms_interior_density` -the density at the center, and `tpms_adaptive_gradient` picks how the density +`sparse_infill_density` is the density at the surface, `adaptive_infill_interior_density` +the density at the center, and `adaptive_infill_gradient` picks how the density goes from one to the other. Only internal sparse infill is graded; the Gyroid Z-buckling optimization does not apply to it. @@ -22,9 +22,9 @@ split into shells or blended between densities. ## Radial field -`TpmsRadialField` gives every point of an object the center of its lobe and a +`AdaptiveInfillField` gives every point of an object the center of its lobe and a radial coordinate: 0 at the center, 1 at the surface along the ray from the -center. `PrintObject::prepare_tpms_radial_fields()` builds it in +center. `PrintObject::prepare_adaptive_infill_fields()` builds it in `bridge_over_infill()`, next to the adaptive cubic octree, because the anchoring infill generated there has to match the printed infill. A field is built for every mode a region uses, and is shared by the regions using that mode: the @@ -202,7 +202,7 @@ built for them. ## Constraints -- With `tpms_adaptive` disabled, or for other patterns, the fill parameters are reset +- With `adaptive_infill_mode` disabled, or for other patterns, the fill parameters are reset to their defaults, so they neither change the infill nor split fill batches. - `Layer::get_sparse_infill_max_void_area()` uses the sparser of the two densities, as the voids at the center are that large. diff --git a/docs/HLSD/filament_id.md b/docs/HLSD/filament_id.md index 122dfb6fdb..555a5d6ad5 100644 --- a/docs/HLSD/filament_id.md +++ b/docs/HLSD/filament_id.md @@ -350,8 +350,11 @@ identity default and translates nothing. `NetworkAgent` forwards both to the liv comparison sites below reach them through `wxGetApp().getAgent()` and leave an id untranslated while no agent is live. Whole documents are Bambu's business alone: `BBLPrinterAgent::to_orca_payload` and `from_orca_payload` rewrite every string under -`tray_info_idx`, `filament_id` or `filamentId` at any depth; text that does not parse, or carries -none of those keys, comes back unchanged. The map is loaded once, lazily; a missing or malformed +`tray_info_idx`, `filament_id`, `filamentId`, `cate` or `fila_id` at any depth; text that does not +parse, or carries none of those keys, comes back unchanged. The last two are the H2C nozzle rack's: +`cate` in the auto nozzle mapping request, `fila_id` in the rack status. A new Bambu message that +carries a filament id under another key needs that key added to `filament_id_keys`, or the id +crosses the boundary untranslated. The map is loaded once, lazily; a missing or malformed file degrades to identity with a log line rather than failing. | Boundary | Where it translates | diff --git a/docs/HLSD/travel-optimization.md b/docs/HLSD/travel-optimization.md new file mode 100644 index 0000000000..119133cee2 --- /dev/null +++ b/docs/HLSD/travel-optimization.md @@ -0,0 +1,198 @@ +# Travel optimization — High Level Design + +## Purpose and scope + +Inside an island, the infill paths of each region are chained into one print +order by a greedy pass that joins the closest free path ends first. That pass +leaves its longest joins for last, and they often cross the whole island. Two +things shorten the travel between infill paths: + +- the fill generators join their lines into as few paths as they can, since + every separate path needs a travel to it; +- the G-code export refines the greedy chain with a local search that shortens + the straight-line travel between the paths. + +The refinement covers every chain that `chain_and_reorder_extrusion_entities()` +builds from a start point: the infill and ironing of `GCode::extrude_infill()` +and the support of `GCode::extrude_support()`, as well as the order of objects +and islands under `print_order` Default. It changes only the order and the +direction of the paths, not the paths or the walls. Neither part has a setting. + +## The chain + +`ObjectByExtruder::Island::Region::append()` flattens every sortable fill +collection into its paths, so the paths of all the fills of a region in one +island are chained together. A collection that must keep its order (`no_sort`: +monotonic, concentric, a forced fill order, the flow calibration) stays a single +entry that cannot be reversed. Paths that must keep their direction cannot be +reversed either: Grid's, since it alternates their direction between layers for +strength, and those of a fill with a forced order. A loop starts and ends at the +same point, so reversing it changes nothing. + +`extrude_infill()` chains each region from the current nozzle position with +`chain_and_reorder_extrusion_entities()`, and chains the paths inside a nested +sortable collection the same way; `extrude_support()` chains the support paths +of a layer so too, unless they keep their order. The overload without a start +point, used to chain collections while slicing, keeps the greedy chain. The +order the fill generators give their paths does not reach the G-code for a +sortable fill, which is chained again. + +## Connecting the lines + +Most patterns cut their lines at the infill boundary, and `Fill::connect_infill()` +joins pairs of line ends that are neighbors on a boundary contour by the arc of +wall between them, shortest arcs first, as long as neither end is joined yet and +the join closes no loop. An arc is joined when it is shorter than +`infill_anchor_max`, or than two anchors and a line width if that is longer: +two ends further apart each get an anchor toward the other, and where those +would meet, the join prints about as much wall as one path instead of two. + +Regular patterns leave many arcs of the same length, and the order among them +decides the pairing. In an arbitrary order the pairs along one wall can fall out +of step, such as lines 1–2 and 3–4, then 6–7 and 8–9, which leaves the end of +line 5 loose, and every loose end starts or ends a separate path. So the arcs +are also sorted in steps of half the line spacing and, within a step, along each +contour forwards and backwards, which pairs the ends of a wall in one phase. +Each order is replayed on the flags and a union-find of the lines, without +building any path, and the one that joins the most lines is used; a tie keeps +the shortest-first order. + +The replay includes the last pass, which joins any two open ends that are +neighbors on a contour. With multiline infill the main pass leaves the copies of +one line to that pass, so that each copy reaches a wall of its own. Two +neighboring groups cut at both walls can then be joined at either wall by arcs +of the same length: at one, their open ends stay next to their own copies, which +the last pass joins, so each line prints out and back; at the other, the copies +end up in separate paths printed apart. + +A line end left unpaired gets an anchor, a piece of the wall at most +`infill_anchor` long. It runs toward the nearest open end of another path, +looking up to 64 ends along the contour, since the next path usually starts +there; without one it takes the side with more free wall. With multiline infill +an anchor toward a copy of the same line stops short of the copy rather than +printing over it. A copy is a neighboring end less than the group width +(`multiline` spacings) across the line, at any wall angle, while the next group +lies a whole line spacing away. Meeting the wall at an angle θ, the copy covers +half a width over sin θ of the wall on each side of its end, so the anchor stops +that far and half its own width before it, or is left out; the end still counts +as anchored, so the last pass pairs the other ends as before. + +Last, `Fill::fill_surface_extrusion()` joins the sparse infill lines whose ends +are at most two line spacings apart with a straight piece. With the anchors off +(`infill_anchor_max` 0) nothing above runs and this is the only joining; with +them on, it takes what the steps above leave next to each other, such as two +anchors that stop just short of each other or a short piece cut off by a corner. +A gap that short leaves no room to print anything in between, and as a travel it +is the one hop a reordering can trade for a longer travel that retracts. +Multiline copies leave the most such ends: one spacing apart across the line, +their ends where it meets a wall at an angle θ are one spacing over sin θ apart +along it, so two spacings reach walls met at 30° and steeper. + +Ends that meet are joined first, then the gaps between the leading ends of their +lines, along each line's overall direction, then the rest, shortest first within +each, without closing a loop or crossing a line or another join. Taking the +leading ends first joins every pair of copies at the same side, which leaves +their open ends next to each other; by length alone, neighboring pairs were +joined at different walls and the travel between them crossed the island. Lines +that cannot reverse, such as Grid's, only join the end of one to the start of the +next, and fills that keep their order are left alone. + +## The search + +A chain of up to eight paths is found exactly, by dynamic programming over the +subsets of paths: a state is the paths visited so far, the last one and its +direction, about four thousand states for eight paths. The shared greedy +chaining, `chain_segments_greedy_constrained_reversals_()`, does the same for two +to four segments, which also orders up to four islands of a layer and the loops +of a perimeter collection exactly. Either way the first path is no longer +always the one nearest the start; with a free end, a path near the start can be +worth leaving for last. + +Objects (`print_order` Default) and the tour of islands across objects are +visited in the same order on every layer, so `chain_points_with_postprocessing()` +orders them as a closed tour rather than an open chain. Up to ten points the +shortest tour is found exactly by the same dynamic programming with the first +point fixed; with a start point the tour then begins at the point nearest it. +Larger sets take the greedy chain and alternate 2-opt, or-opt and crossing +removal; or-opt moves runs of up to three points next to one of the eight points +nearest an end of the run, found on the same grid as the chain's candidates. + +For longer chains, the search refines the greedy chain. On an island cut into many short pieces, +such as infill without anchors, that chain can sweep away from the nozzle and +come back for the rest with one long jump, which no local move below removes. +So a nearest-next chain, going from the nozzle to the nearest free path end each +time, is built too; when it is already shorter than the refined greedy chain, it +is refined and used instead. Elsewhere it costs one grid query per path. + +`improve_chain_by_local_search()` sees the chain as a sequence of segments with +an entry and an exit point each. Its cost is the straight distance from the +nozzle to the first entry plus the distance from every exit to the next entry; +the end of the chain is free. It applies three kinds of moves: + +- 2-opt reverses a run of segments, which flips each of them and replaces the + two links at the ends of the run. +- Or-opt moves a run of up to three segments between two others, flipped or + not. +- A run of any length that starts or ends next to the nozzle moves to the front. + Local search can settle on a chain that starts with a block of paths far from + the nozzle while the paths next to it sit in the middle, and moving that block + takes more than three segments at once. + +A move that would flip a segment that cannot be reversed is skipped, so such +segments are only reordered. + +A move is tried only if every link it creates joins an end point to one of the +32 end points nearest to it, which covers every move on a chain of up to 17 +segments, as most islands are; with 8 candidates the search missed most of the +gain on grid-like patterns such as Triangles. The candidates come from a uniform +grid of about two end points per cell, searched in rings of cells around the +query. `KDTreeIndirect` visits its subtrees in a fixed order rather than the +nearer one first, so a query for 32 points walks most of the tree, and on long +chains finding the candidates would cost more than the search itself. + +The candidates of an end point are tried nearest first, and only while they are +closer to it than the link the move would replace there. A 2-opt move that pays +off creates a link shorter than the one it replaces at one of its two ends, so +this misses no 2-opt move. An or-opt move is tried only while its new link is +shorter than what taking the run out saves, which skips a few or-opt moves that +would still pay off but cuts the search on long chains to a fraction. + +The search works through a queue of segments and applies the first move that +shortens the chain around the segment it examines. After a move, only the +segments next to a changed link are queued again. A new link can also make room +for a run elsewhere that no segment next to it would try, so when the queue +empties after any move, every segment is queued once more, and the search ends +when such a sweep finds no move. + +Every move shortens the chain by more than `SCALED_EPSILON`, so the result is +never longer than the greedy or the nearest-next chain and the search ends; a +cap of 50 moves per segment only bounds its time. The search has no randomness +and visits the segments in a fixed order, so the same input always gives the +same G-code. + +## Cost + +Finding the candidates of an end point visits a few cells, and the nearest-next +chain makes one such query per path, which only grows where the paths around the +nozzle are used up and the chain jumps. Examining a segment tries at most a few +hundred candidate links, usually only the nearest few, plus a scan of the chain +for the move to the front when it is the first segment, and a move rewrites only +the range of the chain it changes, so the search stays close to linear in the +number of segments. Most islands hold a few to a few dozen paths; the cost shows +on infill cut into thousands of pieces per island, such as dense infill with the +anchors off. The straight joins only look at the line segments near a candidate +join for crossings. + +## Limitations + +The search minimizes straight-line distance. It does not know which travels +leave the infill area and retract under `reduce_infill_retraction`, nor the +detours of `reduce_crossing_wall`, and a travel's time is not proportional to +its length: a short travel is bound by acceleration, so its time grows about +with the square root of its length. A chain that is shorter in total but trades +very short travels for longer ones, or for ones past `retraction_minimum_travel`, +can occasionally take a little longer to print. + +The end of the chain is free: it is not steered toward the next island or the +start of the next layer. The regions of an island are chained one after the +other, in region order, each from where the previous one ended. diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot index 1fbe90b60c..aa12e329b2 100644 --- a/localization/i18n/OrcaSlicer.pot +++ b/localization/i18n/OrcaSlicer.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1637,16 +1637,16 @@ msgstr "" msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "" -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "" msgid "No embossed file" msgstr "" -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "" -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "" msgid "Face the camera" @@ -4579,7 +4579,7 @@ msgstr "" msgid "Unknown C++ exception." msgstr "" -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "" msgid "Slicing complete" @@ -6049,7 +6049,7 @@ msgstr "" msgid "Size:" msgstr "" -#, possible-boost-format +#, possible-c-format, possible-boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "" @@ -12318,7 +12318,7 @@ msgstr "" msgid "Left mouse" msgstr "" -msgid "Available anywhere in the window, even while typing in a text field." +msgid "Available anywhere in the window." msgstr "" msgid "Run favorite 1 to 10" @@ -12415,9 +12415,6 @@ msgstr "" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "" -msgid "Global shortcuts also apply while typing." -msgstr "" - msgid "A key that types a character cannot be a global shortcut." msgstr "" @@ -15648,6 +15645,12 @@ msgstr "" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "" +msgid "Outline tolerance" +msgstr "" + +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "" + msgid "Verbose G-code" msgstr "" @@ -20543,7 +20546,7 @@ msgid "test %s start..." msgstr "" #, possible-c-format, possible-boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "" #, possible-c-format, possible-boost-format @@ -26495,17 +26498,18 @@ msgstr "" msgid "Basic Colors" msgstr "" +#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. msgid "Orca Palette" msgstr "" -#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. +#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "RAL Classic" msgstr "" -#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "Gradients" msgstr "" +msgctxt "Color picker" msgid "Solid" msgstr "" @@ -26880,7 +26884,7 @@ msgstr "" msgid "Medium violet red" msgstr "" -msgid "PaleV violet red" +msgid "Pale violet red" msgstr "" msgid "Deep pink" @@ -27042,7 +27046,7 @@ msgstr "" msgid "Shallow sky" msgstr "" -msgid "Electric bel" +msgid "Electric blue" msgstr "" msgid "Dolphin" @@ -27111,7 +27115,7 @@ msgstr "" msgid "Maize yellow" msgstr "" -msgid "Dalmatian yellow" +msgid "Daffodil yellow" msgstr "" msgid "Brown beige" @@ -27372,7 +27376,7 @@ msgstr "" msgid "Turquoise blue" msgstr "" -msgid "Capsanthin violet" +msgid "Capri blue" msgstr "" msgid "Ocean blue" @@ -27486,7 +27490,7 @@ msgstr "" msgid "Silver grey" msgstr "" -msgid "Olivestone" +msgid "Olive grey" msgstr "" msgid "Moss grey" @@ -28074,10 +28078,19 @@ msgstr "" msgid "Built-in" msgstr "" +msgid "My textures" +msgstr "" + msgid "No textures found." msgstr "" -msgid "My textures" +msgid "Texture libraries" +msgstr "" + +msgid "Explore more texture libraries" +msgstr "" + +msgid "Opens OrcaCloud in the Home page to browse for plugins." msgstr "" msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -30130,6 +30143,9 @@ msgstr "" msgid "Slicing Pipeline" msgstr "" +msgid "Resource Texture" +msgstr "" + msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "" @@ -30245,6 +30261,24 @@ msgstr "" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "" +msgid "Resource texture directory is not set" +msgstr "" + +msgid "Resource texture directory could not be resolved" +msgstr "" + +msgid "Resource texture path is not a directory" +msgstr "" + +msgid "Plugin folder could not be resolved" +msgstr "" + +msgid "Resource texture directory is outside the plugin folder" +msgstr "" + +msgid "Resource texture directory could not be read" +msgstr "" + #, possible-boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" msgstr "" @@ -30601,7 +30635,7 @@ msgstr "" #. TRN %1% is the application name. #, possible-boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "" #. TRN %1% is a tag in the G-code file that must not be translated. @@ -30689,7 +30723,7 @@ msgstr "" msgid "Failed making a temporary copy of G-code file %1% before running a post-processing script: %2%" msgstr "" -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "" #, possible-boost-format diff --git a/localization/i18n/ca/OrcaSlicer_ca.po b/localization/i18n/ca/OrcaSlicer_ca.po index 879d094a63..72efab0527 100644 --- a/localization/i18n/ca/OrcaSlicer_ca.po +++ b/localization/i18n/ca/OrcaSlicer_ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2025-03-15 10:55+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -819,18 +819,22 @@ msgstr "Selecció" msgid "Plate" msgstr "Safata" +# AI Translated +# Needs human review: Glossary has no Catalan rendering; Distribuir chosen as the counterpart of Alinear (command that spaces objects evenly). msgid "Distribute" -msgstr "" +msgstr "Distribuir" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Sistema de coordenades utilitzat per a les accions de transformació." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Referència per a l'alineació" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Seleccioneu almenys 3 peces o objectes" # AI Translated msgid "Align left" @@ -883,8 +887,9 @@ msgstr "Distribuir dalt-baix" msgid "Drop" msgstr "Deixar anar" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Moveu la selecció al llarg de Z perquè el seu punt més baix toqui el llit." # AI Translated msgid "Absolute" @@ -1789,7 +1794,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Traç de forma ( %1% ) conté elements no compatibles: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Estat no vàlid; informeu dels passos per reproduir-lo a GitHub" # AI Translated @@ -1797,11 +1802,11 @@ msgid "No embossed file" msgstr "No hi ha cap fitxer en relleu" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Falta el fitxer SVG a la forma en relleu" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Falten les dades del fitxer SVG" msgid "Face the camera" @@ -2127,17 +2132,21 @@ msgstr "Entrant al gizmo d'Ensamblatge" msgid "Leaving Assembly gizmo" msgstr "Sortint del gizmo d'Ensamblatge" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Les peces d'un objecte tallat no es poden moure" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "L'alineació amb la placa només està disponible en X i Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Desactiveu la Caiguda automàtica dels objectes seleccionats per moure'ls en Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Tots els objectes seleccionats han d'estar a la mateixa placa" msgid "Shift+" msgstr "Màj+" @@ -5053,7 +5062,7 @@ msgstr "Deseu el projecte i reinicieu el programa." msgid "Unknown C++ exception." msgstr "Excepció de C++ desconeguda." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Processant el G-code del fitxer anterior..." msgid "Slicing complete" @@ -6599,8 +6608,10 @@ msgstr "Eixos" msgid "Gridlines" msgstr "Línies de la graella" +# AI Translated +# Needs human review: Glossary has no Catalan rendering for Focus mode (hides the UI to concentrate on the 3D canvas); check the wording. msgid "Focus mode" -msgstr "" +msgstr "Mode de concentració" msgid "Labels" msgstr "Etiquetes" @@ -6662,7 +6673,7 @@ msgid "Size:" msgstr "Mida:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "S'han trobat conflictes de rutes de G-code a la capa %d, Z = %.2lfmm. Si us plau, separeu els objectes conflictius més lluny ( %s <-> %s )." @@ -11040,11 +11051,13 @@ msgstr "Mostrar els perfils no compatibles" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Mostra els perfils incompatibles o no compatibles a les llistes desplegables d'impressora i de filament. Aquests perfils no es poden seleccionar." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Exportar estadístiques amb el G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Si està activat, en exportar un fitxer de G-code també s'escriuen les seves estadístiques en JSON al costat, com a .statistics.json, i un fitxer 3MF laminat exportat les conté a dins: temps d'impressió, totals de filament i per tipus de línia, i el mateix per capa i per objecte." # AI Translated msgid "Experimental Features" @@ -11909,6 +11922,10 @@ msgstr "No s'ha pogut pujar el fitxer a l'emmagatzematge de la impressora. Torne msgid "Send Failed" msgstr "L'enviament ha fallat" +# AI Translated +msgid "No available printers" +msgstr "No hi ha impressores disponibles" + msgid "The name length exceeds the limit." msgstr "La longitud del nom supera el límit." @@ -13770,8 +13787,8 @@ msgid "Left mouse" msgstr "Botó esquerre del ratolí" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Disponible a qualsevol lloc de la finestra, fins i tot mentre s'escriu en un camp de text." +msgid "Available anywhere in the window." +msgstr "Disponible a qualsevol lloc de la finestra." # AI Translated msgid "Run favorite 1 to 10" @@ -13884,10 +13901,6 @@ msgstr "La drecera %s està assignada a %s. Voleu reassignar-la a %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "La drecera predeterminada %s està assignada a %s. Voleu reassignar-la a %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Les dreceres globals també s'apliquen mentre s'escriu." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Una tecla que escriu un caràcter no pot ser una drecera global." @@ -14341,9 +14354,10 @@ msgstr "el modificador \"%1%\" de \"%2%\" (%3% en total) no ha tingut cap efecte msgid "Seam placement may differ from expected." msgstr "La posició de la costura pot ser diferent de l'esperada." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "No s'han pogut escriure les estadístiques del G-code a %1%." msgid "Internal Bridge" msgstr "Pont Interior" @@ -17796,6 +17810,14 @@ msgstr "Excloure objectes" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Activeu aquesta opció per afegir l'ordre EXCLUDE OBJECT al G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Tolerància del contorn" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Desviació màxima del contorn de l'objecte escrit a EXCLUDE_OBJECT_DEFINE respecte del contorn original. Els valors més grans donen menys punts, cosa que ajuda el firmware que es bloqueja en analitzar G-code amb molts objectes. 0 conserva tots els punts." + msgid "Verbose G-code" msgstr "G-code detallat" @@ -21063,11 +21085,13 @@ msgstr "Directori de sortida" msgid "This is the output directory for exported files." msgstr "Directori de sortida dels fitxers exportats." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Exportar estadístiques" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Escriu les estadístiques de cada placa laminada en JSON, com a plate_N.statistics.json al costat del seu G-code al directori de sortida i dins del 3MF de --export-3mf: temps d'impressió, totals de filament i per tipus de línia, i el mateix per capa i per objecte." msgid "Debug level" msgstr "Nivell de depuració" @@ -23505,7 +23529,7 @@ msgstr "Inici de la prova de %s..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "Prova de %s: IP resolta = %s" # AI Translated @@ -31003,1231 +31027,1646 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "La llista de filaments actual no conté %s. Després de la descomposició es crearà automàticament un filament de projecte que necessita el filament mixt." msgstr[1] "La llista de filaments actual no conté %s. Després de la descomposició es crearan automàticament els filaments de projecte que necessita el filament mixt." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Selector de color" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Colors bàsics" +# AI Translated #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Paleta Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Clàssic" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Gradients" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Sòlid" +# AI Translated +# Needs human review: Glossary has no Catalan cell for Gradient; kept Gradient, matching the existing Gradient lineal/radial, while the mixed filament gradient uses Degradat. msgid "Gradient" -msgstr "" +msgstr "Gradient" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Inici del gradient" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Final del gradient" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Color del gradient" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Afegir color" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Eliminar color" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Saturació" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Color original" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Desar el color actual" +# AI Translated +# Needs human review: Glossary has no Catalan cell for Palette; Paleta chosen. msgid "Palettes" -msgstr "" +msgstr "Paletes" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Cercar colors" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtrar colors" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "No hi ha colors coincidents" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Color hexadecimal" # AI Translated msgid "Opacity" msgstr "Opacitat" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Percentatge d'opacitat" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Desar color" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Introduïu un color hexadecimal complet" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "La selecció multicolor actual es conserva fins que trieu un color diferent." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "S'admeten fins a %d colors." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Carmesí" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Vermell taronja" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Tomàquet" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Taronja" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Taronja fosc" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Or" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Fusta robusta" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Bisque" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Rosa boirós" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Groc clar" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Xifó de llimona" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beix" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Groc vara d'or clar" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Vara d'or pàl·lida" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Caqui" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Caqui fosc" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Préssec clar" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mocassí" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Nata de papaia" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Ametlla pelada" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Blanc antic" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Blanc navajo" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Blat" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Vara d'or" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Xocolata" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Perú" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Maó refractari" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Sienna" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Marró sella" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Marró" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Marró rosat" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Salmó" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Salmó clar" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Salmó fosc" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Marró sorra" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Corall" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Corall clar" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Vermell indi" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Vermell fosc" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Grana" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Verd groguenc" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Groc verdós" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Verd gespa" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Verd llima" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Verd primavera" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Verd primavera mitjà" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Llima" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Verd bosc" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Verd fosc" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Oliva apagat" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliva" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Verd oliva fosc" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Verd pàl·lid" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Verd clar" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Verd mar mitjà" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Verd mar" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Verd mar fosc" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Blau cadet" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Aiguamarina mitjana" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turquesa" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Turquesa mitjana" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Turquesa fosca" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Turquesa pàl·lida" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aigua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Cian clar" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Crema de menta" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Rosada de mel" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Aiguamarina" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Verd mar clar" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Cian fosc" +# AI Translated +# Needs human review: CSS teal (dark blue-green); check that Verd blavós fosc reads as a color name next to Blau verdós and Verd blavós. msgid "Teal" -msgstr "" +msgstr "Verd blavós fosc" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Gris pissarra fosc" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Gris pissarra clar" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Gris pissarra" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Blau cel intens" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Blau Dodger" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Blau cel" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Blau cel clar" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Blau clar" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Blau talc" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Blau acer clar" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Blau acer" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Blau blauet" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Blau reial" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Blau mitjà" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Blau mitjanit" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Blau fosc" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Blau marí" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Blau pissarra" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Blau pissarra fosc" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Blau pissarra mitjà" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Violeta blavós" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indi" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Violeta fosc" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Orquídia fosca" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Orquídia mitjana" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orquídia" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violeta" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Porpra mitjà" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Porpra" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Porpra Rebecca" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Vermell violeta mitjà" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Vermell violeta pàl·lid" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Rosa intens" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Rosa viu" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Rosa clar" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rosa" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Pruna" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Card" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fúcsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Magenta fosc" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lli" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Punta antiga" +# AI Translated +# Needs human review: CSS color 'seashell'; the Shell glossary match is a false positive. msgid "Sea shell" -msgstr "" +msgstr "Petxina" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Ivori" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Blanc floral" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavanda rosada" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Blanc fantasma" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Blau Alice" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavanda" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Blanc fum" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Negre" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Foc de corall" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Anemone de mar" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Abisme profund" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Vermell llamàntol" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Argila sorrenca" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Fusta de deriva" +# AI Translated +# Needs human review: Plant name (Hippophae); check the Catalan name and whether a color-only name reads better. msgid "Sea buckthorn" -msgstr "" +msgstr "Arç marí" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Escull de capvespre" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Corall tigre" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Corall rosa" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Resplendor de petxina" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Sorra" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Alga daurada" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Duna assolellada" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Nàutil ambre" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Llimona de mar" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Estrella de mar pàl·lida" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Marea viva" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Alga llima" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Herba marina" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Plàncton neó" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Bosc d'algues" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Onada esmeralda" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Ombra de balena" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Tortuga marina" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Llacuna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Corrent tropical" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Fossa de mitjanit" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Alga fosca" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Onatge de cristall" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Badia turquesa" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Cel sobre l'escull" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Cel somer" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Blau elèctric" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Dofí" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Profunditats de l'oceà" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Balena" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Abisme indi" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Eriçó de mar" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Corall lavanda" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Marea violeta" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Orquídia abissal" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Medusa neó" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Corall fúcsia" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Medusa rosa" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Escuma" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Blanc petxina" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Gris còdol" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Núvol de tempesta" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Negre tinta" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Beix verdós" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Groc sorra" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Groc de senyalització" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Groc daurat" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Groc mel" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Groc blat de moro" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Groc narcís" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Beix marronós" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Groc llimona" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Blanc ostra" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Ivori clar" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Groc de zinc" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Beix grisós" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Groc oliva" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Groc colza" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Groc trànsit" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Groc ocre" +# AI Translated +# Needs human review: Source name looks like a RAL variant; check the rendering. msgid "Traffic orange yellow" -msgstr "" +msgstr "Groc taronja trànsit" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curri" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Groc meló" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Groc ginesta" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Groc dàlia" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Groc pastel" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Beix perla" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Or perla" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Groc sol" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Taronja groguenc" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Taronja intens" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Vermelló" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Taronja perla" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Taronja pur" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Taronja lluminós" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Taronja lluminós brillant" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Taronja vermellós brillant" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Taronja trànsit" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Taronja de senyalització" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Taronja salmó" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Rosa perla" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Taronja coure" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Marró de senyalització" +# AI Translated +# Needs human review: RAL color name as given in the source; check the rendering. msgid "Fir orange" -msgstr "" +msgstr "Taronja avet" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Vermell de senyalització" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Vermell lluminós" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Vermell carmí" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Vermell carmí perla" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Vermell pur" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Vermell intens lluminós" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Vermell grosella" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Vermell rubí perla" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Vermell foc" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Vermell rubí" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Vermell porpra" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Vermell vi" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Vermell negrós" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Vermell òxid" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Vermell marronós" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Vermell pi" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Vermell tomàquet" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Rosa antic" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Vermell corall" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rosat" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Vermell maduixa" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Vermell trànsit" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Rosa salmó" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Rosa lluminós" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Vermell brillant lluminós" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Vermell gerd" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Vermell orient" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Rubí perla" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Porpra vermellós" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Violeta vermellós" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Violeta bruc" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Violeta bordeus" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Caoba" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Porpra grisós" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Violeta de senyalització" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Verd avet" +# AI Translated +# Needs human review: RAL color named after Sabine; check the rendering. msgid "Sabine grey" -msgstr "" +msgstr "Gris sabí" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Violeta perla" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Móra perla" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Blau verdós" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Blau ultramar" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Blau safir" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Blau negrós" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Blau de senyalització" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Blau brillant" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Blau grisós" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Blau atzur" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Blau genciana" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Blau cobalt" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Blau colom" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Blau trànsit" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Blau turquesa" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Blau Capri" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Blau oceà" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Blau aigua" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Blau nit" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Blau llunyà" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Blau pastel" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Blau genciana perla" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Blau mitjanit perla" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Verd pàtina" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Verd esmeralda" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Verd fulla" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Verd oliva" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Verd blavós" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Verd molsa" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Oliva grisós" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Verd pi" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Marró pi" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Verd herba" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Verd reseda" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Verd marronós" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Verd canya" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Verd negrós" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Verd turquesa" +# AI Translated msgid "May green" -msgstr "" +msgstr "Verd maig" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Verd òxid de crom" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Verd trànsit" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Verd falguera" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Verd òpal" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Verd menta" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Verd bronze" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Verd perla" +# AI Translated msgid "Sax turquoise" -msgstr "" +msgstr "Turquesa saxe" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Turquesa perla" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Jade perla" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Verd pur" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Verd lluminós" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Gris esquirol" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Gris plata" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Gris oliva" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Gris molsa" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Gris de senyalització" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Gris ratolí" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Gris beix" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Gris caqui" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Gris verdós" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Gris lona" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Gris ferro" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Gris basalt" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Gris marronós" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Gris pissarra" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Gris antracita" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Gris clar" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Gris ombra" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Gris formigó" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Gris grafit" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Gris granit" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Gris pedra" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Gris còdol" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Gris ciment" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Gris groguenc" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Gris platí" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Gris pols" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Gris àgata" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Gris quars" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Gris finestra" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Gris trànsit A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Gris trànsit B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Gris seda" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegris 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegris 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegris 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Gris ratolí perla" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Marró verdós" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Marró ocre" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Marró argila" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Marró coure" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Marró xocolata" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Marró oliva" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Marró nou" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Marró vermellós" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Marró sèpia" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Marró castanya" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Marró caoba" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Marró grisós" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Coure perla" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Marró beix" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Marró moca perla" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Marró terra" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Marró perla" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Crema" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Blanc grisós" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Blanc de senyalització" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Negre de senyalització" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Negre atzabeja" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Alumini blanc" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Alumini gris" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Blanc pur" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Negre grafit" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Blanc trànsit" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Negre trànsit" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Blanc papir" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Gris clar perla" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metall: Plata" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metall: Llautó" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metall: Or" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metall: Coure" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metall: Bronze" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Natura: Perla" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Natura: Arc de Sant Martí" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natura: Cel clar" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Natura: Posta de sol" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Fusta: Fosca" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Fusta: Mitjana" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Fusta: Clara" # AI Translated msgid "Alternate nozzles:" @@ -32703,13 +33142,25 @@ msgstr "Treure de Les meves textures" msgid "Built-in" msgstr "Integrades" +# AI Translated +msgid "My textures" +msgstr "Les meves textures" + # AI Translated msgid "No textures found." msgstr "No s'ha trobat cap textura." # AI Translated -msgid "My textures" -msgstr "Les meves textures" +msgid "Texture libraries" +msgstr "Biblioteques de textures" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Explorar més biblioteques de textures" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Obre OrcaCloud a la pàgina d'inici per cercar connectors." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33112,11 +33563,13 @@ msgstr "Mapat segons la disposició UV del propi model, que ja és la col·locac msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Amplada d'una còpia de la textura sobre el model. Un valor més petit repeteix el patró més sovint i en fa el detall més fi; amb Tessel·lat desactivat, és la mida de la còpia única." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Més gran" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Més petit" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33192,11 +33645,13 @@ msgstr "Colors mixtos" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "El nombre màxim de filaments mixtos que pot afegir una fixació. Es trien a partir dels colors de la textura, i només es creen els que la fixació fa servir realment." +# AI Translated msgid "Few" -msgstr "" +msgstr "Pocs" +# AI Translated msgid "Many" -msgstr "" +msgstr "Molts" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33552,11 +34007,13 @@ msgstr "Remallat" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Mida de triangle amb què es reconstrueix tot el model, en mil·límetres. El desplaçament funciona millor sobre una malla uniforme; això és el que en crea una a partir d'una importació irregular." +# AI Translated msgid "Before" -msgstr "" +msgstr "Abans" +# AI Translated msgid "After" -msgstr "" +msgstr "Després" # AI Translated msgid "Keep sharp edges" @@ -35417,6 +35874,10 @@ msgstr "Script" msgid "Slicing Pipeline" msgstr "Flux de laminat" +# AI Translated +msgid "Resource Texture" +msgstr "Textura de recurs" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "La interfície de configuració del connector era buida. Es mostra l'editor predeterminat." @@ -35564,6 +36025,30 @@ msgstr "El directori del connector conté fitxers d'entrada .py i .whl" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "El directori del connector no conté cap fitxer d'entrada .py ni .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "No s'ha definit el directori de textures de recurs" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "No s'ha pogut resoldre el directori de textures de recurs" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "La ruta de textures de recurs no és un directori" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "No s'ha pogut resoldre la carpeta del connector" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "El directori de textures de recurs és fora de la carpeta del connector" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "No s'ha pogut llegir el directori de textures de recurs" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36022,7 +36507,7 @@ msgstr "No s'ha pogut carregar el fitxer de configuració \"%1%\": %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "No és un fitxer G-code generat per %1%." # AI Translated @@ -36142,7 +36627,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "No s'ha pogut fer una còpia temporal del fitxer G-code %1% abans d'executar un script de postprocessament: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "El postprocessador no troba el fitxer G-code exportat" # AI Translated @@ -36511,6 +36996,27 @@ msgstr "" "Evitar la deformació( warping )\n" "Sabíeu que quan imprimiu materials propensos a deformar-se, com ara l'ABS, augmentar adequadament la temperatura del llit pot reduir la probabilitat de deformació?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Groc dàlmata" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Violeta capsantina" + +# AI Translated +# Needs human review: RAL color name; check the rendering. +#~ msgid "Olivestone" +#~ msgstr "Pedra d'oliva" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Disponible a qualsevol lloc de la finestra, fins i tot mentre s'escriu en un camp de text." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Les dreceres globals també s'apliquen mentre s'escriu." + #~ msgid "Please choose the filament color" #~ msgstr "Trieu el color del filament" @@ -36987,9 +37493,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "cap eina configurada" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "G-code Final en acabar tota la impressió" - #~ msgid "Maximum X speed" #~ msgstr "Velocitat màxima a l'eix X" @@ -37006,27 +37509,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Connector(s) de Python invocats a cada pas del flux de laminat per llegir i modificar dades intermèdies de laminat, incloent-hi un pas final de postprocessament del G-code. Recerca/experimental." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Quan està activat, el laminador genera G-code amb el contingut de la zona principal centrat a l'origen del llit (0,0). El firmware de la impressora s'encarrega de col·locar les còpies/miralls a la posició física de cada zona. Activeu-ho només en impressores el firmware de les quals aplica els seus propis desplaçaments de zona en mode de còpia/mirall (p. ex. el mode de duplicació IDEX de RepRapFirmware). No té cap efecte en mode Principal (Primary)." - # AI Translated # Needs human review: 'pem-inversion' is developer shorthand (inverting the physical extruder map); check the wording reads right. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Correspondència per placa que substitueix l'assignació dels capçals físics a les ranures de filament (començant per 1). Si és buida, s'utilitzen els valors per defecte de la inversió del pem." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Eix al voltant del qual es gira la malla abans de laminar. És la inclinació de la impressora de cinta: una rotació isomètrica (sense distorsió) que també determina la representació del llit i la inclinació de la gravetat dels suports, i que la transformació inversa del G-code desfà abans del cisallament/escala i la reassignació d'eixos del sistema de coordenades de la màquina. X és la inclinació típica del pòrtic (la cinta es desplaça al llarg de Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Ajust per a experts: estableix l'angle d'inclinació del sistema de coordenades de la màquina (cisallament/escala del G-code) independentment de l'angle de rotació previ al laminat. Quan està desactivat, la transformació del sistema de coordenades de la màquina es deriva de l'angle d'inclinació de la cinta, de manera que un sol angle controla les dues etapes. Activeu-ho només per compensar una màquina la inclinació física del pòrtic de la qual difereix de la rotació de laminat." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "La desviació màxima permesa en reduir la resolució per a l'ajustament 'Resolució màxima del perímetre'. Si l'augmenteu, la impressió serà menys precisa, però el G-Code serà més petit. La 'Desviació màxima del perímetre' limita la 'Resolució màxima del perímetre', de manera que, si totes dues entren en conflicte, preval la 'Desviació màxima del perímetre'." - #~ msgid " not in range " #~ msgstr " fora de rang " diff --git a/localization/i18n/cs/OrcaSlicer_cs.po b/localization/i18n/cs/OrcaSlicer_cs.po index c48b4716d6..6b6e2c91b4 100644 --- a/localization/i18n/cs/OrcaSlicer_cs.po +++ b/localization/i18n/cs/OrcaSlicer_cs.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: Jakub Hencl\n" "Language-Team: \n" @@ -791,18 +791,21 @@ msgstr "Výběr" msgid "Plate" msgstr "Deska" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "Rozmístit" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Souřadný systém použitý pro transformační akce." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Reference zarovnání" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Vyberte alespoň 3 díly nebo objekty" # AI Translated msgid "Align left" @@ -855,8 +858,9 @@ msgstr "Rozmístit nahoře-dole" msgid "Drop" msgstr "Pustit" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Posune výběr podél osy Z tak, aby se jeho nejnižší bod dotýkal podložky." # AI Translated msgid "Absolute" @@ -1765,7 +1769,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Obrys tvaru (%1%) obsahuje nepodporované: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Neplatný stav, nahlaste prosím postup reprodukce na GitHubu" # AI Translated @@ -1773,11 +1777,11 @@ msgid "No embossed file" msgstr "Chybí soubor pro reliéf" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "V reliéfním tvaru chybí soubor SVG" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Chybí data souboru SVG" msgid "Face the camera" @@ -2103,17 +2107,22 @@ msgstr "Vstup do nástroje Sestava" msgid "Leaving Assembly gizmo" msgstr "Opustit nástroj Sestava" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Díly rozřezaného objektu nelze přesouvat" +# AI Translated +# Needs human review: 'Plate' here is the build plate (align to the bed), so 'podložka' was used. msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Zarovnání k podložce je možné pouze v osách X a Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Vypněte automatické položení pro vybrané objekty, abyste je mohli posouvat v ose Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Všechny vybrané objekty musí být na stejné desce" msgid "Shift+" msgstr "Shift+" @@ -5022,7 +5031,7 @@ msgstr "Uložte prosím projekt a restartujte program." msgid "Unknown C++ exception." msgstr "Neznámá výjimka C++." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Zpracovávání G-code z předchozího souboru..." msgid "Slicing complete" @@ -6580,8 +6589,9 @@ msgstr "Osy" msgid "Gridlines" msgstr "Mřížka" +# AI Translated msgid "Focus mode" -msgstr "" +msgstr "Režim soustředění" msgid "Labels" msgstr "Popisky" @@ -6643,7 +6653,7 @@ msgid "Size:" msgstr "Velikost:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Byly nalezeny konflikty drah G-code ve vrstvě %d, Z = %.2lf mm. Oddělte prosím konfliktní objekty více od sebe (%s <-> %s)." @@ -11021,11 +11031,14 @@ msgstr "Zobrazit nepodporované předvolby" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Zobrazovat nekompatibilní/nepodporované předvolby v rozevíracích seznamech tiskáren a filamentů. Tyto předvolby nelze vybrat." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Exportovat statistiky spolu s G-code" +# AI Translated +# Needs human review: 'feature totals' = totals per extrusion feature type; check the wording. msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Je-li zapnuto, export souboru G-code zapíše jeho statistiky také jako JSON vedle něj, jako .statistics.json, a exportovaný slicovaný soubor 3MF je obsahuje uvnitř: čas tisku, součty filamentu a typů čar a totéž po vrstvách a po objektech." # AI Translated msgid "Experimental Features" @@ -11892,6 +11905,10 @@ msgstr "Nahrání souboru do úložiště tiskárny selhalo. Zkuste to prosím z msgid "Send Failed" msgstr "Odeslání selhalo" +# AI Translated +msgid "No available printers" +msgstr "Žádné dostupné tiskárny" + msgid "The name length exceeds the limit." msgstr "Délka názvu překračuje limit." @@ -13792,8 +13809,8 @@ msgid "Left mouse" msgstr "Levé tlačítko myši" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Dostupné kdekoli v okně, i při psaní do textového pole." +msgid "Available anywhere in the window." +msgstr "Dostupné kdekoli v okně." # AI Translated msgid "Run favorite 1 to 10" @@ -13905,10 +13922,6 @@ msgstr "Zkratka %s je přiřazena k %s. Přiřadit ji místo toho k %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Výchozí zkratka %s je přiřazena k %s. Přiřadit ji místo toho k %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Globální zkratky platí i při psaní." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Klávesa, která píše znak, nemůže být globální zkratkou." @@ -14362,9 +14375,10 @@ msgstr "modifikátor „%1%“ objektu „%2%“ (celkem %3%) neměl na šev ž msgid "Seam placement may differ from expected." msgstr "Umístění švu se může lišit od očekávaného." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Statistiky G-code se nepodařilo zapsat do %1%." msgid "Internal Bridge" msgstr "Vnitřní most" @@ -17781,6 +17795,14 @@ msgstr "Vyloučit objekty" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Povolte tuto volbu pro přidání příkazu EXCLUDE OBJECT do G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Tolerance obrysu" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Maximální odchylka obrysu objektu zapsaného do EXCLUDE_OBJECT_DEFINE od původního obrysu. Vyšší hodnoty dávají méně bodů, což pomáhá firmwaru, který se při zpracování G-code s mnoha objekty zasekává. 0 zachová každý bod." + msgid "Verbose G-code" msgstr "Podrobný G-code" @@ -21022,11 +21044,14 @@ msgstr "Výstupní adresář" msgid "This is the output directory for exported files." msgstr "Výstupní adresář pro exportované soubory." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Exportovat statistiky" +# AI Translated +# Needs human review: 'feature totals' = totals per extrusion feature type; check the wording. msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Zapíše statistiky každé slicované desky jako JSON, jako plate_N.statistics.json vedle jejího G-code ve výstupním adresáři a uvnitř 3MF z --export-3mf: čas tisku, součty filamentu a typů čar a totéž po vrstvách a po objektech." msgid "Debug level" msgstr "Úroveň ladění" @@ -23454,7 +23479,7 @@ msgstr "test %s spuštěn..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "test %s: IP adresa přeložena = %s" # AI Translated @@ -31045,1231 +31070,1647 @@ msgstr[0] "Aktuální seznam filamentů neobsahuje %s. Filament projektu, který msgstr[1] "Aktuální seznam filamentů neobsahuje %s. Filamenty projektu, které míchaný filament vyžaduje, budou po rozkladu vytvořeny automaticky." msgstr[2] "Aktuální seznam filamentů neobsahuje %s. Filamenty projektu, které míchaný filament vyžaduje, budou po rozkladu vytvořeny automaticky." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Výběr barvy" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Základní barvy" +# AI Translated #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Paleta Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Classic" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Gradienty" +# AI Translated +# Needs human review: Color picker tab: single solid color as opposed to a gradient; check it reads right next to 'Gradients'. +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Jednobarevné" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Gradient" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Začátek gradientu" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Konec gradientu" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Barva gradientu" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Přidat barvu" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Odebrat barvu" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Sytost" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Původní barva" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Uložit aktuální barvu" +# AI Translated msgid "Palettes" -msgstr "" +msgstr "Palety" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Hledat barvy" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtrovat barvy" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Žádné odpovídající barvy" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Barva hex" # AI Translated msgid "Opacity" msgstr "Neprůhlednost" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Neprůhlednost v procentech" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Uložit barvu" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Zadejte úplnou hexadecimální barvu" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Aktuální výběr více barev zůstane zachován, dokud nevyberete jinou barvu." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Podporováno je nejvýše %d barev." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmínová" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Oranžovočervená" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Rajčatová" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Oranžová" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Tmavě oranžová" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Zlatá" +# AI Translated +# Needs human review: CSS color name; 'Dřevitá' is a free rendering. msgid "Burly wood" -msgstr "" +msgstr "Dřevitá" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Krémově růžová" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Mlžná růžová" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Světle žlutá" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Citronový šifón" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Béžová" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Světle zlatobýlově žlutá" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Bledě zlatobýlová" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Khaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Tmavě khaki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Broskvový krém" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mokasínová" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papájový krém" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Bledá mandlová" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antická bílá" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navajská bílá" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Pšeničná" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Zlatobýlová" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Čokoládová" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Cihlová" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Sedlová hnědá" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Hnědá" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Růžovohnědá" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Lososová" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Světle lososová" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Tmavě lososová" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Písčitě hnědá" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Korálová" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Světle korálová" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Indická červená" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Tmavě červená" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Kaštanová" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Zelenožlutá" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Žlutozelená" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Trávníková zelená" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Limetkově zelená" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Jarní zelená" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Středně jarní zelená" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Limetková" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Lesní zelená" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Tmavě zelená" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Armádní olivová" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Olivová" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Tmavě olivově zelená" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Bledě zelená" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Světle zelená" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Středně mořská zelená" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Mořská zelená" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Tmavě mořská zelená" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Kadetská modrá" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Středně akvamarínová" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Tyrkysová" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Středně tyrkysová" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Tmavě tyrkysová" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Bledě tyrkysová" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Světle azurová" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Mátový krém" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Medová rosa" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Akvamarínová" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Světle mořská zelená" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Tmavě azurová" +# AI Translated +# Needs human review: CSS color kept in English because no distinct Czech name exists apart from 'Modrozelená' (Blue green); check. msgid "Teal" -msgstr "" +msgstr "Teal" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Tmavě břidlicově šedá" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Světle břidlicově šedá" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Břidlicově šedá" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Sytě nebesky modrá" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodgerská modrá" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Nebesky modrá" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Světle nebesky modrá" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Světle modrá" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Pudrově modrá" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Světle ocelově modrá" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Ocelově modrá" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Chrpově modrá" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Královská modrá" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Středně modrá" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Půlnočně modrá" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Tmavě modrá" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Námořnická modrá" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Břidlicově modrá" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Tmavě břidlicově modrá" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Středně břidlicově modrá" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Modrofialová" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Tmavě fialová" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Tmavě orchidejová" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Středně orchidejová" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidejová" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Fialová" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Středně purpurová" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Purpurová" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebeccina purpurová" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Středně fialovočervená" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Bledě fialovočervená" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Sytě růžová" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Pronikavě růžová" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Světle růžová" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Růžová" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Švestková" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Bodláková" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuchsiová" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Tmavě magentová" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lněná" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Stará krajka" +# AI Translated +# Needs human review: CSS color Seashell; the glossary Shell term does not apply (false match). msgid "Sea shell" -msgstr "" +msgstr "Mušlová" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Slonovinová" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Květinová bílá" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Levandulově růžová" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Přízračně bílá" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Aliciina modrá" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Levandulová" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Kouřově bílá" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Černá" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Korálový oheň" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Mořská sasanka" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Hluboká propast" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Humří červená" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Písčitá hlína" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Naplavené dřevo" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Rakytník" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Útes při západu slunce" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tygří korál" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Růžový korál" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Záře mušle" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Písek" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Zlatá chaluha" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Duna ve slunci" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Jantarový nautilus" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Mořský citron" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Bledá hvězdice" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Jarní příliv" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Limetkové řasy" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Mořská tráva" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neonový plankton" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Les chaluh" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Smaragdová vlna" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Stín velryby" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Mořská želva" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Laguna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Tropický proud" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Půlnoční příkop" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Tmavá chaluha" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Křišťálový příboj" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Tyrkysová zátoka" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Obloha nad útesem" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Mělká obloha" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektrická modrá" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfín" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Hlubiny oceánu" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Velryba" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indigová propast" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Mořský ježek" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Levandulový korál" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Fialový příliv" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Hlubokomořská orchidej" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neonová medúza" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuchsiový korál" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Růžová medúza" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Pěna" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Mušlově bílá" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Oblázkově šedá" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Bouřkový mrak" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Inkoustově černá" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Zelenobéžová" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Písková žlutá" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Signální žlutá" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Zlatožlutá" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Medově žlutá" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Kukuřičně žlutá" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Narcisově žlutá" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Hnědobéžová" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Citronově žlutá" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Ústřicově bílá" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Světle slonovinová" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Zinkově žlutá" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Šedobéžová" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Olivově žlutá" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Řepkově žlutá" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Dopravní žlutá" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Okrově žlutá" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Dopravní oranžovožlutá" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Kari" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Melounově žlutá" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Janovcově žlutá" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Jiřinkově žlutá" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pastelově žlutá" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Perleťově béžová" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Perleťově zlatá" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Slunečně žlutá" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Žlutooranžová" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Sytě oranžová" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Rumělková" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Perleťově oranžová" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Čistě oranžová" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Zářivě oranžová" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Zářivě jasně oranžová" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Jasně červenooranžová" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Dopravní oranžová" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Signální oranžová" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Lososově oranžová" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Perleťově růžová" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Měděně oranžová" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Signální hnědá" +# AI Translated +# Needs human review: RAL color name, probably a typo of the source; rendering follows the English literally. msgid "Fir orange" -msgstr "" +msgstr "Jedlově oranžová" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Signální červená" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Zářivě červená" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karmínově červená" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Perleťově karmínově červená" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Čistě červená" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Zářivě sytě červená" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Rybízově červená" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Perleťově rubínově červená" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Ohnivě červená" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rubínově červená" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Purpurově červená" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Vínově červená" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Černočervená" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oxidově červená" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Hnědočervená" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Borovicově červená" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Rajčatově červená" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Starorůžová" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Korálově červená" +# AI Translated +# Needs human review: RAL color name; 'Rosé' is kept as a loan word. msgid "Rose" -msgstr "" +msgstr "Rosé" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Jahodově červená" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Dopravní červená" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Lososově růžová" +# AI Translated +# Needs human review: RAL color name; 'Rosé' is kept as a loan word. msgid "Luminous rose" -msgstr "" +msgstr "Zářivě rosé" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Zářivě jasně červená" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Malinově červená" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Orientální červená" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Perleťový rubín" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Červenopurpurová" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Červenofialová" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Vřesově fialová" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordeaux fialová" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Mahagonová" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Šedopurpurová" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Signální fialová" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Jedlově zelená" +# AI Translated +# Needs human review: RAL color name; check. msgid "Sabine grey" -msgstr "" +msgstr "Sabinská šedá" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Perleťově fialová" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Perleťově ostružinová" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Zelenomodrá" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarínově modrá" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Safírově modrá" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Černomodrá" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Signální modrá" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Brilantní modrá" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Šedomodrá" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azurově modrá" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Hořcově modrá" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobaltově modrá" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Holubí modrá" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Dopravní modrá" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Tyrkysově modrá" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Capri modrá" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Oceánově modrá" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Vodově modrá" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Noční modrá" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Vzdálená modrá" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pastelově modrá" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Perleťově hořcově modrá" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Perleťově půlnočně modrá" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patinově zelená" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Smaragdově zelená" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Listově zelená" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Olivově zelená" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Modrozelená" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Mechově zelená" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Šedoolivová" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Borovicově zelená" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Borovicově hnědá" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Trávově zelená" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Rezedově zelená" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Hnědozelená" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Rákosově zelená" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Černozelená" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Tyrkysově zelená" +# AI Translated msgid "May green" -msgstr "" +msgstr "Májově zelená" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Chromoxidově zelená" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Dopravní zelená" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Kapradinově zelená" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opálově zelená" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Mátově zelená" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Bronzově zelená" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Perleťově zelená" +# AI Translated +# Needs human review: RAL color name; 'Sax' may be Saxon or sax blue; check. msgid "Sax turquoise" -msgstr "" +msgstr "Saská tyrkysová" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Perleťově tyrkysová" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Perleťově nefritová" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Čistě zelená" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Zářivě zelená" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Veverčí šedá" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Stříbrně šedá" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Olivově šedá" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Mechově šedá" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Signální šedá" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Myší šedá" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Béžovošedá" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Khaki šedá" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Zelenošedá" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Plachtová šedá" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Železně šedá" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Čedičově šedá" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Hnědošedá" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Břidlicově šedá" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antracitově šedá" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Světle šedá" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umbrově šedá" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Betonově šedá" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafitově šedá" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Žulově šedá" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Kamenně šedá" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Oblázkově šedá" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Cementově šedá" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Žlutošedá" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platinově šedá" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Prašně šedá" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Achátově šedá" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Křemenně šedá" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Okenní šedá" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Dopravní šedá A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Dopravní šedá B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Hedvábně šedá" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telešedá 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telešedá 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telešedá 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Perleťově myší šedá" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Zelenohnědá" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Okrově hnědá" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Jílově hnědá" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Měděně hnědá" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Čokoládově hnědá" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Olivově hnědá" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Ořechově hnědá" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Červenohnědá" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sépiově hnědá" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Kaštanově hnědá" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Mahagonově hnědá" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Šedohnědá" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Perleťově měděná" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Béžovohnědá" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Perleťově mokka hnědá" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Zemitě hnědá" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Perleťově hnědá" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Krémová" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Šedobílá" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Signální bílá" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Signální černá" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Sytě černá" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Bílý hliník" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Šedý hliník" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Čistě bílá" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Grafitově černá" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Dopravní bílá" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Dopravní černá" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papyrově bílá" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Perleťově světle šedá" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Kov: Stříbro" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Kov: Mosaz" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Kov: Zlato" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Kov: Měď" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Kov: Bronz" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Příroda: Perleť" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Příroda: Duha" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Příroda: Jasná obloha" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Příroda: Západ slunce" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Dřevo: Tmavé" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Dřevo: Střední" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Dřevo: Světlé" # AI Translated msgid "Alternate nozzles:" @@ -32747,13 +33188,25 @@ msgstr "Odebrat z Mých textur" msgid "Built-in" msgstr "Vestavěné" +# AI Translated +msgid "My textures" +msgstr "Moje textury" + # AI Translated msgid "No textures found." msgstr "Nebyly nalezeny žádné textury." # AI Translated -msgid "My textures" -msgstr "Moje textury" +msgid "Texture libraries" +msgstr "Knihovny textur" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Prozkoumat další knihovny textur" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Otevře OrcaCloud na domovské stránce a umožní procházet pluginy." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33156,11 +33609,13 @@ msgstr "Mapováno podle vlastního rozložení UV modelu, které už je umístě msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Jak široká je jedna kopie textury na modelu. Menší hodnota opakuje vzor častěji a zjemňuje jeho detaily; při vypnutém Dláždění je to velikost jediné kopie." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Větší" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Menší" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33236,11 +33691,15 @@ msgstr "Míchané barvy" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Nejvyšší počet míchaných filamentů, které může zapečení přidat. Vybírají se z barev textury a vytvoří se pouze ty, které zapečení skutečně použije." +# AI Translated +# Needs human review: Label on the mixed-colors tip image (few vs many colors); check it reads right. msgid "Few" -msgstr "" +msgstr "Málo" +# AI Translated +# Needs human review: Label on the mixed-colors tip image (few vs many colors); check it reads right. msgid "Many" -msgstr "" +msgstr "Mnoho" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33601,11 +34060,13 @@ msgstr "Přesíťování" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Velikost trojúhelníků, se kterou se celý model znovu sestaví, v milimetrech. Reliéf funguje nejlépe na rovnoměrné síti; tímto ji vytvoříte z nerovnoměrného importu." +# AI Translated msgid "Before" -msgstr "" +msgstr "Před" +# AI Translated msgid "After" -msgstr "" +msgstr "Po" # AI Translated msgid "Keep sharp edges" @@ -35498,6 +35959,10 @@ msgstr "Skript" msgid "Slicing Pipeline" msgstr "Proces slicování" +# AI Translated +msgid "Resource Texture" +msgstr "Textura zdroje" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Konfigurační rozhraní pluginu bylo prázdné. Zobrazuje se výchozí editor." @@ -35645,6 +36110,30 @@ msgstr "Adresář pluginu obsahuje vstupní soubory .py i .whl" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Adresář pluginu neobsahuje vstupní soubor .py ani .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Adresář textury zdroje není nastaven" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Adresář textury zdroje se nepodařilo určit" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Cesta textury zdroje není adresář" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Složku pluginu se nepodařilo určit" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Adresář textury zdroje je mimo složku pluginu" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Adresář textury zdroje se nepodařilo přečíst" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36103,7 +36592,7 @@ msgstr "Načtení konfiguračního souboru „%1%“ se nezdařilo: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Nejedná se o soubor G-code vygenerovaný aplikací %1%." # AI Translated @@ -36223,7 +36712,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Před spuštěním post-processing skriptu se nepodařilo vytvořit dočasnou kopii G-code souboru %1%: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Post-processor nemůže najít exportovaný G-code soubor" # AI Translated @@ -36593,6 +37082,27 @@ msgstr "" "Zamezte kroucení\n" "Víte, že při tisku materiálů náchylných ke kroucení, jako je ABS, může vhodné zvýšení teploty vyhřívané desky snížit pravděpodobnost kroucení?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Dalmatská žlutá" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Kapsantinově fialová" + +# AI Translated +# Needs human review: RAL color name written as one word in the source; check. +#~ msgid "Olivestone" +#~ msgstr "Olivový kámen" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Dostupné kdekoli v okně, i při psaní do textového pole." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Globální zkratky platí i při psaní." + # AI Translated #~ msgid "Please choose the filament color" #~ msgstr "Vyberte prosím barvu filamentu" @@ -37074,9 +37584,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "žádném nakonfigurovaném nástroji" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Koncový G-code po dokončení celého tisku." - #~ msgid "Maximum X speed" #~ msgstr "Maximální rychlost osy X" @@ -37093,25 +37600,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Python pluginy volané v každém kroku slicovacího řetězce, které čtou a upravují mezivýsledky slicování, včetně závěrečného kroku postprocessingu G-code. Výzkumné/experimentální." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Je-li povoleno, slicer generuje G-code s obsahem primární zóny vystředěným na počátek podložky (0,0). Za umístění kopií a zrcadlených kopií na fyzickou pozici každé zóny odpovídá firmware tiskárny. Povolte pouze u tiskáren, jejichž firmware v režimu Kopie/Zrcadlo (Copy/Mirror) používá vlastní posuny zón (např. režim duplikace IDEX v RepRapFirmware). V režimu Primární nemá žádný účinek." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Přepsání pro jednotlivé desky, které mapuje fyzické hlavy na sloty filamentů (číslováno od 1). Prázdná hodnota znamená použití výchozích hodnot z inverze pem." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Osa, kolem které se síť před slicováním otočí. Jde o naklonění pásové tiskárny: izometrická rotace (bez zkreslení), která řídí také vykreslování podložky a naklonění gravitace pro podpory a kterou zpětná transformace G-code invertuje před zkosením/změnou měřítka v souřadnicovém systému stroje a přemapováním os. Obvyklé je naklonění portálu kolem osy X (pás se pohybuje podél Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Expertní přepsání: nastaví úhel naklonění souřadnicového systému stroje (zkosení/měřítko G-code) nezávisle na úhlu rotace před slicováním. Je-li vypnuto, transformace souřadnicového systému stroje se odvozuje z úhlu naklonění pásu, takže jediný úhel řídí obě fáze. Povolte pouze pro kompenzaci stroje, jehož fyzické naklonění portálu se liší od rotace při slicování." - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Maximální povolená odchylka při snižování rozlišení pro nastavení „Maximální rozlišení stěny“. Pokud tuto hodnotu zvýšíte, tisk bude méně přesný, ale G-code bude menší. „Maximální odchylka stěny“ omezuje „Maximální rozlišení stěny“, takže pokud jsou tato nastavení v konfliktu, má přednost „Maximální odchylka stěny“." - #~ msgid " not in range " #~ msgstr " není v rozsahu " diff --git a/localization/i18n/de/OrcaSlicer_de.po b/localization/i18n/de/OrcaSlicer_de.po index eb14366783..47f2917e80 100644 --- a/localization/i18n/de/OrcaSlicer_de.po +++ b/localization/i18n/de/OrcaSlicer_de.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: Heiko Liebscher \n" "Language-Team: \n" @@ -769,18 +769,22 @@ msgstr "Auswahl" msgid "Plate" msgstr "Platte" +# AI Translated +# Needs human review: Glossary has no German term yet; Verteilen matches the existing Ausrichten/Verteilen. msgid "Distribute" -msgstr "" +msgstr "Verteilen" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Koordinatensystem, das für Transformationsaktionen verwendet wird." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Referenz für die Ausrichtung" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Mindestens 3 Teile oder Objekte auswählen" # AI Translated msgid "Align left" @@ -833,8 +837,9 @@ msgstr "Oben-unten verteilen" msgid "Drop" msgstr "Ablegen" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Die Auswahl entlang Z verschieben, sodass ihr tiefster Punkt das Druckbett berührt." # AI Translated msgid "Absolute" @@ -1725,7 +1730,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Striche der Form (%1%) enthält nicht unterstützte: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Ungültiger Zustand – bitte melden Sie die Schritte zur Reproduktion auf GitHub" # AI Translated @@ -1733,11 +1738,11 @@ msgid "No embossed file" msgstr "Keine geprägte Datei" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "SVG-Datei in geprägter Form fehlt" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Daten der SVG-Datei fehlen" msgid "Face the camera" @@ -2058,17 +2063,21 @@ msgstr "Assembly Gizmo benutzen" msgid "Leaving Assembly gizmo" msgstr "Assembly Gizmo verlassen" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Teile eines geschnittenen Objekts können nicht verschoben werden" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Die Ausrichtung an der Platte ist nur in X und Y verfügbar" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Automatisches Ablegen für die ausgewählten Objekte ausschalten, um sie in Z zu verschieben" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Alle ausgewählten Objekte müssen auf derselben Platte liegen" msgid "Shift+" msgstr "Umschalt+" @@ -4927,7 +4936,7 @@ msgstr "Bitte speichern Sie das Projekt und starten Sie das Programm neu." msgid "Unknown C++ exception." msgstr "Unbekannte C++-Ausnahme." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Verarbeite G-Code der vorherigen Datei..." msgid "Slicing complete" @@ -6462,8 +6471,10 @@ msgstr "Achsen" msgid "Gridlines" msgstr "Rasterlinien" +# AI Translated +# Needs human review: Glossary has no German term for Focus mode yet; Fokusmodus chosen. msgid "Focus mode" -msgstr "" +msgstr "Fokusmodus" msgid "Labels" msgstr "Beschriftungen" @@ -6524,7 +6535,7 @@ msgstr "Volumen:" msgid "Size:" msgstr "Größe:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Konflikte von G-Code-Pfaden wurden bei Layer %d, Z = %.2lf mm gefunden.Bitte trennen Sie die konfliktbehafteten Objekte weiter voneinander (%s <-> %s)." @@ -10836,11 +10847,13 @@ msgstr "Nicht unterstützte Profile anzeigen" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Zeigt inkompatible/nicht unterstützte Profile in den Dropdown-Listen für Drucker und Filament an. Diese Profile können nicht ausgewählt werden." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Statistiken mit dem G-Code exportieren" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Wenn aktiviert, werden beim Exportieren einer G-Code-Datei auch deren Statistiken als JSON daneben geschrieben, als .statistics.json, und eine exportierte geslicte 3MF-Datei enthält sie intern: Druckzeit, Filament- und Linientyp-Summen sowie dieselben Werte pro Schicht und pro Objekt." msgid "Experimental Features" msgstr "Experimentelle Funktionen" @@ -11697,6 +11710,10 @@ msgstr "Die Datei konnte nicht in den Speicher des Druckers hochgeladen werden. msgid "Send Failed" msgstr "Senden fehlgeschlagen" +# AI Translated +msgid "No available printers" +msgstr "Keine verfügbaren Drucker" + msgid "The name length exceeds the limit." msgstr "Die Namenslänge überschreitet das Limit." @@ -13523,8 +13540,8 @@ msgid "Left mouse" msgstr "Linke Maustaste" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Überall im Fenster verfügbar, auch während der Eingabe in ein Textfeld." +msgid "Available anywhere in the window." +msgstr "Überall im Fenster verfügbar." # AI Translated msgid "Run favorite 1 to 10" @@ -13636,10 +13653,6 @@ msgstr "%s ist %s zugewiesen. Stattdessen %s zuweisen?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Das Standardkürzel %s ist %s zugewiesen. Stattdessen %s zuweisen?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Globale Tastenkürzel gelten auch während der Texteingabe." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Eine Taste, die ein Zeichen eingibt, kann kein globales Tastenkürzel sein." @@ -14083,9 +14096,10 @@ msgstr "Modifizierer „%1%“ von „%2%“ (%3% insgesamt) hatte keine Auswirk msgid "Seam placement may differ from expected." msgstr "Die Nahtplatzierung kann von der erwarteten abweichen." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Die G-Code-Statistiken konnten nicht nach %1% geschrieben werden." msgid "Internal Bridge" msgstr "Interne Brücke" @@ -17443,6 +17457,14 @@ msgstr "Objekte ausschließen" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Aktivieren Sie diese Option, um den Befehl EXCLUDE OBJECT im G-Code hinzuzufügen." +# AI Translated +msgid "Outline tolerance" +msgstr "Umrisstoleranz" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Maximale Abweichung des in EXCLUDE_OBJECT_DEFINE geschriebenen Objektumrisses vom ursprünglichen Umriss. Größere Werte ergeben weniger Punkte, was Firmware hilft, die beim Verarbeiten von G-Code mit vielen Objekten hängen bleibt. 0 behält jeden Punkt." + msgid "Verbose G-code" msgstr "ausführlicher G-Code" @@ -20628,11 +20650,13 @@ msgstr "Ausgabeverzeichnis" msgid "This is the output directory for exported files." msgstr "Ausgabeverzeichnis für die exportierten Dateien." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Statistiken exportieren" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Schreibt die Statistiken jeder gesliceten Platte als JSON, als plate_N.statistics.json neben ihrem G-Code im Ausgabeverzeichnis und in der 3MF von --export-3mf: Druckzeit, Filament- und Linientyp-Summen sowie dieselben Werte pro Schicht und pro Objekt." msgid "Debug level" msgstr "Fehlersuchstufe" @@ -23028,7 +23052,7 @@ msgstr "Test %s startet..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "Test %s IP aufgelöst = %s" # AI Translated @@ -30391,1231 +30415,1648 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "Die aktuelle Filamentliste enthält %s nicht. Ein vom Mischfilament benötigtes Projektfilament wird nach der Zerlegung automatisch erstellt." msgstr[1] "Die aktuelle Filamentliste enthält %s nicht. Vom Mischfilament benötigte Projektfilamente werden nach der Zerlegung automatisch erstellt." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Farbwähler" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Grundfarben" +# AI Translated +# Needs human review: Glossary has no German term for Palette yet; Palette chosen. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca-Palette" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Classic" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Verläufe" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Einfarbig" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Verlauf" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Verlaufsanfang" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Verlaufsende" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Verlaufsfarbe" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Farbe hinzufügen" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Farbe entfernen" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Sättigung" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Ursprüngliche Farbe" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Aktuelle Farbe speichern" +# AI Translated +# Needs human review: Glossary has no German term for Palette yet; Palette/Paletten chosen. msgid "Palettes" -msgstr "" +msgstr "Paletten" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Farben suchen" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Farben filtern" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Keine passenden Farben" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Hex-Farbe" # AI Translated msgid "Opacity" msgstr "Deckkraft" +# AI Translated +# Needs human review: Label of the opacity percent input in the color picker; check it reads right next to the field. msgid "Opacity percent" -msgstr "" +msgstr "Deckkraft in Prozent" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Farbe speichern" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Eine vollständige Hexadezimalfarbe eingeben" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Die aktuelle Mehrfarbenauswahl bleibt erhalten, bis eine andere Farbe gewählt wird." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Bis zu %d Farben werden unterstützt." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmesin" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Orangerot" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Tomate" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Orange" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Dunkelorange" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Gold" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Holzbraun" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Biskuit" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Nebelrosa" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Hellgelb" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Zitronenchiffon" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beige" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Hellgoldrutengelb" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Blasse Goldrute" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Khaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Dunkelkhaki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Pfirsichhauch" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mokassin" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papayacreme" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Geschälte Mandel" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antikweiß" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navajoweiß" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Weizen" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Goldrute" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Schokolade" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Ziegelrot" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Sattelbraun" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Braun" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Rosabraun" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Lachs" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Helles Lachs" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Dunkles Lachs" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Sandbraun" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Koralle" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Helle Koralle" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Indischrot" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Dunkelrot" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Kastanienrot" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Grüngelb" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Gelbgrün" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Rasengrün" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Limettengrün" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Frühlingsgrün" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Mittel-Frühlingsgrün" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Limette" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Waldgrün" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Dunkelgrün" +# AI Translated +# Needs human review: CSS olive drab has no common German name; Mattoliv chosen. msgid "Olive drab" -msgstr "" +msgstr "Mattoliv" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliv" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Dunkelolivgrün" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Blassgrün" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Hellgrün" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Mittel-Meergrün" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Meergrün" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Dunkelmeergrün" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Kadettenblau" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Mittel-Aquamarin" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Türkis" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Mitteltürkis" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Dunkeltürkis" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Blasstürkis" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Hellcyan" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Minzcreme" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Honigmelone" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Aquamarin" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Hellmeergrün" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Dunkelcyan" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Petrol" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Dunkelschiefergrau" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Hellschiefergrau" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Schiefergrau" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Tiefhimmelblau" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodgerblau" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Himmelblau" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Hellhimmelblau" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Hellblau" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Puderblau" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Hellstahlblau" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Stahlblau" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Kornblumenblau" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Königsblau" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Mittelblau" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Mitternachtsblau" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Dunkelblau" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Marineblau" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Schieferblau" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Dunkelschieferblau" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Mittelschieferblau" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Blauviolett" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Dunkelviolett" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Dunkelorchidee" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Mittelorchidee" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidee" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violett" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Mittelpurpur" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Purpur" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebecca-Purpur" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Mittelviolettrot" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Blassviolettrot" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Tiefrosa" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Knallrosa" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Hellrosa" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rosa" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Pflaume" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Distel" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuchsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Dunkelmagenta" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Leinen" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Altspitze" +# AI Translated +# Needs human review: Color name (CSS seashell), not the print Shell; glossary Shell warning is a false match. msgid "Sea shell" -msgstr "" +msgstr "Muschel" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Elfenbein" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Blütenweiß" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavendelrosa" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Geisterweiß" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Aliceblau" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavendel" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Rauchweiß" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Schwarz" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Korallenfeuer" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Seeanemone" +# AI Translated +# Needs human review: Ocean-themed color name; check the German rendering. msgid "Deep abyss" -msgstr "" +msgstr "Tiefer Abgrund" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Hummerrot" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Sandton" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Treibholz" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Sanddorn" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Sonnenuntergangsriff" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tigerkoralle" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Rosakoralle" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Muschelglanz" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Sand" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Goldkelp" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Sonnenbeschienene Düne" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Bernstein-Nautilus" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Seezitrone" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Blasser Seestern" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Springflut" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Limettenalge" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Seegras" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neonplankton" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Kelpwald" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Smaragdwelle" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Walschatten" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Meeresschildkröte" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagune" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Tropenströmung" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Mitternachtsgraben" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Dunkelkelp" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Kristallbrandung" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Türkisbucht" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Himmel über dem Riff" +# AI Translated +# Needs human review: Ocean-themed color name; check the German rendering. msgid "Shallow sky" -msgstr "" +msgstr "Flachwasserhimmel" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektroblau" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfin" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Meerestiefen" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Wal" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indigoabgrund" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Seeigel" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Lavendelkoralle" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Violette Flut" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Tiefsee-Orchidee" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neonqualle" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuchsiakoralle" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Rosa Qualle" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Schaum" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Muschelweiß" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Kieselgrau" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Gewitterwolke" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Tintenschwarz" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Grünbeige" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Sandgelb" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Signalgelb" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Goldgelb" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Honiggelb" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Maisgelb" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Narzissengelb" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Braunbeige" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Zitronengelb" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Perlweiß" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Hellelfenbein" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Zinkgelb" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Graubeige" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Olivgelb" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Rapsgelb" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Verkehrsgelb" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Ockergelb" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Verkehrsorangegelb" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Melonengelb" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Ginstergelb" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Dahliengelb" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pastellgelb" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Perlbeige" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Perlgold" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Sonnengelb" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Gelborange" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Tieforange" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Zinnoberrot" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Perlorange" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Reinorange" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Leuchtorange" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Leuchthellorange" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Hellrotorange" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Verkehrsorange" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Signalorange" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Lachsorange" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Perlrosa" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Kupferorange" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Signalbraun" +# AI Translated +# Needs human review: Unusual name (fir = Tanne); check the German colour name. msgid "Fir orange" -msgstr "" +msgstr "Tannenorange" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Signalrot" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Leuchtrot" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karminrot" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Perlkarminrot" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Reinrot" +# AI Translated +# Needs human review: Nonstandard RAL name; Leuchttiefrot is a literal rendering. msgid "Luminous deep red" -msgstr "" +msgstr "Leuchttiefrot" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Johannisbeerrot" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Perlrubinrot" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Feuerrot" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rubinrot" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Purpurrot" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Weinrot" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Schwarzrot" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oxidrot" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Braunrot" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Kiefernrot" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Tomatenrot" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Altrosa" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Korallenrot" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rosé" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Erdbeerrot" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Verkehrsrot" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Lachsrosa" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Leuchtrosa" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Leuchthellrot" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Himbeerrot" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Orientrot" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Perlrubin" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Rotpurpur" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Rotviolett" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Erikaviolett" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordeauxviolett" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Mahagoni" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Graupurpur" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Signalviolett" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Tannengrün" +# AI Translated msgid "Sabine grey" -msgstr "" +msgstr "Sabinegrau" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Perlviolett" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Perlbrombeer" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Grünblau" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarinblau" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Saphirblau" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Schwarzblau" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Signalblau" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Brillantblau" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Graublau" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azurblau" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Enzianblau" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobaltblau" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Taubenblau" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Verkehrsblau" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Türkisblau" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Capriblau" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Ozeanblau" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Wasserblau" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Nachtblau" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Fernblau" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pastellblau" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Perlenzianblau" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Perl-Mitternachtsblau" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patinagrün" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Smaragdgrün" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Laubgrün" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Olivgrün" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Blaugrün" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Moosgrün" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Grauoliv" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Kieferngrün" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Kiefernbraun" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Grasgrün" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Resedagrün" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Braungrün" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Schilfgrün" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Schwarzgrün" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Türkisgrün" +# AI Translated msgid "May green" -msgstr "" +msgstr "Maigrün" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Chromoxidgrün" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Verkehrsgrün" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Farngrün" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opalgrün" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Minzgrün" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Bronzegrün" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Perlgrün" +# AI Translated +# Needs human review: Unclear RAL-style name (Sax = Saxe blue?); check the German colour name. msgid "Sax turquoise" -msgstr "" +msgstr "Sax-Türkis" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Perltürkis" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Perljade" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Reingrün" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Leuchtgrün" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Eichhörnchengrau" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Silbergrau" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Olivgrau" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Moosgrau" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Signalgrau" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Mausgrau" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Beigegrau" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Khakigrau" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Grüngrau" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Zeltgrau" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Eisengrau" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Basaltgrau" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Braungrau" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Schiefergrau" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Anthrazitgrau" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Hellgrau" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umbragrau" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Betongrau" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Graphitgrau" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Granitgrau" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Steingrau" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Kieselgrau" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Zementgrau" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Gelbgrau" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platingrau" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Staubgrau" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Achatgrau" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Quarzgrau" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Fenstergrau" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Verkehrsgrau A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Verkehrsgrau B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Seidengrau" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegrau 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegrau 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegrau 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Perlmausgrau" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Grünbraun" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Ockerbraun" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Lehmbraun" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Kupferbraun" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Schokoladenbraun" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Olivbraun" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Nussbraun" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Rotbraun" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sepiabraun" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Kastanienbraun" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Mahagonibraun" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Graubraun" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Perlkupfer" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Beigebraun" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Perlmokkabraun" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Erdbraun" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Perlbraun" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Creme" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Grauweiß" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Signalweiß" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Signalschwarz" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Tiefschwarz" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Weißaluminium" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Graualuminium" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Reinweiß" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Graphitschwarz" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Verkehrsweiß" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Verkehrsschwarz" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papyrusweiß" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Perlhellgrau" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metall: Silber" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metall: Messing" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metall: Gold" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metall: Kupfer" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metall: Bronze" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Natur: Perle" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Natur: Regenbogen" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natur: Klarer Himmel" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Natur: Sonnenuntergang" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Holz: Dunkel" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Holz: Mittel" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Holz: Hell" # AI Translated msgid "Alternate nozzles:" @@ -32091,13 +32532,25 @@ msgstr "Aus „Meine Texturen“ entfernen" msgid "Built-in" msgstr "Integriert" +# AI Translated +msgid "My textures" +msgstr "Meine Texturen" + # AI Translated msgid "No textures found." msgstr "Keine Texturen gefunden." # AI Translated -msgid "My textures" -msgstr "Meine Texturen" +msgid "Texture libraries" +msgstr "Texturbibliotheken" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Weitere Texturbibliotheken entdecken" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Öffnet OrcaCloud auf der Startseite, um nach Plugins zu suchen." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32500,11 +32953,13 @@ msgstr "Abgebildet über das eigene UV-Layout des Modells, das bereits die Platz msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Wie breit eine Kopie der Textur auf dem Modell ist. Kleinere Werte wiederholen das Muster häufiger und machen seine Details feiner; bei deaktiviertem „Kacheln“ ist dies die Größe der einzelnen Kopie." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Größer" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Kleiner" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -32580,11 +33035,14 @@ msgstr "Mischfarben" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Die maximale Anzahl an Mischfilamenten, die beim Einbrennen hinzugefügt werden darf. Sie werden aus den Farben der Textur ausgewählt, und nur diejenigen, die das Einbrennen tatsächlich verwendet, werden erstellt." +# AI Translated +# Needs human review: Caption under an illustration in the texture displacement mixed-colors option; check it reads right as a pair with Many. msgid "Few" -msgstr "" +msgstr "Wenige" +# AI Translated msgid "Many" -msgstr "" +msgstr "Viele" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -32940,11 +33398,13 @@ msgstr "Neuvernetzung" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Dreiecksgröße, mit der das ganze Modell neu aufgebaut wird, in Millimetern. Die Verschiebung funktioniert am besten auf einem gleichmäßigen Netz; so entsteht eines aus einem ungleichmäßigen Import." +# AI Translated msgid "Before" -msgstr "" +msgstr "Vorher" +# AI Translated msgid "After" -msgstr "" +msgstr "Nachher" # AI Translated msgid "Keep sharp edges" @@ -34799,6 +35259,10 @@ msgstr "Skript" msgid "Slicing Pipeline" msgstr "Slicing-Pipeline" +# AI Translated +msgid "Resource Texture" +msgstr "Ressourcentextur" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Die Konfigurationsoberfläche des Plugins war leer. Der Standardeditor wird angezeigt." @@ -34946,6 +35410,30 @@ msgstr "Das Plugin-Verzeichnis enthält sowohl .py- als auch .whl-Einstiegsdatei msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Das Plugin-Verzeichnis enthält keine .py- oder .whl-Einstiegsdatei" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Das Verzeichnis der Ressourcentextur ist nicht festgelegt" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Das Verzeichnis der Ressourcentextur konnte nicht aufgelöst werden" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Der Pfad der Ressourcentextur ist kein Verzeichnis" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Der Plugin-Ordner konnte nicht aufgelöst werden" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Das Verzeichnis der Ressourcentextur liegt außerhalb des Plugin-Ordners" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Das Verzeichnis der Ressourcentextur konnte nicht gelesen werden" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -35406,7 +35894,7 @@ msgstr "Laden der Konfigurationsdatei „%1%“ fehlgeschlagen: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Keine von %1% erzeugte G-Code-Datei." # AI Translated @@ -35526,7 +36014,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Temporäre Kopie der G-Code-Datei %1% konnte vor dem Ausführen eines Nachbearbeitungsskripts nicht erstellt werden: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Nachbearbeitung kann die exportierte G-Code-Datei nicht finden" # AI Translated @@ -35894,6 +36382,29 @@ msgstr "" "Verwerfungen vermeiden\n" "Wussten Sie, dass beim Drucken von Materialien, die zu Verwerfungen neigen, wie z.B. ABS, durch eine entsprechende Erhöhung der Heizbetttemperatur die Wahrscheinlichkeit von Verwerfungen verringert werden kann?" +# AI Translated +# Needs human review: Likely RAL 1007 daffodil yellow (Narzissengelb); source name is nonstandard. +#~ msgid "Dalmatian yellow" +#~ msgstr "Narzissengelb" + +# AI Translated +# Needs human review: Source likely a typo for RAL 5019 Capri blue (sits between Turquoise blue and Ocean blue); translated as Capriblau. +#~ msgid "Capsanthin violet" +#~ msgstr "Capriblau" + +# AI Translated +# Needs human review: Source likely a typo for RAL 7002 Olive grey; translated as Olivgrau. +#~ msgid "Olivestone" +#~ msgstr "Olivgrau" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Überall im Fenster verfügbar, auch während der Eingabe in ein Textfeld." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Globale Tastenkürzel gelten auch während der Texteingabe." + #~ msgid "Please choose the filament color" #~ msgstr "Bitte wählen Sie die Filamentfarbe" @@ -36369,9 +36880,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "keinem konfigurierten Werkzeug" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "End G-Code nach dem fertigstellen des Drucks hinzufügen." - #~ msgid "Maximum X speed" #~ msgstr "Maximale Geschwindigkeit X" @@ -36388,25 +36896,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Python-Plugin(s), die bei jedem Schritt der Slicing-Pipeline aufgerufen werden, um Slicing-Zwischendaten zu lesen und zu ändern, einschließlich eines abschließenden G-code-Nachbearbeitungsschritts. Forschung/experimentell." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Wenn aktiviert, gibt der Slicer G-Code aus, bei dem der Inhalt der primären Zone auf den Ursprung des Druckbetts (0,0) zentriert ist. Die Drucker-Firmware ist dafür verantwortlich, Kopien/Spiegelungen an der jeweiligen physischen Zonenposition zu platzieren. Nur bei Druckern aktivieren, deren Firmware im Kopie-/Spiegelungsmodus eigene Zonenversätze anwendet (z. B. der IDEX-Duplizierungsmodus von RepRapFirmware). Hat im Modus Primär keine Wirkung." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Plattenspezifische Überschreibung, die physische Köpfe den Filament-Slots zuordnet (ab 1 gezählt). Leer bedeutet, die Standardwerte aus der pem-Umkehrung zu verwenden." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Achse, um die das Netz vor dem Slicen gedreht wird. Dies ist die Neigung des Förderbanddruckers: eine isometrische (verzerrungsfreie) Drehung, die auch die Darstellung des Druckbetts und die Schwerkraftneigung der Stützen bestimmt und die von der G-Code-Rücktransformation vor der Scherung/Skalierung und Achsenzuordnung im Maschinenkoordinatensystem umgekehrt wird. X ist die typische Portalneigung (das Förderband bewegt sich entlang Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Experten-Überschreibung: Legt den Neigungswinkel des Maschinenkoordinatensystems (G-Code-Scherung/-Skalierung) unabhängig vom Drehwinkel vor dem Slicen fest. Wenn deaktiviert, wird die Transformation ins Maschinenkoordinatensystem aus dem Neigungswinkel des Förderbands abgeleitet, sodass ein einziger Winkel beide Stufen steuert. Nur aktivieren, um eine Maschine auszugleichen, deren physische Portalneigung von der Slicing-Drehung abweicht." - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Die maximale Abweichung, die bei der Reduzierung der Auflösung für die Einstellung 'Maximale Wandauflösung' zulässig ist. Wenn Sie diesen Wert erhöhen, wird der Druck weniger genau, aber der G-Code wird kleiner. 'Maximale Wandabweichung' begrenzt 'Maximale Wandauflösung', so dass wenn die beiden in Konflikt stehen, 'Maximale Wandabweichung' Vorrang hat." - #~ msgid " not in range " #~ msgstr "nicht im Bereich" diff --git a/localization/i18n/en/OrcaSlicer_en.po b/localization/i18n/en/OrcaSlicer_en.po index ea45cda8c0..7152dd5f56 100644 --- a/localization/i18n/en/OrcaSlicer_en.po +++ b/localization/i18n/en/OrcaSlicer_en.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-06-17 15:44-0300\n" "Last-Translator: Alexandre Folle de Menezes\n" "Language-Team: \n" @@ -1633,16 +1633,16 @@ msgstr "" msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "" -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "" msgid "No embossed file" msgstr "" -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "" -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "" msgid "Face the camera" @@ -4575,7 +4575,7 @@ msgstr "" msgid "Unknown C++ exception." msgstr "" -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "" msgid "Slicing complete" @@ -6045,7 +6045,7 @@ msgstr "" msgid "Size:" msgstr "" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "" @@ -10653,6 +10653,9 @@ msgstr "" msgid "Send Failed" msgstr "" +msgid "No available printers" +msgstr "" + msgid "The name length exceeds the limit." msgstr "" @@ -12311,7 +12314,7 @@ msgstr "" msgid "Left mouse" msgstr "" -msgid "Available anywhere in the window, even while typing in a text field." +msgid "Available anywhere in the window." msgstr "" msgid "Run favorite 1 to 10" @@ -12408,9 +12411,6 @@ msgstr "" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "" -msgid "Global shortcuts also apply while typing." -msgstr "" - msgid "A key that types a character cannot be a global shortcut." msgstr "" @@ -15641,6 +15641,12 @@ msgstr "" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "" +msgid "Outline tolerance" +msgstr "" + +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "" + msgid "Verbose G-code" msgstr "" @@ -20536,7 +20542,7 @@ msgid "test %s start..." msgstr "" #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "" #, c-format, boost-format @@ -26488,17 +26494,18 @@ msgstr "" msgid "Basic Colors" msgstr "" +#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. msgid "Orca Palette" msgstr "" -#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. +#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "RAL Classic" msgstr "" -#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "Gradients" msgstr "" +msgctxt "Color picker" msgid "Solid" msgstr "" @@ -26873,7 +26880,7 @@ msgstr "" msgid "Medium violet red" msgstr "" -msgid "PaleV violet red" +msgid "Pale violet red" msgstr "" msgid "Deep pink" @@ -27035,7 +27042,7 @@ msgstr "" msgid "Shallow sky" msgstr "" -msgid "Electric bel" +msgid "Electric blue" msgstr "" msgid "Dolphin" @@ -27104,7 +27111,7 @@ msgstr "" msgid "Maize yellow" msgstr "" -msgid "Dalmatian yellow" +msgid "Daffodil yellow" msgstr "" msgid "Brown beige" @@ -27365,7 +27372,7 @@ msgstr "" msgid "Turquoise blue" msgstr "" -msgid "Capsanthin violet" +msgid "Capri blue" msgstr "" msgid "Ocean blue" @@ -27479,7 +27486,7 @@ msgstr "" msgid "Silver grey" msgstr "" -msgid "Olivestone" +msgid "Olive grey" msgstr "" msgid "Moss grey" @@ -28067,10 +28074,19 @@ msgstr "" msgid "Built-in" msgstr "" +msgid "My textures" +msgstr "" + msgid "No textures found." msgstr "" -msgid "My textures" +msgid "Texture libraries" +msgstr "" + +msgid "Explore more texture libraries" +msgstr "" + +msgid "Opens OrcaCloud in the Home page to browse for plugins." msgstr "" msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -30123,6 +30139,9 @@ msgstr "" msgid "Slicing Pipeline" msgstr "" +msgid "Resource Texture" +msgstr "" + msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "" @@ -30238,6 +30257,24 @@ msgstr "" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "" +msgid "Resource texture directory is not set" +msgstr "" + +msgid "Resource texture directory could not be resolved" +msgstr "" + +msgid "Resource texture path is not a directory" +msgstr "" + +msgid "Plugin folder could not be resolved" +msgstr "" + +msgid "Resource texture directory is outside the plugin folder" +msgstr "" + +msgid "Resource texture directory could not be read" +msgstr "" + #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" msgstr "" @@ -30594,7 +30631,7 @@ msgstr "" #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "" #. TRN %1% is a tag in the G-code file that must not be translated. @@ -30682,7 +30719,7 @@ msgstr "" msgid "Failed making a temporary copy of G-code file %1% before running a post-processing script: %2%" msgstr "" -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "" #, boost-format diff --git a/localization/i18n/es/OrcaSlicer_es.po b/localization/i18n/es/OrcaSlicer_es.po index ca65a6e16c..85c4ebe695 100644 --- a/localization/i18n/es/OrcaSlicer_es.po +++ b/localization/i18n/es/OrcaSlicer_es.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: Ian A. Bassi <>\n" "Language-Team: \n" @@ -722,17 +722,21 @@ msgstr "Selección" msgid "Plate" msgstr "Cama" +# AI Translated +# Needs human review: Distribute has no glossary rendering yet; check the term. msgid "Distribute" -msgstr "" +msgstr "Distribuir" msgid "Coordinate system used for transform actions." msgstr "Sistema de coordenadas utilizado para las acciones de transformación." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Referencia de alineación" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Selecciona al menos 3 piezas u objetos" # AI Translated msgid "Align left" @@ -785,8 +789,9 @@ msgstr "Distribuir arriba-abajo" msgid "Drop" msgstr "Soltar" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Mueve la selección a lo largo de Z para que su punto más bajo toque la cama." msgid "Absolute" msgstr "Absoluto" @@ -1673,7 +1678,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Trazo de forma (%1%) contiene no soportado: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Estado no válido; informe en GitHub de los pasos para reproducirlo" # AI Translated @@ -1681,11 +1686,11 @@ msgid "No embossed file" msgstr "No hay archivo en relieve" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Falta el archivo SVG en la forma en relieve" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Faltan los datos del archivo SVG" msgid "Face the camera" @@ -2003,17 +2008,21 @@ msgstr "Entrando al mecanismo de ensamblaje" msgid "Leaving Assembly gizmo" msgstr "Saliendo del mecanismo de ensamblaje" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Las piezas de un objeto cortado no se pueden mover" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "La alineación con la cama solo está disponible en X e Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Desactiva Dejar caer automáticamente en los objetos seleccionados para moverlos en Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Todos los objetos seleccionados deben estar en la misma cama" msgid "Shift+" msgstr "Shift+" @@ -4796,7 +4805,7 @@ msgstr "Guarde el proyecto y reinicie el programa." msgid "Unknown C++ exception." msgstr "Excepción de C++ desconocida." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Procesando el G-Code del archivo anterior…" msgid "Slicing complete" @@ -6316,8 +6325,10 @@ msgstr "Ejes" msgid "Gridlines" msgstr "Cuadrícula" +# AI Translated +# Needs human review: Name of a view mode hiding the surrounding UI; glossary cell is empty, check the term. msgid "Focus mode" -msgstr "" +msgstr "Modo de enfoque" msgid "Labels" msgstr "Etiquetas" @@ -6378,7 +6389,7 @@ msgstr "Volumen:" msgid "Size:" msgstr "Tamaño:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Se han encontrado conflictos de rutas G-Code en la capa %d, Z = %.2lfmm. Por favor, separe más los objetos en conflicto (%s <-> %s)." @@ -10602,11 +10613,13 @@ msgstr "Mostrar ajustes preestablecidos no compatibles" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Mostrar los ajustes preestablecidos incompatibles o no compatibles en los menús desplegables de impresoras y filamentos. Estos ajustes preestablecidos no se pueden seleccionar." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Exportar estadísticas con el G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Si se activa, al exportar un archivo G-code también se escriben sus estadísticas como JSON junto a él, como .statistics.json, y un archivo 3MF laminado exportado las contiene en su interior: tiempo de impresión, totales de filamento y por tipo de línea, y lo mismo por capa y por objeto." msgid "Experimental Features" msgstr "Funciones experimentales" @@ -11434,6 +11447,10 @@ msgstr "No se ha podido cargar el archivo en el almacenamiento de la impresora. msgid "Send Failed" msgstr "Envío fallido" +# AI Translated +msgid "No available printers" +msgstr "No hay impresoras disponibles" + msgid "The name length exceeds the limit." msgstr "La longitud del nombre supera el límite." @@ -13221,8 +13238,8 @@ msgid "Left mouse" msgstr "Botón izquierdo" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Disponible en cualquier parte de la ventana, incluso mientras se escribe en un campo de texto." +msgid "Available anywhere in the window." +msgstr "Disponible en cualquier parte de la ventana." # AI Translated msgid "Run favorite 1 to 10" @@ -13332,10 +13349,6 @@ msgstr "%s está asignado a %s. ¿Reasignarlo a %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "El %s predeterminado está asignado a %s. ¿Reasignarlo a %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Los atajos globales también se aplican mientras se escribe." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Una tecla que escribe un carácter no puede ser un atajo global." @@ -13775,9 +13788,10 @@ msgstr "el modificador \"%1%\" de \"%2%\" (%3% en total) no tuvo efecto en la co msgid "Seam placement may differ from expected." msgstr "La ubicación de la costura puede diferir de la esperada." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "No se pudieron escribir las estadísticas del G-code en %1%." msgid "Internal Bridge" msgstr "Puente Interior" @@ -17077,6 +17091,14 @@ msgstr "Excluir objetos" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Activar esta opción para añadir el comando EXCLUDE OBJECT en el G-Code." +# AI Translated +msgid "Outline tolerance" +msgstr "Tolerancia del contorno" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Desviación máxima del contorno del objeto escrito en EXCLUDE_OBJECT_DEFINE respecto al contorno original. Los valores más altos dan menos puntos, lo que ayuda al firmware que se bloquea al analizar G-code con muchos objetos. 0 conserva todos los puntos." + msgid "Verbose G-code" msgstr "G-Code detallado" @@ -20230,11 +20252,13 @@ msgstr "Directorio de salida" msgid "This is the output directory for exported files." msgstr "Directorio de salida para los archivos exportados." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Exportar estadísticas" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Escribe las estadísticas de cada cama laminada como JSON, como plate_N.statistics.json junto a su G-code en el directorio de salida y dentro del 3MF de --export-3mf: tiempo de impresión, totales de filamento y por tipo de línea, y lo mismo por capa y por objeto." msgid "Debug level" msgstr "Nivel de depuración" @@ -22631,7 +22655,7 @@ msgstr "prueba de %s iniciada..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "prueba de %s: IP resuelta = %s" # AI Translated @@ -29930,1231 +29954,1648 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "La lista de filamentos actual no contiene %s. Tras la descomposición se creará automáticamente un filamento de proyecto necesario para el filamento mixto." msgstr[1] "La lista de filamentos actual no contiene %s. Tras la descomposición se crearán automáticamente los filamentos de proyecto necesarios para el filamento mixto." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Selector de color" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Colores básicos" +# AI Translated +# Needs human review: Palette has no glossary rendering yet; check the term. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Paleta Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Classic" + +# AI Translated +# Needs human review: Gradient has no glossary rendering in this language; used the catalog's color-gradient term. msgid "Gradients" -msgstr "" +msgstr "Gradientes" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Sólido" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Gradiente" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Inicio del gradiente" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Fin del gradiente" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Color del gradiente" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Añadir color" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Eliminar color" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Saturación" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Color original" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Guardar color actual" +# AI Translated +# Needs human review: Palette has no glossary rendering yet; check the term. msgid "Palettes" -msgstr "" +msgstr "Paletas" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Buscar colores" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtrar colores" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "No hay colores coincidentes" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Color hexadecimal" # AI Translated msgid "Opacity" msgstr "Opacidad" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Porcentaje de opacidad" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Guardar color" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Introduce un color hexadecimal completo" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "La selección multicolor actual se mantiene hasta que elijas otro color." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Se admiten hasta %d colores." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Carmesí" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Rojo anaranjado" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Tomate" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Naranja" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Naranja oscuro" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Oro" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Madera clara" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Bizcocho" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Rosa brumoso" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Amarillo claro" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Gasa de limón" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beige" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Amarillo vara de oro claro" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Vara de oro pálido" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Caqui" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Caqui oscuro" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Melocotón suave" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mocasín" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Crema de papaya" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Almendra pelada" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Blanco antiguo" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Blanco navajo" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Trigo" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Vara de oro" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Chocolate" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Perú" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Ladrillo refractario" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Marrón cuero" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Marrón" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Marrón rosado" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Salmón" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Salmón claro" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Salmón oscuro" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Marrón arenoso" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Coral" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Coral claro" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Rojo indio" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Rojo oscuro" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Granate" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Verde amarillento" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Amarillo verdoso" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Verde césped" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Verde lima" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Verde primavera" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Verde primavera medio" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Lima" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Verde bosque" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Verde oscuro" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Verde oliva mate" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliva" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Verde oliva oscuro" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Verde pálido" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Verde claro" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Verde mar medio" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Verde mar" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Verde mar oscuro" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Azul cadete" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Aguamarina medio" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turquesa" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Turquesa medio" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Turquesa oscuro" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Turquesa pálido" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Agua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Cian claro" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Crema de menta" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Rocío de miel" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Aguamarina" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Verde mar claro" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Cian oscuro" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Verde azulado" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Gris pizarra oscuro" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Gris pizarra claro" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Gris pizarra" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Azul cielo intenso" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Azul Dodger" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Azul cielo" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Azul cielo claro" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Azul claro" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Azul polvo" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Azul acero claro" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Azul acero" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Azul aciano" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Azul real" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Azul medio" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Azul medianoche" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Azul oscuro" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Azul marino" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Azul pizarra" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Azul pizarra oscuro" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Azul pizarra medio" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Azul violeta" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Índigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Violeta oscuro" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Orquídea oscura" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Orquídea media" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orquídea" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violeta" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Púrpura medio" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Púrpura" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Púrpura Rebecca" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Rojo violeta medio" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Rojo violeta pálido" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Rosa intenso" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Rosa fuerte" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Rosa claro" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rosa" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Ciruela" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Cardo" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fucsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Magenta oscuro" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lino" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Encaje antiguo" +# AI Translated +# Needs human review: CSS color Seashell (a shell in the seafood sense); glossary Shell warning is a false match. msgid "Sea shell" -msgstr "" +msgstr "Concha marina" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Marfil" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Blanco floral" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Rubor de lavanda" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Blanco fantasma" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Azul Alicia" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavanda" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Humo blanco" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Negro" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Fuego de coral" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Anémona de mar" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Abismo profundo" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Rojo langosta" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Arcilla arenosa" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Madera a la deriva" +# AI Translated +# Needs human review: Ocean-themed color name; check the plant name. msgid "Sea buckthorn" -msgstr "" +msgstr "Espino amarillo" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Arrecife al atardecer" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Coral tigre" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Coral rosa" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Resplandor de concha" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Arena" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Alga dorada" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Duna iluminada" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Nautilo ámbar" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Limón de mar" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Estrella de mar pálida" +# AI Translated +# Needs human review: Ocean-themed color name; check the sense (tide vs spring season). msgid "Spring tide" -msgstr "" +msgstr "Marea viva" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Alga lima" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Hierba marina" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Plancton neón" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Bosque de algas" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Ola esmeralda" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Sombra de ballena" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Tortuga marina" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Laguna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Corriente tropical" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Fosa de medianoche" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Alga oscura" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Oleaje cristalino" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Bahía turquesa" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Cielo sobre el arrecife" +# AI Translated +# Needs human review: Ocean-themed color name; check it reads as a pale sky blue. msgid "Shallow sky" -msgstr "" +msgstr "Cielo somero" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Azul eléctrico" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfín" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Profundidades oceánicas" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Ballena" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Abismo índigo" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Erizo de mar" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Coral lavanda" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Marea violeta" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Orquídea de aguas profundas" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Medusa neón" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Coral fucsia" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Medusa rosa" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Espuma" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Blanco concha" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Gris guijarro" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Nube de tormenta" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Negro tinta" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Beige verdoso" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Amarillo arena" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Amarillo señales" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Amarillo dorado" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Amarillo miel" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Amarillo maíz" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Amarillo narciso" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Beige amarronado" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Amarillo limón" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Blanco ostra" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Marfil claro" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Amarillo zinc" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Beige grisáceo" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Amarillo oliva" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Amarillo colza" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Amarillo tráfico" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Amarillo ocre" +# AI Translated +# Needs human review: RAL name; unusual source name, translated by its parts. msgid "Traffic orange yellow" -msgstr "" +msgstr "Amarillo anaranjado tráfico" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Amarillo melón" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Amarillo retama" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Amarillo dalia" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Amarillo pastel" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Beige perlado" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Oro perlado" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Amarillo sol" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Naranja amarillento" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Naranja intenso" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Bermellón" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Naranja perlado" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Naranja puro" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Naranja brillante" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Naranja claro brillante" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Rojo anaranjado claro" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Naranja tráfico" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Naranja señales" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Naranja salmón" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Rosa perlado" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Naranja cobre" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Marrón señales" +# AI Translated +# Needs human review: RAL name; 'Fir orange' looks odd in the source, translated literally. msgid "Fir orange" -msgstr "" +msgstr "Naranja abeto" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Rojo señales" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Rojo brillante" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Rojo carmín" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Rojo carmín perlado" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Rojo puro" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Rojo intenso brillante" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Rojo grosella" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Rojo rubí perlado" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Rojo fuego" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rojo rubí" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Rojo púrpura" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Rojo vino" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Rojo negruzco" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Rojo óxido" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Rojo amarronado" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Rojo pino" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Rojo tomate" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Rosa antiguo" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Rojo coral" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rosa" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Rojo fresa" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Rojo tráfico" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Rosa salmón" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Rosa brillante" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Rojo claro brillante" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Rojo frambuesa" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Rojo oriente" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Rubí perlado" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Púrpura rojizo" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Violeta rojizo" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Violeta brezo" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Violeta burdeos" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Caoba" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Púrpura grisáceo" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Violeta señales" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Verde abeto" +# AI Translated msgid "Sabine grey" -msgstr "" +msgstr "Gris sabino" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Violeta perlado" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Mora perlada" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Azul verdoso" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Azul ultramar" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Azul zafiro" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Azul negruzco" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Azul señales" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Azul brillante" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Azul grisáceo" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azul azur" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Azul genciana" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Azul cobalto" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Azul paloma" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Azul tráfico" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Azul turquesa" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Azul Capri" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Azul océano" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Azul agua" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Azul noche" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Azul lejano" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Azul pastel" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Azul genciana perlado" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Azul medianoche perlado" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Verde pátina" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Verde esmeralda" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Verde hoja" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Verde oliva" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Verde azulado" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Verde musgo" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Oliva grisáceo" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Verde pino" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Marrón pino" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Verde hierba" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Verde reseda" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Verde amarronado" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Verde caña" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Verde negruzco" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Verde turquesa" +# AI Translated msgid "May green" -msgstr "" +msgstr "Verde mayo" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Verde óxido de cromo" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Verde tráfico" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Verde helecho" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Verde ópalo" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Verde menta" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Verde bronce" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Verde perlado" +# AI Translated +# Needs human review: RAL name (Saxe blue-like turquoise); check the rendering. msgid "Sax turquoise" -msgstr "" +msgstr "Turquesa sajón" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Turquesa perlado" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Jade perlado" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Verde puro" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Verde brillante" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Gris ardilla" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Gris plata" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Gris oliva" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Gris musgo" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Gris señales" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Gris ratón" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Gris beige" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Gris caqui" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Gris verdoso" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Gris lona" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Gris hierro" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Gris basalto" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Gris amarronado" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Gris pizarra" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Gris antracita" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Gris claro" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Gris sombra" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Gris hormigón" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Gris grafito" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Gris granito" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Gris piedra" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Gris guijarro" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Gris cemento" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Gris amarillento" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Gris platino" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Gris polvo" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Gris ágata" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Gris cuarzo" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Gris ventana" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Gris tráfico A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Gris tráfico B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Gris seda" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegris 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegris 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegris 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Gris ratón perlado" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Marrón verdoso" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Marrón ocre" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Marrón arcilla" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Marrón cobre" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Marrón chocolate" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Marrón oliva" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Marrón nuez" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Marrón rojizo" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Marrón sepia" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Marrón castaño" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Marrón caoba" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Marrón grisáceo" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Cobre perlado" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Marrón beige" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Marrón moca perlado" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Marrón tierra" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Marrón perlado" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Crema" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Blanco grisáceo" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Blanco señales" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Negro señales" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Negro azabache" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Aluminio blanco" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Aluminio gris" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Blanco puro" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Negro grafito" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Blanco tráfico" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Negro tráfico" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Blanco papiro" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Gris claro perlado" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metal: Plata" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metal: Latón" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metal: Oro" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metal: Cobre" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metal: Bronce" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Naturaleza: Perla" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Naturaleza: Arcoíris" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Naturaleza: Cielo despejado" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Naturaleza: Atardecer" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Madera: Oscura" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Madera: Media" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Madera: Clara" # AI Translated msgid "Alternate nozzles:" @@ -31630,13 +32071,25 @@ msgstr "Quitar de Mis texturas" msgid "Built-in" msgstr "Integradas" +# AI Translated +msgid "My textures" +msgstr "Mis texturas" + # AI Translated msgid "No textures found." msgstr "No se encontraron texturas." # AI Translated -msgid "My textures" -msgstr "Mis texturas" +msgid "Texture libraries" +msgstr "Bibliotecas de texturas" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Explorar más bibliotecas de texturas" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Abre OrcaCloud en la página de inicio para explorar plugins." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32039,11 +32492,15 @@ msgstr "Se mapea según la disposición UV del propio modelo, que ya es la ubica msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Ancho de una copia de la textura sobre el modelo. Un valor menor repite el patrón más a menudo y hace su detalle más fino; con Mosaico desactivado, es el tamaño de la copia única." +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Larger" -msgstr "" +msgstr "Más grande" +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Smaller" -msgstr "" +msgstr "Más pequeño" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -32119,11 +32576,15 @@ msgstr "Colores mezclados" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "El número máximo de filamentos mixtos que puede añadir un empotrado. Se eligen a partir de los colores de la textura y solo se crean los que el empotrado usa realmente." +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Few" -msgstr "" +msgstr "Pocos" +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Many" -msgstr "" +msgstr "Muchos" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -32479,11 +32940,15 @@ msgstr "Remallado" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Tamaño de triángulo con el que se reconstruye todo el modelo, en milímetros. El desplazamiento funciona mejor en una malla uniforme; esto es lo que la crea a partir de una importación irregular." +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Before" -msgstr "" +msgstr "Antes" +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "After" -msgstr "" +msgstr "Después" # AI Translated msgid "Keep sharp edges" @@ -34337,6 +34802,10 @@ msgstr "Script" msgid "Slicing Pipeline" msgstr "Flujo de laminado" +# AI Translated +msgid "Resource Texture" +msgstr "Textura de recursos" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "La interfaz de configuración del plugin estaba vacía. Se muestra el editor predeterminado." @@ -34484,6 +34953,30 @@ msgstr "El directorio del plugin contiene archivos de entrada .py y .whl a la ve msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "El directorio del plugin no contiene ningún archivo de entrada .py ni .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "El directorio de texturas de recursos no está establecido" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "No se pudo resolver el directorio de texturas de recursos" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "La ruta de texturas de recursos no es un directorio" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "No se pudo resolver la carpeta del plugin" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "El directorio de texturas de recursos está fuera de la carpeta del plugin" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "No se pudo leer el directorio de texturas de recursos" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -34942,7 +35435,7 @@ msgstr "Error al cargar el archivo de configuración \"%1%\": %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "No es un archivo G-code generado por %1%." # AI Translated @@ -35061,7 +35554,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "No se pudo hacer una copia temporal del archivo G-code %1% antes de ejecutar un script de posprocesamiento: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "El posprocesador no encuentra el archivo G-code exportado" # AI Translated @@ -35429,6 +35922,27 @@ msgstr "" "Evita la deformación\n" "¿Sabías que al imprimir materiales propensos a la deformación como el ABS, aumentar adecuadamente la temperatura de la cama térmica puede reducir la probabilidad de deformaciones?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Amarillo Dalmacia" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Violeta capsantina" + +# AI Translated +# Needs human review: RAL grey name, single coined word; translated literally. +#~ msgid "Olivestone" +#~ msgstr "Piedra oliva" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Disponible en cualquier parte de la ventana, incluso mientras se escribe en un campo de texto." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Los atajos globales también se aplican mientras se escribe." + #~ msgid "Please choose the filament color" #~ msgstr "Por favor, elija el color del filamento" @@ -35897,9 +36411,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "ninguna herramienta configurada" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "G-Code ejecutado en el final de la impresión completa." - #~ msgid "Maximum X speed" #~ msgstr "Velocidad máxima en X" @@ -35915,27 +36426,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Plugin(s) de Python que se invocan en cada paso de la canalización de laminado para leer y modificar los datos intermedios de laminado, incluido un paso final de posprocesamiento de G-code. Investigación/experimental." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Si se activa, el laminador emite el G-Code con el contenido de la zona principal centrado en el origen de la cama (0,0). El firmware de la impresora se encarga de colocar las copias o los reflejos en la posición física de cada zona. Actívelo solo en impresoras cuyo firmware aplique sus propios desplazamientos de zona en el modo Copia/Espejo (Copy/Mirror) (p. ej., el modo de duplicación IDEX de RepRapFirmware). No tiene efecto en el modo Principal (Primary)." - # AI Translated # Needs human review: 'pem-inversion' kept verbatim; it looks like an internal term (physical extruder map inversion). Check whether users understand it or the English should be rephrased. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Asignación por cama que sustituye la correspondencia entre los cabezales físicos y las ranuras de filamento (empezando en 1). Si está vacía, se usan los valores predeterminados de pem-inversion." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Eje alrededor del cual se gira la malla antes de laminar. Es la inclinación de la impresora de cinta: una rotación isométrica (sin distorsión) que también determina la representación de la cama y la inclinación de la gravedad de los soportes, y que la transformación inversa del G-Code deshace antes del cizallamiento/escalado y la reasignación al sistema de coordenadas de la máquina. X es la inclinación típica del pórtico (la cinta avanza a lo largo de Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Ajuste para expertos: establece el ángulo de inclinación del sistema de coordenadas de la máquina (cizallamiento/escalado del G-Code) de forma independiente del ángulo de rotación previo al laminado. Si se desactiva, la transformación del sistema de coordenadas de la máquina se deriva del ángulo de inclinación de la cinta, de modo que un único ángulo controla ambas etapas. Actívelo solo para compensar una máquina cuya inclinación física del pórtico difiera de la rotación de laminado." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "La desviación máxima permitida al reducir la resolución para el parámetro «Resolución máxima de la pared». Si aumentas este valor, la impresión será menos precisa, pero el G-code será más pequeño. El parámetro «Desviación máxima de la pared» limita la «Resolución máxima de la pared», por lo que, si ambos entran en conflicto, prevalece el primero." - #~ msgid " not in range " #~ msgstr " fuera de rango " diff --git a/localization/i18n/eu/OrcaSlicer_eu.po b/localization/i18n/eu/OrcaSlicer_eu.po index 0482155c5a..ae0c510186 100644 --- a/localization/i18n/eu/OrcaSlicer_eu.po +++ b/localization/i18n/eu/OrcaSlicer_eu.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-07-20 13:33+0200\n" "Last-Translator: Manu Goiogana \n" "Language-Team: \n" @@ -754,17 +754,21 @@ msgstr "Hautaketa" msgid "Plate" msgstr "Plaka" +# AI Translated +# Needs human review: Glossary has no Basque rendering; Banatu chosen (command that spaces objects evenly, counterpart of Lerrokatu). msgid "Distribute" -msgstr "" +msgstr "Banatu" msgid "Coordinate system used for transform actions." msgstr "Eraldatze-ekintzetan erabilitako koordenatu-sistema." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Lerrokatzeko erreferentzia" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Hautatu gutxienez 3 pieza edo objektu" # AI Translated msgid "Align left" @@ -821,8 +825,9 @@ msgstr "Banatu goi-behe norabidean" msgid "Drop" msgstr "Askatu" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Mugitu hautapena Z ardatzean, bere punturik baxuenak ohea ukitu dezan." msgid "Absolute" msgstr "Absolutua" @@ -1710,7 +1715,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "(%1%) formaren trazuak onartzen ez direnak ditu: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Egoera baliogabea; jakinarazi erreproduzitzeko urratsak GitHub-en" # AI Translated @@ -1718,11 +1723,11 @@ msgid "No embossed file" msgstr "Ez dago erliebeko fitxategirik" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "SVG fitxategia falta da erliebeko forman" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "SVG fitxategiaren datuak falta dira" msgid "Face the camera" @@ -2044,17 +2049,21 @@ msgstr "Muntaketa tresnan sartzen" msgid "Leaving Assembly gizmo" msgstr "Muntaketa tresnatik irteten" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Ebakitako objektu baten piezak ezin dira mugitu" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Plakarekin lerrokatzea X eta Y ardatzetan bakarrik dago erabilgarri" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Desgaitu hautatutako objektuen 'Automatikoki jaitsi' aukera, Z ardatzean mugitzeko" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Hautatutako objektu guztiak plaka berean egon behar dute" msgid "Shift+" msgstr "Shift+" @@ -4849,7 +4858,7 @@ msgstr "Mesedez, gorde proiektua eta berrabiarazi programa." msgid "Unknown C++ exception." msgstr "C++ salbuespen ezezaguna." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "G-codea prozesatzen aurreko fitxategitik…" msgid "Slicing complete" @@ -6373,8 +6382,10 @@ msgstr "Ardatzak" msgid "Gridlines" msgstr "Sareta-lerroak" +# AI Translated +# Needs human review: Glossary has no Basque rendering for Focus mode (hides the UI to concentrate on the 3D canvas); check the wording. msgid "Focus mode" -msgstr "" +msgstr "Kontzentrazio modua" msgid "Labels" msgstr "Etiketak" @@ -6435,7 +6446,7 @@ msgstr "Bolumena:" msgid "Size:" msgstr "Tamaina:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "G-code ibilbideen gatazkak aurkitu dira %d geruzan, Z = %.2lf mm. Urrundu gehiago gatazkan dauden objektuak (%s <-> %s)." @@ -10692,11 +10703,13 @@ msgstr "Erakutsi onartzen ez diren aurrezarpenak" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Erakutsi bateraezinak edo onartu gabeak diren aurrezarpenak inprimagailuaren eta filamentuaren goitibeherako zerrendetan. Aurrezarpen hauek ezin dira hautatu." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Esportatu estatistikak G-codearekin" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Gaituta badago, G-code fitxategi bat esportatzean haren estatistikak ere JSON gisa idazten dira alboan, .statistics.json izenarekin, eta esportatutako 3MF xerratu fitxategiak barruan gordetzen ditu: inprimatze-denbora, filamentuaren eta lerro-motaren araberako guztiak, eta gauza bera geruza bakoitzeko eta objektu bakoitzeko." msgid "Experimental Features" msgstr "Ezaugarri esperimentalak" @@ -11541,6 +11554,10 @@ msgstr "Huts egin du fitxategia inprimagailuaren biltegira igotzean. Saiatu berr msgid "Send Failed" msgstr "Bidalketak huts egin du" +# AI Translated +msgid "No available printers" +msgstr "Ez dago inprimagailurik erabilgarri" + msgid "The name length exceeds the limit." msgstr "Izenaren luzerak muga gainditzen du." @@ -13358,8 +13375,8 @@ msgid "Left mouse" msgstr "Saguaren ezkerreko botoia" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Leihoko edozein tokitan erabilgarri, baita testu-eremu batean idazten ari zarenean ere." +msgid "Available anywhere in the window." +msgstr "Leihoko edozein lekutan erabilgarri." # AI Translated msgid "Run favorite 1 to 10" @@ -13471,10 +13488,6 @@ msgstr "%s %s ekintzari esleituta dago. %s ekintzari berriro esleitu?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "%s lehenetsia %s ekintzari esleituta dago. %s ekintzari berriro esleitu?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Lasterbide globalak idazten ari zarenean ere aplikatzen dira." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Karaktere bat idazten duen tekla bat ezin da lasterbide globala izan." @@ -13915,9 +13928,10 @@ msgstr "\"%2%\" objektuaren \"%1%\" aldatzaileak (%3% guztira) ez du eraginik iz msgid "Seam placement may differ from expected." msgstr "Josturaren kokapena espero zena ez bezalakoa izan daiteke." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Ezin izan dira G-codearen estatistikak idatzi hemen: %1%." msgid "Internal Bridge" msgstr "Barruko zubia" @@ -17258,6 +17272,14 @@ msgstr "Baztertu objektuak" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Gaitu aukera hau G-codean EXCLUDE OBJECT komandoa gehitzeko." +# AI Translated +msgid "Outline tolerance" +msgstr "Ingeradaren tolerantzia" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "EXCLUDE_OBJECT_DEFINE-n idatzitako objektuaren ingeradak jatorrizko ingeradarekiko duen gehieneko desbideratzea. Balio handiagoek puntu gutxiago ematen dituzte, eta horrek objektu askoko G-codea aztertzean blokeatzen diren firmwareei laguntzen die. 0 balioak puntu guztiak mantentzen ditu." + msgid "Verbose G-code" msgstr "G-code xehea" @@ -20431,11 +20453,13 @@ msgstr "Irteerako direktorioa" msgid "This is the output directory for exported files." msgstr "Hau da esportatutako fitxategien irteerako direktorioa." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Esportatu estatistikak" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Idatzi xerratutako plaka bakoitzaren estatistikak JSON gisa, plate_N.statistics.json izenarekin irteera-direktorioan bere G-codearen ondoan eta --export-3mf aukerak sortutako 3MFaren barruan: inprimatze-denbora, filamentuaren eta lerro-motaren araberako guztiak, eta gauza bera geruza bakoitzeko eta objektu bakoitzeko." msgid "Debug level" msgstr "Arazketa-maila" @@ -22835,7 +22859,7 @@ msgstr "%s proba hasten..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "%s proba: IPa ebatzita = %s" # AI Translated @@ -30144,1231 +30168,1651 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "Uneko filamentu-zerrendan ez dago %s. Filamentu nahasiak behar duen proiektuko filamentu bat automatikoki sortuko da deskonposatu ondoren." msgstr[1] "Uneko filamentu-zerrendan ez dago %s. Filamentu nahasiak behar dituen proiektuko filamentuak automatikoki sortuko dira deskonposatu ondoren." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Kolore-hautatzailea" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Oinarrizko koloreak" +# AI Translated #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca paleta" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL klasikoa" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Gradienteak" +# AI Translated +# Needs human review: Single solid color as opposed to a gradient (color picker tab); Uniformea chosen to avoid the solid-infill sense, check the wording. +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Uniformea" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Gradientea" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Gradientearen hasiera" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Gradientearen amaiera" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Gradientearen kolorea" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Gehitu kolorea" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Kendu kolorea" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Saturazioa" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Jatorrizko kolorea" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Gorde uneko kolorea" +# AI Translated +# Needs human review: Glossary has no Basque cell for Palette; Paleta chosen. msgid "Palettes" -msgstr "" +msgstr "Paletak" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Bilatu koloreak" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Iragazi koloreak" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Ez dago bat datorren kolorerik" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Kolore hexadezimala" # AI Translated msgid "Opacity" msgstr "Opakutasuna" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Opakutasun-ehunekoa" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Gorde kolorea" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Idatzi kolore hexadezimal osoa" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Uneko kolore anitzeko hautapena mantendu egiten da beste kolore bat aukeratu arte." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Gehienez %d kolore onartzen dira." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmesia" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Laranja-gorria" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Tomatea" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Laranja" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Laranja iluna" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Urrea" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Zur sendoa" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Bisque" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Arrosa lainotsua" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Hori argia" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Limoi-xifoia" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beixa" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Urre-makila hori argia" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Urre-makila zurbila" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Kakia" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Kaki iluna" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Mertxika-bolia" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mokasina" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papaia-krema" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Almendra zurituta" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Zuri antzinakoa" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navajo zuria" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Garia" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Urre-makila" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Txokolatea" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Su-adreilua" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Zela-marroia" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Marroia" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Marroi arrosatua" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Izokina" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Izokin argia" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Izokin iluna" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Hare-marroia" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Korala" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Koral argia" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Gorri indiarra" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Gorri iluna" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Granatea" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Berde horixka" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Hori berdexka" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Zelai-berdea" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Lima-berdea" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Udaberri-berdea" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Udaberri-berde ertaina" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Lima" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Baso-berdea" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Berde iluna" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Oliba apala" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliba-berdea" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Oliba-berde iluna" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Berde zurbila" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Berde argia" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Itsaso-berde ertaina" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Itsaso-berdea" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Itsaso-berde iluna" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Kadete-urdina" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Akuamarina ertaina" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turkesa" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Turkesa ertaina" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Turkesa iluna" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Turkesa zurbila" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Akua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Ziano argia" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Menta-krema" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Ezti-ihintza" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Akuamarina" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Itsaso-berde argia" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Ziano iluna" +# AI Translated +# Needs human review: CSS teal (dark blue-green); check that Berde-urdin iluna reads as a color name next to Urdin berdexka and Berde urdinxka. msgid "Teal" -msgstr "" +msgstr "Berde-urdin iluna" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Pizarra-gris iluna" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Pizarra-gris argia" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Pizarra-grisa" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Zeru-urdin sakona" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodger urdina" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Zeru-urdina" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Zeru-urdin argia" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Urdin argia" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Hauts-urdina" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Altzairu-urdin argia" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Altzairu-urdina" +# AI Translated +# Needs human review: Flower name not known in Basque; rendered as Lore-urdina (flower blue), check for a proper name. msgid "Cornflower blue" -msgstr "" +msgstr "Lore-urdina" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Urdin erreala" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Urdin ertaina" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Gauerdi-urdina" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Urdin iluna" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Itsas-urdina" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Pizarra-urdina" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Pizarra-urdin iluna" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Pizarra-urdin ertaina" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Urdin-bioleta" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigoa" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Bioleta iluna" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Orkidea iluna" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Orkidea ertaina" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orkidea" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Bioleta" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "More ertaina" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Morea" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebecca morea" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Bioleta-gorri ertaina" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Bioleta-gorri zurbila" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Arrosa sakona" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Arrosa bizia" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Arrosa argia" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Arrosa" +# AI Translated +# Needs human review: Rendered as Aran-morea (plum purple); check the color name. msgid "Plum" -msgstr "" +msgstr "Aran-morea" +# AI Translated +# Needs human review: Rendered as Kardu-morea (thistle purple); check the color name. msgid "Thistle" -msgstr "" +msgstr "Kardu-morea" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuksia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Magenta iluna" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lihoa" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Dantela zaharra" +# AI Translated +# Needs human review: CSS color 'seashell'; the Shell glossary match is a false positive. msgid "Sea shell" -msgstr "" +msgstr "Itsaso-maskorra" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Eborea" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Lore-zuria" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Izpiliku arrosatua" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Mamu-zuria" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Alice urdina" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Izpilikua" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Ke-zuria" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Beltza" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Koral-sua" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Itsas anemona" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Amildegi sakona" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Otarrain-gorria" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Buztin hareatsua" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Uhin-egurra" +# AI Translated +# Needs human review: Plant name (Hippophae); check the Basque name and whether a color-only name reads better. msgid "Sea buckthorn" -msgstr "" +msgstr "Itsas elorri-zuria" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Ilunabarreko arrezifea" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tigre-korala" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Koral arrosa" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Maskor-dirdira" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Harea" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Alga urrea" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Eguzkitako duna" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Anbar-nautilusa" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Itsas limoia" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Itsas-izar zurbila" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Marea bizia" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Lima-alga" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Itsas-belarra" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neon-planktona" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Alga-basoa" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Esmeralda-olatua" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Balearen itzala" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Itsas dortoka" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Laguna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Korronte tropikala" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Gauerdiko itsas-sakonuna" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Alga iluna" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Kristal-olatua" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Badia turkesa" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Arrezife gaineko zerua" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Zeru azalekoa" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Urdin elektrikoa" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Izurdea" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Ozeanoaren sakonerak" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Balea" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indigo-amildegia" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Itsas trikua" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Izpiliku-korala" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Marea bioleta" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Itsaso sakoneko orkidea" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neon-medusa" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuksia-korala" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Medusa arrosa" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Aparra" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Maskor-zuria" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Koxkor-grisa" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Ekaitz-hodeia" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Tinta-beltza" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Beixa berdexka" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Hare-horia" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Seinale-horia" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Urre-horia" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Ezti-horia" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Arto-horia" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Nartziso-horia" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Beixa marroixka" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Limoi-horia" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Ostra-zuria" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Ebore argia" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Zink-horia" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Beixa grisaxka" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Oliba-horia" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Koltza-horia" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Trafiko-horia" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Okre-horia" +# AI Translated +# Needs human review: Source name looks like a RAL variant; check the rendering. msgid "Traffic orange yellow" -msgstr "" +msgstr "Trafiko-laranja horixka" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Meloi-horia" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Isats-horia" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Dalia-horia" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Hori pastela" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Perla-beixa" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Perla-urrea" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Eguzki-horia" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Hori-laranja" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Laranja sakona" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Bermilioia" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Perla-laranja" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Laranja hutsa" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Laranja argitsua" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Laranja argitsu distiratsua" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Gorri-laranja distiratsua" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Trafiko-laranja" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Seinale-laranja" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Izokin-laranja" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Perla-arrosa" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Kobre-laranja" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Seinale-marroia" +# AI Translated +# Needs human review: RAL color name as given in the source; check the rendering. msgid "Fir orange" -msgstr "" +msgstr "Izei-laranja" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Seinale-gorria" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Gorri argitsua" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karmin-gorria" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Perla-karmin-gorria" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Gorri hutsa" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Gorri sakon argitsua" +# AI Translated +# Needs human review: Fruit name; Mahats-gorria is approximate, check. msgid "Currant red" -msgstr "" +msgstr "Mahats-gorria" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Perla-rubi-gorria" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Su-gorria" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rubi-gorria" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "More-gorria" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Ardo-gorria" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Gorri beltzaxka" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oxido-gorria" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Gorri marroixka" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Pinu-gorria" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Tomate-gorria" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Arrosa antzinakoa" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Koral-gorria" +# AI Translated +# Needs human review: Same word as Pink (Arrosa); check whether a distinct name is wanted. msgid "Rose" -msgstr "" +msgstr "Arrosa" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Marrubi-gorria" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Trafiko-gorria" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Izokin-arrosa" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Arrosa argitsua" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Gorri argitsu distiratsua" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Mugurdi-gorria" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Ekialdeko gorria" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Perla-rubia" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "More gorrixka" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Bioleta gorrixka" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Txilar-bioleta" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordele-bioleta" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Kaoba" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "More grisaxka" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Seinale-bioleta" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Izei-berdea" +# AI Translated +# Needs human review: RAL color named after Sabine; check the rendering. msgid "Sabine grey" -msgstr "" +msgstr "Sabine grisa" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Perla-bioleta" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Perla-masusta" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Berde urdinxka" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramar urdina" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Zafiro-urdina" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Urdin beltzaxka" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Seinale-urdina" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Urdin distiratsua" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Urdin grisaxka" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azur-urdina" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Gentziana-urdina" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobalto-urdina" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Uso-urdina" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Trafiko-urdina" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Turkesa-urdina" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Capri-urdina" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Ozeano-urdina" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Ur-urdina" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Gau-urdina" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Urdin urruna" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Urdin pastela" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Perla-gentziana-urdina" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Perla-gauerdi-urdina" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patina-berdea" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Esmeralda-berdea" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Hosto-berdea" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Oliba-berdea" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Urdin berdexka" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Goroldio-berdea" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Oliba grisaxka" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Pinu-berdea" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Pinu-marroia" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Belar-berdea" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Reseda-berdea" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Berde marroixka" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Lezka-berdea" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Berde beltzaxka" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Turkesa-berdea" +# AI Translated msgid "May green" -msgstr "" +msgstr "Maiatz-berdea" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Kromo oxido-berdea" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Trafiko-berdea" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Garo-berdea" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opalo-berdea" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Menta-berdea" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Brontze-berdea" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Perla-berdea" +# AI Translated msgid "Sax turquoise" -msgstr "" +msgstr "Saxe-turkesa" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Perla-turkesa" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Perla-jadea" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Berde hutsa" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Berde argitsua" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Katagorri-grisa" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Zilar-grisa" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Oliba-grisa" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Goroldio-grisa" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Seinale-grisa" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Sagu-grisa" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Gris beixa" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Kaki-grisa" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Gris berdexka" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Mihise-grisa" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Burdin-grisa" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Basalto-grisa" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Gris marroixka" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Pizarra-grisa" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antrazita-grisa" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Gris argia" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umbra-grisa" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Hormigoi-grisa" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafito-grisa" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Granito-grisa" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Harri-grisa" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Koxkor-grisa" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Zementu-grisa" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Gris horixka" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platino-grisa" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Hauts-grisa" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Agata-grisa" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Kuartzo-grisa" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Leiho-grisa" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Trafiko-grisa A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Trafiko-grisa B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Zeta-grisa" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegris 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegris 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegris 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Perla-sagu-grisa" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Marroi berdexka" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Okre-marroia" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Buztin-marroia" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Kobre-marroia" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Txokolate-marroia" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Oliba-marroia" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Intxaur-marroia" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Marroi gorrixka" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sepia-marroia" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Gaztaina-marroia" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Kaoba-marroia" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Marroi grisaxka" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Perla-kobrea" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Beixa-marroia" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Perla-moka-marroia" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Lur-marroia" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Perla-marroia" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Krema" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Zuri grisaxka" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Seinale-zuria" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Seinale-beltza" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Gagatz-beltza" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Aluminio zuria" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Aluminio grisa" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Zuri hutsa" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Grafito-beltza" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Trafiko-zuria" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Trafiko-beltza" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papiro-zuria" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Perla-gris argia" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metala: Zilarra" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metala: Letoia" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metala: Urrea" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metala: Kobrea" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metala: Brontzea" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Natura: Perla" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Natura: Ortzadarra" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natura: Zeru garbia" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Natura: Ilunabarra" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Egurra: Iluna" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Egurra: Ertaina" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Egurra: Argia" # AI Translated msgid "Alternate nozzles:" @@ -31844,13 +32288,25 @@ msgstr "Kendu Nire testuretatik" msgid "Built-in" msgstr "Integratuak" +# AI Translated +msgid "My textures" +msgstr "Nire testurak" + # AI Translated msgid "No textures found." msgstr "Ez da testurarik aurkitu." # AI Translated -msgid "My textures" -msgstr "Nire testurak" +msgid "Texture libraries" +msgstr "Testura-liburutegiak" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Arakatu testura-liburutegi gehiago" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "OrcaCloud irekitzen du Hasiera orrian, pluginak arakatzeko." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32253,11 +32709,13 @@ msgstr "Modeloaren UV diseinuak berak mapatzen du, eta hori da jada kokapena - t msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Testuraren kopia batek modeloan duen zabalera. Txikiagoak patroia maizago errepikatzen du eta xehetasuna finagoa egiten du; Lauzatu desaktibatuta dagoenean, kopia bakarraren tamaina da." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Handiagoa" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Txikiagoa" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -32333,11 +32791,13 @@ msgstr "Kolore nahasiak" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Finkatze batek gehi ditzakeen filamentu nahasien gehieneko kopurua. Testuraren koloreetatik aukeratzen dira, eta finkatzeak benetan erabiltzen dituenak soilik sortzen dira." +# AI Translated msgid "Few" -msgstr "" +msgstr "Gutxi" +# AI Translated msgid "Many" -msgstr "" +msgstr "Asko" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -32693,11 +33153,13 @@ msgstr "Birsaretzea" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Modelo osoa berreraikitzeko erabiltzen den triangelu-tamaina, milimetrotan. Desplazamenduak sare uniforme batean funtzionatzen du ondoen; honek bihurtzen du inportazio irregular bat sare uniforme." +# AI Translated msgid "Before" -msgstr "" +msgstr "Aurretik" +# AI Translated msgid "After" -msgstr "" +msgstr "Ondoren" # AI Translated msgid "Keep sharp edges" @@ -34575,6 +35037,10 @@ msgstr "Scripta" msgid "Slicing Pipeline" msgstr "Xerratze-kanalizazioa" +# AI Translated +msgid "Resource Texture" +msgstr "Baliabide-testura" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Pluginaren konfigurazio-interfazea hutsik zegoen. Editore lehenetsia erakusten." @@ -34722,6 +35188,30 @@ msgstr "Pluginaren direktorioak .py eta .whl sarrera-fitxategiak ditu" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Pluginaren direktorioak ez du .py edo .whl sarrera-fitxategirik" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Baliabide-testuren direktorioa ez dago ezarrita" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Ezin izan da baliabide-testuren direktorioa ebatzi" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Baliabide-testuren bidea ez da direktorio bat" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Ezin izan da pluginaren karpeta ebatzi" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Baliabide-testuren direktorioa pluginaren karpetatik kanpo dago" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Ezin izan da baliabide-testuren direktorioa irakurri" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -35180,7 +35670,7 @@ msgstr "Huts egin du \"%1%\" konfigurazio-fitxategia kargatzeak: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Ez da %1% aplikazioak sortutako G-code fitxategia." # AI Translated @@ -35300,7 +35790,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Ezin izan da %1% G-code fitxategiaren aldi baterako kopia egin post-prozesatze scripta exekutatu aurretik: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Post-prozesadoreak ezin du esportatutako G-code fitxategia aurkitu" # AI Translated @@ -35668,6 +36158,27 @@ msgstr "" "Saihestu okertzea\n" "Ba al zenekien ABS bezalako okertzeko joera duten materialak inprimatzean ohe beroaren tenperatura egoki igotzeak okertzeko probabilitatea murriztu dezakeela?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Dalmaziar horia" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Kapsantina-bioleta" + +# AI Translated +# Needs human review: RAL color name; check the rendering. +#~ msgid "Olivestone" +#~ msgstr "Oliba-harria" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Leihoko edozein tokitan erabilgarri, baita testu-eremu batean idazten ari zarenean ere." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Lasterbide globalak idazten ari zarenean ere aplikatzen dira." + #~ msgid "Please choose the filament color" #~ msgstr "Hautatu filamentuen kolorea" @@ -36137,9 +36648,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "konfiguratutako erremintarik ez" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Gehitu amaierako G-codea inprimaketa osoa amaitzean." - #~ msgid "Maximum X speed" #~ msgstr "X gehieneko abiadura" @@ -36155,25 +36663,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Xerratze-prozesuko urrats bakoitzean deitzen diren Python pluginak, tarteko datuak irakurri eta aldatzeko; horien artean, G-codearen azken post-prozesatze fasea ere sartzen da. Ikerketa- edo esperimentazio-mailakoak." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Gaituta dagoenean, xerratzaileak eremu nagusiaren edukia ohearen jatorrian (0,0) zentratuta duen G-code sortzen du. Inprimagailuaren firmwareak kokatzen ditu kopiak/ispiluak eremu fisiko bakoitzaren posizioan. Gaitu soilik firmwareak kopia/ispilu moduan bere eremu-desplazamenduak aplikatzen dituen inprimagailuetan (adib. RepRapFirmware-ren IDEX bikoizte-modua). Ez du eraginik Nagusia (Primary) moduan." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Plaka bakoitzeko gainidazketa, buru fisikoak filamentu-zirrikituekin lotzen dituena (1etik hasita). Hutsik badago, pem-inbertsioaren balio lehenetsiak erabiltzen dira." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Xerratu aurretik sarea zein ardatzaren inguruan biratzen den. Zinta-inprimagailuaren inklinazioa da: biraketa isometriko bat (distortsiorik gabea), ohearen errendatzea eta euskarrien grabitate-inklinazioa ere gidatzen dituena, eta G-codearen alderantzizko transformazioak desegiten duena makinaren koordenatu-sistemaren zizailadura/eskala eta berresleipena aplikatu aurretik. X da atariaren ohiko inklinazioa (zinta Y ardatzean zehar mugitzen da)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Adituentzako gainidazketa: ezarri makinaren koordenatu-sistemaren inklinazio-angelua (G-codearen zizailadura/eskala) xerratu aurreko biraketa-angelutik independenteki. Desgaituta dagoenean, makinaren koordenatu-sistemaren transformazioa zintaren inklinazio-angelutik ateratzen da; beraz, angelu bakar batek gidatzen ditu bi etapak. Gaitu soilik atariaren inklinazio fisikoa xerratze-biraketatik desberdina duen makina bat konpentsatzeko." - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "'Hormaren gehieneko bereizmena' ezarpenerako bereizmena murriztean baimendutako gehieneko desbideratzea. Handitzen baduzu, inprimaketa ez da hain zehatza izango, baina G-codea txikiagoa izango da. 'Hormaren gehieneko desbideratzeak'-ek 'Hormaren gehieneko bereizmena' mugatzen du; beraz, bien artean gatazkarik badago, 'Hormaren gehieneko desbideratzeak' izango du lehentasuna." - #~ msgid " not in range " #~ msgstr " ez dago tartean " diff --git a/localization/i18n/fr/OrcaSlicer_fr.po b/localization/i18n/fr/OrcaSlicer_fr.po index 87b8a18e88..92b9b18041 100644 --- a/localization/i18n/fr/OrcaSlicer_fr.po +++ b/localization/i18n/fr/OrcaSlicer_fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: Guislain Cyril, Thomas Lété\n" @@ -311,7 +311,7 @@ msgid "Tungsten Carbide" msgstr "Carbure de tungstène" msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." -msgstr "La tête d'outil et le rack hotend peuvent se déplacer. Veuillez garder vos mains hors de la chambre." +msgstr "La tête d'outil et le rack hotend peuvent se déplacer. Veuillez garder vos mains hors du caisson." msgid "Warning" msgstr "Avertissement" @@ -329,7 +329,7 @@ msgid "Reading the hotends, please wait." msgstr "Lecture des hotends, veuillez patienter." msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." -msgstr "Pendant la mise à niveau du hotend, la tête d’outil va se déplacer. Ne mettez pas vos mains dans la chambre." +msgstr "Pendant la mise à niveau du hotend, la tête d’outil va se déplacer. Ne mettez pas vos mains dans le caisson." msgid "Update" msgstr "Mise à jour" @@ -771,17 +771,20 @@ msgstr "Sélection" msgid "Plate" msgstr "Plaque" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "Répartir" msgid "Coordinate system used for transform actions." msgstr "Système de coordonnées utilisé pour les actions de transformation." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Référence d’alignement" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Sélectionnez au moins 3 pièces ou objets" # AI Translated msgid "Align left" @@ -834,8 +837,9 @@ msgstr "Répartir haut-bas" msgid "Drop" msgstr "Déposer" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Déplace la sélection le long de Z pour que son point le plus bas touche le plateau." msgid "Absolute" msgstr "Absolu" @@ -1142,13 +1146,13 @@ msgid "Delete connector" msgstr "Supprimer le connecteur" msgid "Entering Cut gizmo" -msgstr "Entrée dans l’outil Couper" +msgstr "Entrée dans le gizmo Couper" msgid "Leaving Cut gizmo" -msgstr "Quitter l’outil Couper" +msgstr "Sortie du gizmo Couper" msgid "Cut gizmo editing" -msgstr "Modification de la découpe" +msgstr "Édition dans le gizmo Couper" msgid "Mesh name" msgstr "Nom du maillage" @@ -1250,10 +1254,10 @@ msgid "Embossed text" msgstr "Texte en relief" msgid "Enter emboss gizmo" -msgstr "Entrer dans l’outil d’embossage" +msgstr "Entrer dans le gizmo d’embossage" msgid "Leave emboss gizmo" -msgstr "Quitter l’outil d’embossage" +msgstr "Quitter le gizmo d’embossage" msgid "Embossing actions" msgstr "Actions d’embossage" @@ -1665,10 +1669,10 @@ msgid "SVG move" msgstr "Déplacement du SVG" msgid "Enter SVG gizmo" -msgstr "Ouvrir l’outil SVG" +msgstr "Ouvrir le gizmo SVG" msgid "Leave SVG gizmo" -msgstr "Quitter l’outil SVG" +msgstr "Quitter le gizmo SVG" msgid "SVG actions" msgstr "Actions SVG" @@ -1723,7 +1727,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Le trait de la forme (%1%) contient un élément non pris en charge : %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "État non valide, veuillez signaler les étapes de reproduction sur GitHub" # AI Translated @@ -1731,11 +1735,11 @@ msgid "No embossed file" msgstr "Aucun fichier en relief" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Fichier SVG manquant dans la forme en relief" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Données du fichier SVG manquantes" msgid "Face the camera" @@ -2007,10 +2011,10 @@ msgid "Flip by Face 2" msgstr "Retournement par la Face 2" msgid "Entering Measure gizmo" -msgstr "Entrée dans l’outil Mesurer" +msgstr "Entrée dans le gizmo Mesurer" msgid "Leaving Measure gizmo" -msgstr "Quitter l’outil Mesurer" +msgstr "Sortie du gizmo Mesurer" # AI Translated msgctxt "Assembly tool" @@ -2051,22 +2055,26 @@ msgid "Face and face assembly" msgstr "Assemblage face à face" msgid "Entering Assembly gizmo" -msgstr "Entrée dans l’outil Assemblage" +msgstr "Entrée dans le gizmo Assemblage" msgid "Leaving Assembly gizmo" -msgstr "Quitter l’outil Assemblage" +msgstr "Sortie du gizmo Assemblage" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Les pièces d’un objet coupé ne peuvent pas être déplacées" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "L’alignement sur la plaque n’est disponible qu’en X et Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Désactivez le dépôt automatique des objets sélectionnés pour les déplacer en Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Tous les objets sélectionnés doivent se trouver sur la même plaque" msgid "Shift+" msgstr "Maj+" @@ -3805,7 +3813,7 @@ msgid "Init" msgstr "Initialisation" msgid "Chamber" -msgstr "Chambre" +msgstr "Caisson" msgid "Innerloop" msgstr "Boucle interne" @@ -4872,7 +4880,7 @@ msgstr "Veuillez enregistrer le projet et redémarrer le programme." msgid "Unknown C++ exception." msgstr "Exception C++ inconnue." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Traitement du G-Code du fichier précédent…" msgid "Slicing complete" @@ -6401,8 +6409,9 @@ msgstr "Axes" msgid "Gridlines" msgstr "Quadrillage" +# AI Translated msgid "Focus mode" -msgstr "" +msgstr "Mode focus" msgid "Labels" msgstr "Étiquettes" @@ -6463,7 +6472,7 @@ msgstr "Volume :" msgid "Size:" msgstr "Taille :" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Des conflits de chemins G-code ont été trouvés au niveau de la couche %d, z = %.2lfmm. Veuillez séparer davantage les objets en conflit (%s <-> %s)." @@ -8234,7 +8243,7 @@ msgstr "Éjection en cours." msgid "%1$d Object has custom supports." msgid_plural "%1$d Objects have custom supports." msgstr[0] "%1$d objet a des supports personnalisés." -msgstr[1] " %1$d objets ont des supports personnalisés." +msgstr[1] "%1$d objets ont des supports personnalisés." #, c-format, boost-format msgid "%1$d Object has color painting." @@ -8419,11 +8428,11 @@ msgstr "Identifie le type et la position de la plaque de construction sur le pla # AI Translated msgid "Purifies the chamber air as the print finishes, based on the selected mode." -msgstr "Purifie l'air de la chambre à la fin de l'impression, selon le mode sélectionné." +msgstr "Purifie l'air du caisson à la fin de l'impression, selon le mode sélectionné." # AI Translated msgid "Purifies the chamber air through internal circulation as each print finishes." -msgstr "Purifie l'air de la chambre par circulation interne à la fin de chaque impression." +msgstr "Purifie l'air du caisson par circulation interne à la fin de chaque impression." # AI Translated msgid "Automatically match the corresponding switch strategy for leak-prone filaments (disable blob detection) and regular filaments (enable blob detection)." @@ -10706,11 +10715,13 @@ msgstr "Afficher les préréglages non pris en charge" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Affiche les préréglages incompatibles ou non pris en charge dans les listes déroulantes d’imprimantes et de filaments. Ces préréglages ne peuvent pas être sélectionnés." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Exporter les statistiques avec le G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Si activé, l’export d’un fichier G-code écrit aussi ses statistiques au format JSON à côté, sous la forme .statistics.json, et un fichier 3MF découpé exporté les contient : durée d’impression, totaux du filament et par type de ligne, ainsi que les mêmes données par couche et par objet." msgid "Experimental Features" msgstr "Fonctionnalités expérimentales" @@ -11461,7 +11472,7 @@ msgid "The selected printer (%s) has an unknown model, so compatibility with the msgstr "L’imprimante sélectionnée (%s) est d’un modèle inconnu ; la compatibilité avec la configuration du fichier d’impression (%s) ne peut donc pas être vérifiée. Veuillez vérifier le préréglage d’imprimante avant l’envoi." msgid "When spiral vase mode is enabled, machines with I3 structure will not generate timelapse videos." -msgstr "Lorsque vous activez le mode vase, les machines avec une structure I3 ne généreront pas de vidéos timelapse." +msgstr "Lorsque vous activez le mode vase spirale, les machines avec une structure I3 ne généreront pas de vidéos timelapse." msgid "The current printer does not support timelapse in Traditional Mode when printing By-Object." msgstr "L'imprimante actuelle ne prend pas en charge le timelapse en mode traditionnel lors de l'impression par objet." @@ -11551,6 +11562,10 @@ msgstr "Échec du téléversement du fichier vers le stockage de l’imprimante. msgid "Send Failed" msgstr "Échec de l’envoi" +# AI Translated +msgid "No available printers" +msgstr "Aucune imprimante disponible" + msgid "The name length exceeds the limit." msgstr "La longueur du nom dépasse la limite." @@ -12051,8 +12066,8 @@ msgid "" "When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n" "by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\"." msgstr "" -"Lorsque vous enregistrez un timelapse sans tête d’outil, il est recommandé d’ajouter une \"Tour d’essuyage timelapse\".\n" -"en faisant un clic droit sur un emplacement vide sur le plateau et en choisissant \"Ajouter Primitive\"-> \"Tour d’essuyage timelapse\"." +"Lorsque vous enregistrez un timelapse sans tête d’outil, il est recommandé d’ajouter une \"Tour d’amorçage timelapse\".\n" +"en faisant un clic droit sur un emplacement vide sur le plateau et en choisissant \"Ajouter Primitive\"-> \"Tour d’amorçage timelapse\"." msgid "A copy of the current system preset will be created, which will be detached from the system preset." msgstr "Une copie du préréglage actuel du système est créée et détachée du préréglage du système." @@ -12351,7 +12366,7 @@ msgid "Filament end G-code" msgstr "G-code de fin de filament" msgid "Wipe tower parameters" -msgstr "Paramètres de la tour d’essuyage" +msgstr "Paramètres de la tour d’amorçage" msgid "Multi Filament" msgstr "Multi-filament" @@ -12500,7 +12515,7 @@ msgid "Nozzle diameter" msgstr "Diamètre de la buse" msgid "Wipe tower" -msgstr "Tour d’essuyage" +msgstr "Tour d’amorçage" # AI Translated msgid "Belt purge tower" @@ -13369,8 +13384,8 @@ msgid "Left mouse" msgstr "Clic gauche" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Disponible partout dans la fenêtre, même pendant la saisie dans un champ de texte." +msgid "Available anywhere in the window." +msgstr "Disponible partout dans la fenêtre." # AI Translated msgid "Run favorite 1 to 10" @@ -13475,9 +13490,6 @@ msgstr "%s est attribué à %s. Le réattribuer à %s ?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "La valeur par défaut %s est attribuée à %s. La réattribuer à %s ?" -msgid "Global shortcuts also apply while typing." -msgstr "Les raccourcis globaux s'appliquent aussi pendant la saisie." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Une touche qui saisit un caractère ne peut pas être un raccourci global." @@ -13751,7 +13763,7 @@ msgstr "Ouvrir un fichier G-code :" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "Wipe tower generation failed, possibly due to empty first layer." -msgstr "Échec de la génération de la tour d’essuyage, peut-être à cause d’une première couche vide." +msgstr "Échec de la génération de la tour d’amorçage, peut-être à cause d’une première couche vide." msgid "One object has an empty first layer and can't be printed. Please Cut the bottom or enable supports." msgstr "Un objet a une couche initiale vide et ne peut pas être imprimé. Veuillez couper le bas ou activer les supports." @@ -13920,9 +13932,10 @@ msgstr "le modificateur « %1% » de « %2% » (%3% au total) n’a eu aucun eff msgid "Seam placement may differ from expected." msgstr "Le placement de la couture peut différer de celui attendu." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Échec de l’écriture des statistiques du G-code dans %1%." msgid "Internal Bridge" msgstr "Pont interne" @@ -14275,16 +14288,16 @@ msgstr "La hauteur de couche variable n’est pas prise en charge avec les suppo # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "The wipe tower filament cannot be a mixed filament." -msgstr "Le filament de la tour d’essuyage ne peut pas être un filament mixte." +msgstr "Le filament de la tour d’amorçage ne peut pas être un filament mixte." msgid "Different nozzle diameters and different filament diameters may not work well when the prime tower is enabled. It's very experimental, so please proceed with caution." msgstr "Différents diamètres de buses et de filaments peuvent ne pas fonctionner correctement lorsque la tour d’amorçage est activée. Il s’agit d’un projet très expérimental, il convient donc de procéder avec prudence." msgid "The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1)." -msgstr "La tour d’essuyage n’est actuellement prise en charge qu’avec l’adressage relatif des extrudeurs (use_relative_e_distances=1)." +msgstr "La tour d’amorçage n’est actuellement prise en charge qu’avec l’adressage relatif des extrudeurs (use_relative_e_distances=1)." msgid "Ooze prevention is only supported with the wipe tower when 'single_extruder_multi_material' is off." -msgstr "La prévention du suintement n’est possible qu’avec la tour d’essuyage lorsque l’option ‘single_extruder_multi_material’ est désactivée." +msgstr "La prévention du suintement n’est possible qu’avec la tour d’amorçage lorsque l’option ‘single_extruder_multi_material’ est désactivée." msgid "The prime tower is currently only supported for the Marlin, RepRap/Sprinter, RepRapFirmware and Repetier G-code flavors." msgstr "La tour d’amorçage n’est actuellement prise en charge que pour les versions Marlin, RepRap/Sprinter, RepRapFirmware et Repetier G-code." @@ -16225,7 +16238,7 @@ msgid "Loading speed" msgstr "Vitesse de chargement" msgid "Speed used for loading the filament on the wipe tower." -msgstr "Vitesse utilisée pour charger le filament sur la tour d’essuyage." +msgstr "Vitesse utilisée pour charger le filament sur la tour d’amorçage." msgid "Loading speed at the start" msgstr "Vitesse de chargement au démarrage" @@ -16237,7 +16250,7 @@ msgid "Unloading speed" msgstr "Vitesse de déchargement" msgid "Speed used for unloading the filament on the wipe tower (does not affect initial part of unloading just after ramming)." -msgstr "Vitesse utilisée pour le déchargement du filament sur la tour d’essuyage (n’affecte pas la partie initiale de retrait juste après le pilonnage)." +msgstr "Vitesse utilisée pour le déchargement du filament sur la tour d’amorçage (n’affecte pas la partie initiale de retrait juste après le pilonnage)." msgid "Unloading speed at the start" msgstr "Vitesse de déchargement au démarrage" @@ -16276,13 +16289,13 @@ msgid "Cooling moves are gradually accelerating beginning at this speed." msgstr "Les mouvements de refroidissement s’accélèrent progressivement à partir de cette vitesse." msgid "Minimal purge on wipe tower" -msgstr "Purge minimale sur la tour d’essuyage" +msgstr "Purge minimale sur la tour d’amorçage" msgid "After a tool change, the exact position of the newly loaded filament inside the nozzle may not be known, and the filament pressure is likely not yet stable. Before purging the print head into an infill or a sacrificial object, Orca Slicer will always prime this amount of material into the wipe tower to produce successive infill or sacrificial object extrusions reliably." -msgstr "Après un changement d’outil, la position exacte du filament nouvellement chargé à l’intérieur de la buse peut ne pas être connue et la pression du filament n’est probablement pas encore stable. Avant de purger la tête d’impression dans un remplissage ou un objet, Orca Slicer amorcera toujours cette quantité de matériau dans la tour d’essuyage pour purger dans les remplissages ou objets de manière fiable." +msgstr "Après un changement d’outil, la position exacte du filament nouvellement chargé à l’intérieur de la buse peut ne pas être connue et la pression du filament n’est probablement pas encore stable. Avant de purger la tête d’impression dans un remplissage ou un objet, Orca Slicer amorcera toujours cette quantité de matériau dans la tour d’amorçage pour purger dans les remplissages ou objets de manière fiable." msgid "Wipe tower cooling" -msgstr "Refroidissement de la tour d’essuyage" +msgstr "Refroidissement de la tour d’amorçage" msgid "Temperature drop before entering filament tower" msgstr "Baisse de température avant l’entrée dans la tour de filament" @@ -16336,7 +16349,7 @@ msgid "Enable ramming for multi-tool setups" msgstr "Activer le pilonnage pour les configurations multi-outils" msgid "Perform ramming when using multi-tool printer (i.e. when the 'Single Extruder Multimaterial' in Printer Settings is unchecked). When checked, a small amount of filament is rapidly extruded on the wipe tower just before the tool change. This option is only used when the wipe tower is enabled." -msgstr "Effectuez un pilonnage lorsque vous utilisez une imprimante multi-outils (c’est-à-dire lorsque l’option ‘Multi-matériau à extrudeur unique’ dans les paramètres de l’imprimante n’est pas cochée). Une fois vérifié, une petite quantité de filament est rapidement extrudée sur la tour d’essuyage juste avant le changement d’outil. Cette option n’est utilisée que lorsque la tour d’essuyage est activée." +msgstr "Effectuez un pilonnage lorsque vous utilisez une imprimante multi-outils (c’est-à-dire lorsque l’option ‘Multi-matériau à extrudeur unique’ dans les paramètres de l’imprimante n’est pas cochée). Une fois vérifié, une petite quantité de filament est rapidement extrudée sur la tour d’amorçage juste avant le changement d’outil. Cette option n’est utilisée que lorsque la tour d’amorçage est activée." msgid "Multi-tool ramming volume" msgstr "Volume du pilonnage multi-outils" @@ -17274,6 +17287,14 @@ msgstr "Exclure des objets" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Activer cette option pour ajouter la commande EXCLUDE OBJECT dans le G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Tolérance du contour" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Écart maximal entre le contour de l’objet écrit dans EXCLUDE_OBJECT_DEFINE et le contour d’origine. Des valeurs plus grandes donnent moins de points, ce qui aide les firmwares qui se bloquent à l’analyse d’un G-code contenant de nombreux objets. 0 conserve tous les points." + msgid "Verbose G-code" msgstr "G-code commenté" @@ -18580,10 +18601,10 @@ msgid "Minimum number of segments of each scarf." msgstr "Nombre minimum de segments de chaque biseau." msgid "Scarf joint for inner walls" -msgstr "Joint en biseau pour les parois intérieures" +msgstr "Couture en biseau pour les parois intérieures" msgid "Use scarf joint for inner walls as well." -msgstr "Utiliser également un joint en biseau pour les parois intérieures." +msgstr "Utiliser également une couture en biseau pour les parois intérieures." # AI Translated msgid "Role based wipe speed" @@ -18671,7 +18692,7 @@ msgid "Single loop after first layer" msgstr "Boucle unique après la première couche" msgid "Limits the skirt/draft shield loops to one wall after the first layer. This is useful, on occasion, to conserve filament but may cause the draft shield/skirt to warp / crack." -msgstr "Limite les boucles de jupe/bouclier de courant d'air à une seule paroi après la première couche. Cela est utile, à l'occasion, pour économiser du filament mais peut provoquer le gauchissement/fissuration du bouclier de courant d'air/de la jupe." +msgstr "Limite les boucles de jupe/paravent à une seule paroi après la première couche. Cela est utile, à l'occasion, pour économiser du filament mais peut provoquer le gauchissement/fissuration du paravent/de la jupe." msgid "Draft shield" msgstr "Paravent" @@ -18806,7 +18827,7 @@ msgstr "Timelapse au point le plus éloigné" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." -msgstr "Lorsque cette option est activée, l’instantané du timelapse est pris au point le plus éloigné de la caméra au lieu de se déplacer vers la tour d’essuyage ou la goulotte d’évacuation. Efficace uniquement en mode timelapse traditionnel sur les imprimantes non-I3." +msgstr "Lorsque cette option est activée, l’instantané du timelapse est pris au point le plus éloigné de la caméra au lieu de se déplacer vers la tour d’amorçage ou la goulotte d’évacuation. Efficace uniquement en mode timelapse traditionnel sur les imprimantes non-I3." msgid "Temperature variation" msgstr "Variation de température" @@ -18979,10 +19000,10 @@ msgid "Enable this option to omit the custom Change filament G-code only at the msgstr "Activez cette option pour omettre le G-code de changement de filament personnalisé uniquement au début de l’impression. La commande de changement d’outil (par exemple, T0) sera ignorée tout au long de l’impression. Ceci est utile pour l’impression manuelle multi-matériaux, où nous utilisons M600/PAUSE pour déclencher l’action de changement manuel de filament." msgid "Wipe tower type" -msgstr "Type de tour de purge" +msgstr "Type de tour d'amorçage" msgid "Choose the wipe tower implementation for multi-material prints. Type 1 is recommended for Bambu and Qidi printers with a filament cutter. Type 2 offers better compatibility with multi-tool and MMU printers and provide overall better compatibility." -msgstr "Choisir l'implémentation de la tour de purge pour les impressions multi-matériaux. Le Type 1 est recommandé pour les imprimantes Bambu et Qidi avec un coupeur de filament. Le Type 2 offre une meilleure compatibilité avec les imprimantes multi-outils et MMU et une meilleure compatibilité globale." +msgstr "Choisir l'implémentation de la tour d'amorçage pour les impressions multi-matériaux. Le Type 1 est recommandé pour les imprimantes Bambu et Qidi avec un coupeur de filament. Le Type 2 offre une meilleure compatibilité avec les imprimantes multi-outils et MMU et une meilleure compatibilité globale." msgid "Type 1" msgstr "Type 1" @@ -19000,20 +19021,20 @@ msgid "Enable filament ramming" msgstr "Activer le bourrage de filament" msgid "Tool change on wipe tower" -msgstr "Changement d’outil sur la tour d’essuyage" +msgstr "Changement d’outil sur la tour d’amorçage" msgid "Force the toolhead to travel to the wipe tower before issuing the tool change command (Tx). Only relevant for multi-extruder (multi-toolhead) printers using a Type 2 wipe tower. By default Orca skips the travel on multi-toolhead machines because the firmware handles the head swap, which can result in the Tx command being issued above the printed part. Enable this option if you want the tool change to always be issued above the wipe tower instead." -msgstr "Force la tête d’outil à se déplacer vers la tour d’essuyage avant d’émettre la commande de changement d’outil (Tx). Pertinent uniquement pour les imprimantes multi-extrudeurs (à têtes d’outil multiples) utilisant une tour d’essuyage de type 2. Par défaut, Orca omet ce déplacement sur les machines à têtes d’outil multiples car le firmware gère le changement de tête, ce qui peut entraîner l’émission de la commande Tx au-dessus de la pièce imprimée. Activez cette option si vous préférez que le changement d’outil soit toujours émis au-dessus de la tour d’essuyage." +msgstr "Force la tête d’outil à se déplacer vers la tour d’amorçage avant d’émettre la commande de changement d’outil (Tx). Pertinent uniquement pour les imprimantes multi-extrudeurs (à têtes d’outil multiples) utilisant une tour d’amorçage de type 2. Par défaut, Orca omet ce déplacement sur les machines à têtes d’outil multiples car le firmware gère le changement de tête, ce qui peut entraîner l’émission de la commande Tx au-dessus de la pièce imprimée. Activez cette option si vous préférez que le changement d’outil soit toujours émis au-dessus de la tour d’amorçage." # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "Wait for temperature on wipe tower" -msgstr "Attendre la température sur la tour d’essuyage" +msgstr "Attendre la température sur la tour d’amorçage" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "Pick up the new tool without waiting for it to reach printing temperature, travel to the wipe tower, and wait for the temperature there, right before purging. Ooze from the heat-up lands on the tower instead of the model, and the travel overlaps with the heating. Only relevant for multi-extruder (multi-toolhead) printers using a Type 2 wipe tower. The firmware or tool change macro must not wait for the temperature itself. When disabled, the temperature wait is issued right after the tool change command." -msgstr "Prend le nouvel outil sans attendre qu’il atteigne la température d’impression, se déplace vers la tour d’essuyage et y attend la température, juste avant la purge. Le suintement dû à la chauffe se dépose sur la tour plutôt que sur le modèle, et le déplacement se superpose à la chauffe. Uniquement pertinent pour les imprimantes multi-extrudeurs (multi-têtes) utilisant une tour d’essuyage de type 2. Le firmware ou la macro de changement d’outil ne doivent pas attendre la température eux-mêmes. Lorsque cette option est désactivée, l’attente de température est émise juste après la commande de changement d’outil." +msgstr "Prend le nouvel outil sans attendre qu’il atteigne la température d’impression, se déplace vers la tour d’amorçage et y attend la température, juste avant la purge. Le suintement dû à la chauffe se dépose sur la tour plutôt que sur le modèle, et le déplacement se superpose à la chauffe. Uniquement pertinent pour les imprimantes multi-extrudeurs (multi-têtes) utilisant une tour d’amorçage de type 2. Le firmware ou la macro de changement d’outil ne doivent pas attendre la température eux-mêmes. Lorsque cette option est désactivée, l’attente de température est émise juste après la commande de changement d’outil." msgid "No sparse layers (beta)" msgstr "Pas de couches éparses (beta)" @@ -19021,7 +19042,7 @@ msgstr "Pas de couches éparses (beta)" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "If enabled, the wipe tower will not be printed on layers with no tool changes. On layers with a tool change, extruder will travel downward to print the wipe tower, so the tower ends up below the model and the toolhead has to reach down to it. Layouts where that would collide with an already printed object are rejected. Has no effect with smooth timelapse or clumping detection, which need a tower on every layer." -msgstr "Si cette option est activée, la tour d’essuyage n’est pas imprimée sur les couches sans changement d’outil. Sur les couches comportant un changement d’outil, l’extrudeur descend pour imprimer la tour d’essuyage : la tour se retrouve donc sous le modèle et la tête d’outil doit descendre jusqu’à elle. Les dispositions où cela entrerait en collision avec un objet déjà imprimé sont rejetées. Sans effet avec le timelapse fluide ou la détection d’agglomération de la buse, qui nécessitent une tour à chaque couche." +msgstr "Si cette option est activée, la tour d’amorçage n’est pas imprimée sur les couches sans changement d’outil. Sur les couches comportant un changement d’outil, l’extrudeur descend pour imprimer la tour d’amorçage : la tour se retrouve donc sous le modèle et la tête d’outil doit descendre jusqu’à elle. Les dispositions où cela entrerait en collision avec un objet déjà imprimé sont rejetées. Sans effet avec le timelapse fluide ou la détection d’agglomération de la buse, qui nécessitent une tour à chaque couche." # AI Translated msgid "Combine sparse layers" @@ -19507,7 +19528,7 @@ msgstr "Activer la tour de purge du tapis" # AI Translated # Needs human review: Glossary cell for Prime tower / Wipe tower is unsettled (⚠); used the catalog's Tour d’essuyage / Tour d’amorçage msgid "Belt-printer replacement for the wipe/prime tower. When enabled on a belt printer, a purge prism is automatically generated next to the printed parts and filament-change purging is routed into it (the classic wipe tower cannot be used on belt printers because its G-code bypasses the belt transform). Only available on belt printers." -msgstr "Remplacement de la tour d’essuyage/d’amorçage pour les imprimantes à tapis. Lorsque cette option est activée sur une imprimante à tapis, un prisme de purge est généré automatiquement à côté des pièces imprimées et la purge lors des changements de filament y est dirigée (la tour d’essuyage classique ne peut pas être utilisée sur les imprimantes à tapis, car son G-code contourne la transformation du tapis). Disponible uniquement sur les imprimantes à tapis." +msgstr "Remplacement de la tour d’amorçage pour les imprimantes à tapis. Lorsque cette option est activée sur une imprimante à tapis, un prisme de purge est généré automatiquement à côté des pièces imprimées et la purge lors des changements de filament y est dirigée (la tour d’amorçage classique ne peut pas être utilisée sur les imprimantes à tapis, car son G-code contourne la transformation du tapis). Disponible uniquement sur les imprimantes à tapis." # AI Translated msgid "Belt purge tower width" @@ -19516,7 +19537,7 @@ msgstr "Largeur de la tour de purge du tapis" # AI Translated # Needs human review: Glossary cell for Prime tower / Wipe tower is unsettled (⚠); used the catalog's Tour d’essuyage for 'wipe tower' msgid "Width (machine X, across the belt) of the purge prism that is automatically generated on belt printers when the belt purge tower is enabled and multiple filaments are used. Filament-change purging is routed into this prism's extrusions instead of a classic wipe tower. Its height is computed automatically from the worst-case purge volume per layer: a wider prism results in a shorter one." -msgstr "Largeur (X machine, en travers du tapis) du prisme de purge généré automatiquement sur les imprimantes à tapis lorsque la tour de purge du tapis est activée et que plusieurs filaments sont utilisés. La purge lors des changements de filament est dirigée vers les extrusions de ce prisme au lieu d'une tour d’essuyage classique. Sa hauteur est calculée automatiquement à partir du volume de purge le plus défavorable par couche : un prisme plus large sera moins haut." +msgstr "Largeur (X machine, en travers du tapis) du prisme de purge généré automatiquement sur les imprimantes à tapis lorsque la tour de purge du tapis est activée et que plusieurs filaments sont utilisés. La purge lors des changements de filament est dirigée vers les extrusions de ce prisme au lieu d'une tour d’amorçage classique. Sa hauteur est calculée automatiquement à partir du volume de purge le plus défavorable par couche : un prisme plus large sera moins haut." msgid "Tree support branch angle" msgstr "Angle de branche support arborescent" @@ -19766,7 +19787,7 @@ msgid "Enable mixed color sublayer splitting. When enabled, layers containing mi msgstr "Active la division en sous-couches de couleur mixte. Lorsqu’elle est activée, les couches contenant des filaments de couleur mixte sont divisées en sous-couches afin d’obtenir des effets de mélange de couleurs." msgid "The wiping tower can be used to clean up residue on the nozzle and stabilize the chamber pressure inside the nozzle in order to avoid appearance defects when printing objects." -msgstr "La tour de purge peut être utilisée pour nettoyer les résidus sur la buse et stabiliser la pression du caisson à l'intérieur de la buse afin d'éviter les défauts d'apparence lors de l'impression d'objets." +msgstr "La tour d'amorçage peut être utilisée pour nettoyer les résidus sur la buse et stabiliser la pression du caisson à l'intérieur de la buse afin d'éviter les défauts d'apparence lors de l'impression d'objets." msgid "Internal ribs" msgstr "Nervures internes" @@ -19804,7 +19825,7 @@ msgstr "Mode de volume d'amorçage" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." -msgstr "Sélectionne la manière dont les volumes d’amorçage et de purge de la tour d’essuyage sont calculés sur les imprimantes multi-extrudeurs." +msgstr "Sélectionne la manière dont les volumes d’amorçage et de purge de la tour d’amorçage sont calculés sur les imprimantes multi-extrudeurs." # AI Translated msgid "Saving" @@ -19818,10 +19839,10 @@ msgid "This is the width of prime towers." msgstr "Largeur de la tour d’amorçage" msgid "Wipe tower rotation angle" -msgstr "Angle de rotation de la tour d’essuyage" +msgstr "Angle de rotation de la tour d’amorçage" msgid "Wipe tower rotation angle with respect to X axis." -msgstr "Angle de rotation de la tour d’essuyage par rapport à l’axe X." +msgstr "Angle de rotation de la tour d’amorçage par rapport à l’axe X." msgid "Brim width of prime tower, negative number means auto calculated width based on the height of prime tower." msgstr "Largeur de la bordure de la tour d'amorçage, un nombre négatif signifie une largeur calculée automatiquement en fonction de la hauteur de la tour d'amorçage." @@ -19830,10 +19851,10 @@ msgid "Stabilization cone apex angle" msgstr "Angle au sommet du cône de stabilisation" msgid "Angle at the apex of the cone that is used to stabilize the wipe tower. Larger angle means wider base." -msgstr "Angle au sommet du cône utilisé pour stabiliser la tour d’essuyage. Un angle plus grand signifie une base plus large." +msgstr "Angle au sommet du cône utilisé pour stabiliser la tour d’amorçage. Un angle plus grand signifie une base plus large." msgid "Maximum wipe tower print speed" -msgstr "Vitesse maximale d’impression de la tour d’essuyage" +msgstr "Vitesse maximale d’impression de la tour d’amorçage" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. @@ -19848,15 +19869,15 @@ msgid "" "\n" "For the wipe tower external perimeters the internal perimeter speed is used, also limited by this setting." msgstr "" -"Vitesse d’impression maximale lors de la purge dans la tour d’essuyage et de l’impression des couches éparses de la tour d’essuyage. Lors de la purge, si la vitesse de remplissage ou la vitesse calculée à partir de la vitesse volumétrique maximale du filament est inférieure, c’est la plus faible qui sera utilisée.\n" +"Vitesse d’impression maximale lors de la purge dans la tour d’amorçage et de l’impression des couches éparses de la tour d’amorçage. Lors de la purge, si la vitesse de remplissage ou la vitesse calculée à partir de la vitesse volumétrique maximale du filament est inférieure, c’est la plus faible qui sera utilisée.\n" "\n" "Lors de l’impression des couches éparses, si la vitesse de remplissage ou la vitesse calculée à partir de la vitesse volumétrique maximale du filament est inférieure, c’est la plus faible qui sera utilisée.\n" "\n" -"L’augmentation de cette vitesse peut affecter la stabilité de la tour et accroître la force avec laquelle la buse heurte les éventuels amas qui se sont formés sur la tour d’essuyage.\n" +"L’augmentation de cette vitesse peut affecter la stabilité de la tour et accroître la force avec laquelle la buse heurte les éventuels amas qui se sont formés sur la tour d’amorçage.\n" "\n" "Avant d’augmenter ce paramètre au-delà de la valeur par défaut de 90 mm/s, assurez-vous que votre imprimante peut réaliser des ponts de façon fiable à des vitesses plus élevées et que le suintement lors des changements d’outil est bien maîtrisé.\n" "\n" -"Pour les périmètres externes de la tour d’essuyage, c’est la vitesse du périmètre interne qui est utilisée, également limitée par ce paramètre." +"Pour les périmètres externes de la tour d’amorçage, c’est la vitesse du périmètre interne qui est utilisée, également limitée par ce paramètre." msgid "Wall type" msgstr "Type de paroi" @@ -19869,9 +19890,9 @@ msgid "" "2. Cone: A cone with a fillet at the bottom to help stabilize the wipe tower.\n" "3. Rib: The default wall type, which adds four ribs to the tower wall for enhanced stability." msgstr "" -"Type de paroi extérieure de la tour d’essuyage.\n" +"Type de paroi extérieure de la tour d’amorçage.\n" "1. Rectangle : Un rectangle avec une largeur et une hauteur fixes.\n" -"2. Cône : Un cône avec un congé en bas pour aider à stabiliser la tour d’essuyage.\n" +"2. Cône : Un cône avec un congé en bas pour aider à stabiliser la tour d’amorçage.\n" "3. Nervure : Le type de paroi par défaut, qui ajoute quatre nervures à la paroi de la tour pour une stabilité améliorée." msgid "Rectangle" @@ -19899,13 +19920,13 @@ msgid "The wall of prime tower will fillet." msgstr "La paroi de la tour d'amorçage aura un congé." msgid "The extruder to use when printing perimeter of the wipe tower. Set to 0 to use the one that is available (non-soluble would be preferred)." -msgstr "L’extrudeur à utiliser lors de l’impression du périmètre de la tour d’essuyage. Réglez sur 0 pour utiliser celui qui est disponible (un non-soluble serait préféré)." +msgstr "L’extrudeur à utiliser lors de l’impression du périmètre de la tour d’amorçage. Réglez sur 0 pour utiliser celui qui est disponible (un non-soluble serait préféré)." msgid "Purging volumes - load/unload volumes" msgstr "Volumes de purge - Volume de Chargement/Déchargement" msgid "This vector saves required volumes to change from/to each tool used on the wipe tower. These values are used to simplify creation of the full purging volumes below." -msgstr "Ce vecteur enregistre les volumes requis pour passer de/vers chaque outil utilisé sur la tour d’essuyage. Ces valeurs sont utilisées pour simplifier la création des volumes de purge complets ci-dessous." +msgstr "Ce vecteur enregistre les volumes requis pour passer de/vers chaque outil utilisé sur la tour d’amorçage. Ces valeurs sont utilisées pour simplifier la création des volumes de purge complets ci-dessous." msgid "Skip points" msgstr "Sauter des points" @@ -19955,10 +19976,10 @@ msgid "Maximal distance between supports on sparse infill sections." msgstr "Distance maximale entre les supports sur les sections de remplissage." msgid "Wipe tower purge lines spacing" -msgstr "Espacement des lignes de purge de la tour d’essuyage" +msgstr "Espacement des lignes de purge de la tour d’amorçage" msgid "Spacing of purge lines on the wipe tower." -msgstr "Espacement des lignes de purge sur la tour d’essuyage." +msgstr "Espacement des lignes de purge sur la tour d’amorçage." msgid "Extra flow for purging" msgstr "Débit supplémentaire pour purger" @@ -19966,7 +19987,7 @@ msgstr "Débit supplémentaire pour purger" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "Extra flow used for the purging lines on the wipe tower. This makes the purging lines thicker than they normally would be. The spacing is adjusted automatically." -msgstr "Débit supplémentaire utilisé pour les lignes de purge de la tour d’essuyage. Cela rend les lignes de purge plus épaisses qu’elles ne le seraient normalement. L’espacement est ajusté automatiquement." +msgstr "Débit supplémentaire utilisé pour les lignes de purge de la tour d’amorçage. Cela rend les lignes de purge plus épaisses qu’elles ne le seraient normalement. L’espacement est ajusté automatiquement." msgid "Idle temperature" msgstr "Température au repos" @@ -20041,7 +20062,7 @@ msgid "Use relative E distances" msgstr "Utiliser l’extrusion relative" msgid "Relative extrusion is recommended when using \"label_objects\" option. Some extruders work better with this option unchecked (absolute extrusion mode). Wipe tower is only compatible with relative mode. It is recommended on most printers. Default is checked." -msgstr "L’extrusion relative est recommandée lors de l’utilisation de l’option « label_objects ». Certains extrudeurs fonctionnent mieux avec cette option non verrouillée (mode d’extrusion absolu). La tour d’essuyage n’est compatible qu’avec le mode relatif. Il est recommandé sur la plupart des imprimantes. L’option par défaut est cochée" +msgstr "L’extrusion relative est recommandée lors de l’utilisation de l’option « label_objects ». Certains extrudeurs fonctionnent mieux avec cette option non verrouillée (mode d’extrusion absolu). La tour d’amorçage n’est compatible qu’avec le mode relatif. Il est recommandé sur la plupart des imprimantes. L’option par défaut est cochée" msgid "The classic wall generator produces walls with constant extrusion width and for very thin areas, gap-fill is used. The Arachne engine produces walls with variable extrusion width." msgstr "Le générateur de paroi classique produit des parois avec une largeur d’extrusion constante et, pour les zones très fines, il utilise le remplissage d’espace. Le moteur Arachne produit des parois avec une largeur d’extrusion variable." @@ -20466,11 +20487,13 @@ msgstr "Répertoire de sortie" msgid "This is the output directory for exported files." msgstr "Répertoire de sortie des fichiers exportés." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Exporter les statistiques" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Écrit les statistiques de chaque plaque découpée au format JSON, sous la forme plate_N.statistics.json à côté de son G-code dans le répertoire de sortie et dans le 3MF de --export-3mf : durée d’impression, totaux du filament et par type de ligne, ainsi que les mêmes données par couche et par objet." msgid "Debug level" msgstr "Niveau de débogage" @@ -20601,10 +20624,10 @@ msgid "Specific for sequential printing. Zero-based index of currently printed o msgstr "Spécifique à l’impression séquentielle. Index commençant à zéro de l’objet en cours d’impression." msgid "Has wipe tower" -msgstr "Possède une tour d’essuyage" +msgstr "Possède une tour d’amorçage" msgid "Whether or not wipe tower is being generated in the print." -msgstr "Indique si la tour d’essuyage est générée ou non dans l’impression." +msgstr "Indique si la tour d’amorçage est générée ou non dans l’impression." msgid "Initial extruder" msgstr "Extrudeur initial" @@ -20741,16 +20764,16 @@ msgid "Total cost of all material used in the print. Calculated from filament_co msgstr "Coût total de tous les matériaux utilisés dans l'impression. Calculé à partir de la valeur filament_cost dans les paramètres de filament." msgid "Total wipe tower cost" -msgstr "Coût total de la tour de purge" +msgstr "Coût total de la tour d'amorçage" msgid "Total cost of the material wasted on the wipe tower. Calculated from filament_cost value in Filament Settings." -msgstr "Coût total du matériau gaspillé sur la tour de purge. Calculé à partir de la valeur filament_cost dans les paramètres de filament." +msgstr "Coût total du matériau gaspillé sur la tour d'amorçage. Calculé à partir de la valeur filament_cost dans les paramètres de filament." msgid "Wipe tower volume" -msgstr "Volume de la tour de purge" +msgstr "Volume de la tour d'amorçage" msgid "Total filament volume extruded on the wipe tower." -msgstr "Volume total de filament extrudé sur la tour de purge." +msgstr "Volume total de filament extrudé sur la tour d'amorçage." msgid "Used filament" msgstr "Filament utilisé" @@ -20867,7 +20890,7 @@ msgstr "Taille du plateau d’impression" # AI Translated # Needs human review: Unsettled glossary term (⚠) "Prime tower / Wipe tower": this entry uses "tour d’essuyage"; align it once the term is settled. msgid "First layer center without wipe tower" -msgstr "Centre de la première couche sans tour d’essuyage" +msgstr "Centre de la première couche sans tour d’amorçage" # AI Translated msgid "Height of the first layer." @@ -22022,7 +22045,7 @@ msgid "Flow Ratio" msgstr "Rapport de débit" msgid "Please input a valid value (0.0 < flow ratio < 2.0)" -msgstr "Veuillez saisir une valeur valide (0,0 < ratio du débit < 2,0)" +msgstr "Veuillez saisir une valeur valide (0,0 < rapport de débit < 2,0)" msgid "Please enter the name of the preset you want to save." msgstr "Veuillez saisir le nom du préréglage que vous souhaitez enregistrer." @@ -22044,7 +22067,7 @@ msgstr "Ignorer la Calibration 2" #, c-format, boost-format msgid "flow ratio : %s " -msgstr "ratio du débit : %s " +msgstr "rapport de débit : %s " msgid "Please choose a block with smoothest top surface." msgstr "Veuillez choisir un bloc avec la surface supérieure la plus lisse." @@ -22059,7 +22082,7 @@ msgid "Complete Calibration" msgstr "Calibration complète" msgid "Fine Calibration based on flow ratio" -msgstr "Calibration précise d’après le ratio du débit" +msgstr "Calibration précise d’après le rapport de débit" msgid "Title" msgstr "Titre" @@ -22807,10 +22830,10 @@ msgid "1 selected" msgstr "1 sélectionné" msgid "Part 1" -msgstr "Partie 1" +msgstr "Pièce 1" msgid "Part 2" -msgstr "Partie 2" +msgstr "Pièce 2" msgid "Delete input" msgstr "Supprimer l’objet" @@ -22859,7 +22882,7 @@ msgstr "début du test %s…" # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "test %s : IP résolue = %s" # AI Translated @@ -23175,10 +23198,10 @@ msgid "Printer presets(.zip)" msgstr "Préréglages d’imprimante(.zip)" msgid "Filament presets(.zip)" -msgstr "Présélections de filaments(.zip)" +msgstr "Préréglages de filaments(.zip)" msgid "Process presets(.zip)" -msgstr "Présélections de traitement(.zip)" +msgstr "Préréglages de traitement(.zip)" msgid "initialize fail" msgstr "échec de l’initialisation" @@ -28896,7 +28919,7 @@ msgid "Gizmo FDM paint-on seam" msgstr "Gizmo Peinture de la couture FDM" msgid "Gizmo FDM paint-on fuzzy skin" -msgstr "Outil FDM de surface irrégulière peinte" +msgstr "Gizmo Peinture de la surface irrégulière FDM" msgid "Gizmo multi-material painting" msgstr "Gizmo de peinture multi-matériaux" @@ -28942,7 +28965,7 @@ msgid "Camera view - Top" msgstr "Vue caméra - Haut" msgid "Camera view - Bottom" -msgstr "Vue caméra - Bas" +msgstr "Vue caméra - Dessous" msgid "Camera view - Front" msgstr "Vue de la caméra - Avant" @@ -29899,1231 +29922,1642 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "La liste de filaments actuelle ne contient pas %s. Un filament de projet requis par le filament mixte sera créé automatiquement après la décomposition." msgstr[1] "La liste de filaments actuelle ne contient pas %s. Les filaments de projet requis par le filament mixte seront créés automatiquement après la décomposition." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Sélecteur de couleur" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Couleurs de base" +# AI Translated #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Palette Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Classic" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Dégradés" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Uni" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Dégradé" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Début du dégradé" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Fin du dégradé" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Couleur du dégradé" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Ajouter une couleur" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Supprimer la couleur" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Saturation" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Couleur d’origine" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Enregistrer la couleur actuelle" +# AI Translated msgid "Palettes" -msgstr "" +msgstr "Palettes" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Rechercher des couleurs" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtrer les couleurs" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Aucune couleur correspondante" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Couleur hexadécimale" # AI Translated msgid "Opacity" msgstr "Opacité" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Pourcentage d’opacité" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Enregistrer la couleur" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Saisissez une couleur hexadécimale complète" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "La sélection multicolore actuelle est conservée jusqu’à ce que vous choisissiez une autre couleur." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Jusqu’à %d couleurs prises en charge." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Cramoisi" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Rouge orangé" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Tomate" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Orange" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Orange foncé" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Or" +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier msgid "Burly wood" -msgstr "" +msgstr "Bois de santal" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Bisque" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Rose brumeux" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Jaune clair" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Mousseline de citron" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beige" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Jaune verge d’or clair" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Verge d’or pâle" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Kaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Kaki foncé" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Pêche pâle" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mocassin" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Crème de papaye" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Amande blanchie" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Blanc antique" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Blanc navajo" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Blé" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Verge d’or" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Chocolat" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Pérou" +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier msgid "Fire brick" -msgstr "" +msgstr "Brique réfractaire" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Terre de Sienne" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Brun selle" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Marron" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Brun rosé" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Saumon" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Saumon clair" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Saumon foncé" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Brun sableux" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Corail" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Corail clair" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Rouge indien" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Rouge foncé" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Bordeaux" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Jaune-vert" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Vert jaune" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Vert pelouse" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Vert citron vert" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Vert printemps" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Vert printemps moyen" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Citron vert" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Vert forêt" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Vert foncé" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Brun olive" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Olive" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Vert olive foncé" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Vert pâle" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Vert clair" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Vert marin moyen" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Vert marin" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Vert marin foncé" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Bleu cadet" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Aigue-marine moyen" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turquoise" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Turquoise moyen" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Turquoise foncé" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Turquoise pâle" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Cyan clair" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Crème de menthe" +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier msgid "Honey dew" -msgstr "" +msgstr "Miellat" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Aigue-marine" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Vert marin clair" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Cyan foncé" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Bleu sarcelle" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Gris ardoise foncé" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Gris ardoise clair" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Gris ardoise" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Bleu ciel profond" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Bleu Dodger" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Bleu ciel" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Bleu ciel clair" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Bleu clair" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Bleu poudre" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Bleu acier clair" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Bleu acier" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Bleu bleuet" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Bleu roi" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Bleu moyen" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Bleu nuit" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Bleu foncé" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Bleu marine" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Bleu ardoise" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Bleu ardoise foncé" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Bleu ardoise moyen" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Bleu violet" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Violet foncé" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Orchidée foncé" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Orchidée moyen" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidée" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violet" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Pourpre moyen" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Pourpre" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Pourpre Rebecca" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Rouge violacé moyen" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Rouge violacé pâle" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Rose profond" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Rose vif" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Rose clair" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rose" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Prune" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Chardon" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuchsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Magenta foncé" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lin" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Vieille dentelle" +# AI Translated msgid "Sea shell" -msgstr "" +msgstr "Coquillage" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Ivoire" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Blanc floral" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavande rosée" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Blanc fantôme" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Bleu Alice" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavande" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Fumée blanche" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Noir" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Corail ardent" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Anémone de mer" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Abysse profond" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Rouge homard" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Argile sableuse" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Bois flotté" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Argousier" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Récif au coucher du soleil" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Corail tigre" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Corail rose" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Éclat de coquillage" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Sable" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Varech doré" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Dune ensoleillée" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Nautile ambré" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Citron de mer" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Étoile de mer pâle" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Grande marée" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Algue vert citron" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Herbe marine" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Plancton néon" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Forêt de varech" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Vague émeraude" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Ombre de baleine" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Tortue de mer" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagon" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Courant tropical" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Fosse de minuit" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Varech foncé" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Surf cristallin" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Baie turquoise" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Ciel sur le récif" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Ciel de lagune" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Bleu électrique" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Dauphin" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Profondeurs océaniques" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Baleine" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Abysse indigo" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Oursin" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Corail lavande" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Marée violette" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Orchidée des abysses" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Méduse néon" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Corail fuchsia" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Méduse rose" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Écume" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Blanc coquillage" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Gris galet" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Nuage d’orage" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Noir d’encre" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Beige vert" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Jaune sable" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Jaune de sécurité" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Jaune d’or" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Jaune miel" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Jaune maïs" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Jaune jonquille" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Beige brun" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Jaune citron" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Blanc huître" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Ivoire clair" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Jaune de zinc" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Beige gris" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Jaune olive" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Jaune colza" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Jaune signalisation" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Jaune ocre" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Jaune orangé signalisation" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Jaune melon" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Jaune genêt" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Jaune dahlia" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Jaune pastel" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Beige nacré" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Or nacré" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Jaune soleil" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Orange jaune" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Orange profond" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Vermillon" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Orange nacré" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Orange pur" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Orange lumineux" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Orange vif lumineux" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Orange rouge vif" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Orange signalisation" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Orange de sécurité" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Orange saumon" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Rose nacré" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Orange cuivré" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Brun de sécurité" +# AI Translated msgid "Fir orange" -msgstr "" +msgstr "Orange sapin" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Rouge de sécurité" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Rouge lumineux" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Rouge carmin" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Rouge carmin nacré" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Rouge pur" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Rouge profond lumineux" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Rouge groseille" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Rouge rubis nacré" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Rouge feu" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rouge rubis" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Rouge pourpre" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Rouge vin" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Rouge noir" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Rouge oxyde" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Rouge brun" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Rouge pin" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Rouge tomate" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Rose antique" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Rouge corail" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rose" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Rouge fraise" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Rouge signalisation" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Rose saumon" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Rose lumineux" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Rouge vif lumineux" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Rouge framboise" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Rouge oriental" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Rubis nacré" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Pourpre rouge" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Violet rouge" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Violet bruyère" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Violet bordeaux" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Acajou" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Pourpre gris" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Violet de sécurité" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Vert sapin" +# AI Translated msgid "Sabine grey" -msgstr "" +msgstr "Gris sabine" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Violet nacré" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Mûre nacrée" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Bleu vert" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Bleu outremer" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Bleu saphir" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Bleu noir" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Bleu de sécurité" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Bleu brillant" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Bleu gris" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Bleu azur" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Bleu gentiane" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Bleu cobalt" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Bleu pigeon" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Bleu signalisation" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Bleu turquoise" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Bleu Capri" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Bleu océan" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Bleu eau" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Bleu nuit" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Bleu lointain" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Bleu pastel" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Bleu gentiane nacré" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Bleu nuit nacré" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Vert patine" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Vert émeraude" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Vert feuille" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Vert olive" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Vert bleu" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Vert mousse" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Olive gris" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Vert pin" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Brun pin" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Vert herbe" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Vert réséda" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Vert brun" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Vert roseau" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Vert noir" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Vert turquoise" +# AI Translated msgid "May green" -msgstr "" +msgstr "Vert mai" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Vert oxyde de chrome" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Vert signalisation" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Vert fougère" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Vert opale" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Vert menthe" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Vert bronze" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Vert nacré" +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier msgid "Sax turquoise" -msgstr "" +msgstr "Turquoise saxe" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Turquoise nacré" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Jade nacré" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Vert pur" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Vert lumineux" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Gris écureuil" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Gris argent" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Gris olive" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Gris mousse" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Gris de sécurité" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Gris souris" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Gris beige" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Gris kaki" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Gris vert" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Gris bâche" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Gris fer" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Gris basalte" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Gris brun" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Gris ardoise" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Gris anthracite" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Gris clair" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Gris terre d’ombre" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Gris béton" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Gris graphite" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Gris granit" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Gris pierre" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Gris galet" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Gris ciment" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Gris jaune" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Gris platine" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Gris poussière" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Gris agate" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Gris quartz" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Gris fenêtre" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Gris signalisation A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Gris signalisation B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Gris soie" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Télégris 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Télégris 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Télégris 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Gris souris nacré" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Brun vert" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Brun ocre" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Brun argile" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Brun cuivré" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Brun chocolat" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Brun olive" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Brun noisette" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Brun rouge" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Brun sépia" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Brun châtaigne" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Brun acajou" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Brun gris" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Cuivre nacré" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Brun beige" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Brun moka nacré" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Brun terre" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Brun nacré" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Crème" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Blanc gris" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Blanc de sécurité" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Noir de sécurité" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Noir profond" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Aluminium blanc" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Aluminium gris" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Blanc pur" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Noir graphite" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Blanc signalisation" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Noir signalisation" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Blanc papyrus" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Gris clair nacré" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Métal : argent" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Métal : laiton" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Métal : or" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Métal : cuivre" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Métal : bronze" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Nature : perle" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Nature : arc-en-ciel" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Nature : ciel dégagé" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Nature : coucher de soleil" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Bois : foncé" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Bois : moyen" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Bois : clair" # AI Translated msgid "Alternate nozzles:" @@ -31599,13 +32033,25 @@ msgstr "Retirer de Mes textures" msgid "Built-in" msgstr "Prédéfinies" +# AI Translated +msgid "My textures" +msgstr "Mes textures" + # AI Translated msgid "No textures found." msgstr "Aucune texture trouvée." # AI Translated -msgid "My textures" -msgstr "Mes textures" +msgid "Texture libraries" +msgstr "Bibliothèques de textures" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Explorer d’autres bibliothèques de textures" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Ouvre OrcaCloud dans la page d’accueil pour parcourir les plugins." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32008,11 +32454,13 @@ msgstr "Mappé selon la disposition UV propre au modèle, qui constitue déjà l msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Largeur d’une copie de la texture sur le modèle. Plus elle est petite, plus le motif se répète souvent et plus ses détails sont fins ; avec Mosaïque désactivée, c’est la taille de la copie unique." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Plus grand" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Plus petit" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -32088,11 +32536,13 @@ msgstr "Couleurs mixtes" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Nombre maximal de filaments mixtes qu'une intégration peut ajouter. Ils sont choisis parmi les couleurs de la texture, et seuls ceux réellement utilisés par l'intégration sont créés." +# AI Translated msgid "Few" -msgstr "" +msgstr "Peu" +# AI Translated msgid "Many" -msgstr "" +msgstr "Beaucoup" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -32448,11 +32898,13 @@ msgstr "Remaillage" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Taille des triangles avec laquelle tout le modèle est reconstruit, en millimètres. Le déplacement fonctionne mieux sur un maillage uniforme ; c’est ce qui en crée un à partir d’une importation irrégulière." +# AI Translated msgid "Before" -msgstr "" +msgstr "Avant" +# AI Translated msgid "After" -msgstr "" +msgstr "Après" # AI Translated msgid "Keep sharp edges" @@ -34308,6 +34760,10 @@ msgstr "Script" msgid "Slicing Pipeline" msgstr "Pipeline de découpage" +# AI Translated +msgid "Resource Texture" +msgstr "Texture de ressource" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "L’interface de configuration du plugin était vide. Affichage de l’éditeur par défaut." @@ -34455,6 +34911,30 @@ msgstr "Le répertoire du plugin contient à la fois des fichiers d’entrée .p msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Le répertoire du plugin ne contient aucun fichier d’entrée .py ou .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Le répertoire des textures de ressource n’est pas défini" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Le répertoire des textures de ressource n’a pas pu être résolu" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Le chemin des textures de ressource n’est pas un répertoire" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Le dossier du plugin n’a pas pu être résolu" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Le répertoire des textures de ressource se trouve en dehors du dossier du plugin" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Le répertoire des textures de ressource n’a pas pu être lu" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -34913,7 +35393,7 @@ msgstr "Échec du chargement du fichier de configuration « %1% » : %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Ce n’est pas un fichier G-code généré par %1%." # AI Translated @@ -35033,7 +35513,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Échec de la création d’une copie temporaire du fichier G-code %1% avant l’exécution d’un script de post-traitement : %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Le post-processeur ne trouve pas le fichier G-code exporté" # AI Translated @@ -35163,7 +35643,7 @@ msgid "" "You can switch between Prepare and Preview workspaces by pressing the Tab key." msgstr "" "Changer les espaces de travail\n" -"Vous pouvez alterner entre l’espace de travail Préparer et Aperçu en appuyant sur la touche Tab." +"Vous pouvez alterner entre les espaces de travail Préparer et Aperçu en appuyant sur la touche Tab." #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -35266,7 +35746,7 @@ msgid "" "Split to Objects/Parts\n" "Did you know that you can split a big object into small ones for easy colorizing or printing?" msgstr "" -"Séparer en objets/parties\n" +"Séparer en objets/pièces\n" "Saviez-vous que vous pouvez séparer un gros objet en petits objets pour les colorier ou les imprimer facilement ?" #: resources/data/hints.ini: [hint:Subtract a Part] @@ -35382,7 +35862,7 @@ msgid "" "Did you know that you can use more wall loops and higher sparse infill density to improve the strength of the model?" msgstr "" "Améliorer la solidité\n" -"Saviez-vous que vous pouvez définir un plus grand nombre de périmètre et une densité de remplissage plus élevée pour améliorer la résistance du modèle ?" +"Saviez-vous que vous pouvez définir un plus grand nombre de parois et une densité de remplissage plus élevée pour améliorer la résistance du modèle ?" #: resources/data/hints.ini: [hint:When do you need to print with the printer #: door opened] @@ -35401,6 +35881,41 @@ msgstr "" "Éviter la déformation\n" "Saviez-vous que lors de l’impression de matériaux susceptibles de se déformer, tels que l’ABS, une augmentation appropriée de la température du plateau chauffant peut réduire la probabilité de déformation?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Jaune dalmatien" + +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier +#~ msgid "Capsanthin violet" +#~ msgstr "Violet capsanthine" + +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier +#~ msgid "Olivestone" +#~ msgstr "Pierre d’olive" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Disponible partout dans la fenêtre, même pendant la saisie dans un champ de texte." + +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Les raccourcis globaux s'appliquent aussi pendant la saisie." + +# AI Translated +#~ msgid "Solid" +#~ msgstr "Uni" + +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier +#~ msgid "PaleV violet red" +#~ msgstr "Rouge violacé pâle" + +# AI Translated +# Needs human review: Nom de couleur inhabituel ou source possiblement erronée : vérifier +#~ msgid "Electric bel" +#~ msgstr "Bleu électrique" + #~ msgid "Please choose the filament color" #~ msgstr "Veuillez choisir la couleur du filament" @@ -35869,9 +36384,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "aucun outil configuré" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "G-code de fin lorsque vous avez terminé toute l'impression" - #~ msgid "Maximum X speed" #~ msgstr "Vitesse en X maximale" @@ -35888,25 +36400,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Plugin(s) Python invoqué(s) à chaque étape du pipeline de découpe pour lire et modifier les données de découpe intermédiaires, y compris une étape finale de post-traitement du G-code. Recherche/expérimental." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Si activé, le logiciel de découpe génère un G-code dont le contenu de la zone principale est centré sur l'origine du plateau (0,0). Le firmware de l'imprimante se charge de placer les copies et les images miroir à la position physique de chaque zone. N'activez cette option que sur les imprimantes dont le firmware applique ses propres décalages de zone en mode copie/miroir (par ex. le mode duplication IDEX de RepRapFirmware). Sans effet en mode Principal (Primary)." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Remplacement, par plaque, de la correspondance entre têtes physiques et emplacements de filament (numérotés à partir de 1). Vide signifie utiliser les valeurs par défaut obtenues par inversion de la table pem." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Axe autour duquel le maillage pivote avant le découpage. Il s'agit de l'inclinaison de l'imprimante à tapis : une rotation isométrique (sans distorsion) qui détermine aussi le rendu du plateau et l'inclinaison de la gravité pour les supports, et que la transformation inverse du G-code annule avant le cisaillement/la mise à l'échelle et le remappage dans le repère machine. X correspond à l'inclinaison habituelle du portique (le tapis avance le long de Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Réglage expert : définit l'angle d'inclinaison du repère machine (cisaillement/mise à l'échelle du G-code) indépendamment de l'angle de rotation avant découpage. Si désactivé, la transformation du repère machine est dérivée de l'angle d'inclinaison du tapis, de sorte qu'un seul angle pilote les deux étapes. N'activez cette option que pour compenser une machine dont l'inclinaison physique du portique diffère de la rotation de découpage." - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Écart maximal autorisé lors de la réduction de la résolution pour le paramètre « Résolution maximale des parois ». Si vous l’augmentez, l’impression sera moins exacte, mais le G-code sera plus petit. « Écart maximal des parois » limite « Résolution maximale des parois » ; en cas de conflit entre les deux, « Écart maximal des parois » est prioritaire." - #~ msgid " not in range " #~ msgstr " hors plage " diff --git a/localization/i18n/hu/OrcaSlicer_hu.po b/localization/i18n/hu/OrcaSlicer_hu.po index 612504a77b..29e1b662cf 100644 --- a/localization/i18n/hu/OrcaSlicer_hu.po +++ b/localization/i18n/hu/OrcaSlicer_hu.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -779,18 +779,23 @@ msgstr "Kijelölés" msgid "Plate" msgstr "Tálca" +# AI Translated +# Needs human review: Glossary cell empty for hu; reused the catalog's 'Elosztás' (Distribute left-right etc.) msgid "Distribute" -msgstr "" +msgstr "Elosztás" # AI Translated msgid "Coordinate system used for transform actions." msgstr "A transzformációs műveletekhez használt koordináta-rendszer." +# AI Translated +# Needs human review: Tooltip in the object manipulation panel; check it reads right next to the align buttons msgid "Reference for alignment" -msgstr "" +msgstr "Igazítás referenciája" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Válassz ki legalább 3 tárgyat vagy objektumot" # AI Translated msgid "Align left" @@ -844,8 +849,9 @@ msgstr "Elosztás fel-le irányban" msgid "Drop" msgstr "Lehelyezés" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "A kijelölés mozgatása Z mentén úgy, hogy a legalacsonyabb pontja érintse az asztalt." # AI Translated msgid "Absolute" @@ -1743,7 +1749,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Az alakzat körvonala (%1%) nem támogatott elemet tartalmaz: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Érvénytelen állapot, kérlek, jelentsd a reprodukálás lépéseit a GitHubon" # AI Translated @@ -1751,11 +1757,11 @@ msgid "No embossed file" msgstr "Nincs dombornyomott fájl" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Hiányzik az SVG fájl a dombornyomott alakzatból" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Hiányoznak az SVG fájl adatai" msgid "Face the camera" @@ -2081,17 +2087,21 @@ msgstr "Belépés az összeállítás gizmóba" msgid "Leaving Assembly gizmo" msgstr "Kilépés az összeállítás gizmóból" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "A vágott objektum tárgyai nem mozgathatók" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "A tálcához igazítás csak X és Y irányban érhető el" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Kapcsold ki a kijelölt objektumok automatikus leejtését, hogy Z irányban mozgathasd őket" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Az összes kijelölt objektumnak ugyanazon a tálcán kell lennie" msgid "Shift+" msgstr "Shift+" @@ -4984,7 +4994,7 @@ msgid "Unknown C++ exception." msgstr "Ismeretlen C++ kivétel." # AI Translated -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "G-code feldolgozása egy előző fájlból..." msgid "Slicing complete" @@ -6533,8 +6543,10 @@ msgstr "Tengelyek" msgid "Gridlines" msgstr "Rácsvonalak" +# AI Translated +# Needs human review: Glossary cell empty for hu; check the term for this view mode msgid "Focus mode" -msgstr "" +msgstr "Fókuszmód" msgid "Labels" msgstr "Címkék" @@ -6596,7 +6608,7 @@ msgid "Size:" msgstr "Méret:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "G-code útvonalütközés található a(z) %d. rétegen, Z = %.2lfmm. Helyezd távolabb egymástól az ütköző objektumokat (%s <-> %s)." @@ -10947,11 +10959,13 @@ msgstr "Nem támogatott beállítások megjelenítése" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Megjeleníti a nem kompatibilis vagy nem támogatott beállításokat a nyomtató- és filamentlegördülő listákban. Ezek a beállítások nem választhatók ki." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Statisztika exportálása G-code-dal" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Ha be van kapcsolva, a G-code fájl exportálásakor annak statisztikája is JSON-ként kiíródik mellé .statistics.json néven, az exportált szeletelt 3MF fájl pedig belül tartalmazza: a nyomtatási időt, a filament- és vonaltípus-összesítőket, valamint ugyanezeket rétegenként és objektumonként." # AI Translated msgid "Experimental Features" @@ -11819,6 +11833,10 @@ msgstr "Nem sikerült feltölteni a fájlt a nyomtató tárhelyére. Próbáld msgid "Send Failed" msgstr "Sikertelen küldés" +# AI Translated +msgid "No available printers" +msgstr "Nincs elérhető nyomtató" + msgid "The name length exceeds the limit." msgstr "A név hossza meghaladja a korlátot." @@ -13688,8 +13706,8 @@ msgid "Left mouse" msgstr "Bal egérgomb" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Az ablakban bárhol elérhető, szövegmezőbe gépelés közben is." +msgid "Available anywhere in the window." +msgstr "Az ablak bármely pontján elérhető." # AI Translated msgid "Run favorite 1 to 10" @@ -13801,10 +13819,6 @@ msgstr "A(z) %s ehhez van rendelve: %s. Átrendeled ehhez: %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Az alapértelmezett %s ehhez van rendelve: %s. Átrendeled ehhez: %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "A globális gyorsbillentyűk gépelés közben is működnek." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Karaktert beíró billentyű nem lehet globális gyorsbillentyű." @@ -14259,9 +14273,10 @@ msgstr "a(z) \"%2%\" \"%1%\" módosítója (összesen %3%) nem volt hatással a msgid "Seam placement may differ from expected." msgstr "A varrat elhelyezése eltérhet a várttól." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Nem sikerült a G-code statisztikát a(z) %1% helyre írni." msgid "Internal Bridge" msgstr "Belső híd" @@ -17679,6 +17694,14 @@ msgstr "Tárgyak kizárása" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Engedélyezd ezt az opciót, hogy EXCLUDE OBJECT parancs kerüljön a G-code-ba." +# AI Translated +msgid "Outline tolerance" +msgstr "Körvonal tűrése" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Az EXCLUDE_OBJECT_DEFINE-ba írt objektumkörvonal legnagyobb megengedett eltérése az eredeti körvonaltól. Nagyobb értékeknél kevesebb pont keletkezik, ami segít azokon a firmware-eken, amelyek sok objektumot tartalmazó G-code feldolgozásakor megakadnak. A 0 minden pontot megtart." + # AI Translated msgid "Verbose G-code" msgstr "Bővebb G-code" @@ -20918,11 +20941,13 @@ msgstr "Kimeneti mappa" msgid "This is the output directory for exported files." msgstr "Az exportált fájlok kimeneti mappája." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Statisztika exportálása" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Minden szeletelt tálca statisztikáját JSON-ként írja ki: plate_N.statistics.json néven a G-code mellé a kimeneti mappába, valamint az --export-3mf által írt 3MF fájlba: nyomtatási idő, filament- és vonaltípus-összesítők, valamint ugyanezek rétegenként és objektumonként." msgid "Debug level" msgstr "Hibakeresés szintje" @@ -23346,7 +23371,7 @@ msgstr "%s tesztelése indul..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "%s tesztelése: IP feloldva = %s" # AI Translated @@ -30840,1231 +30865,1645 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "A jelenlegi filamentlista nem tartalmazza ezt: %s. A kevert filamenthez szükséges projektfilament a szétbontás után automatikusan létrejön." msgstr[1] "A jelenlegi filamentlista nem tartalmazza ezt: %s. A kevert filamenthez szükséges projektfilamentek a szétbontás után automatikusan létrejönnek." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Színválasztó" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Alapszínek" +# AI Translated +# Needs human review: Glossary cell for Palette empty for hu; 'paletta' used #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca paletta" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Klasszikus" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Színátmenetek" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Egyszínű" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Színátmenet" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Színátmenet kezdete" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Színátmenet vége" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Színátmenet színe" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Szín hozzáadása" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Szín eltávolítása" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Telítettség" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Eredeti szín" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Jelenlegi szín mentése" +# AI Translated +# Needs human review: Glossary cell for Palette empty for hu; 'paletta' used msgid "Palettes" -msgstr "" +msgstr "Paletták" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Színek keresése" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Színek szűrése" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Nincs egyező szín" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Hex szín" # AI Translated msgid "Opacity" msgstr "Átlátszatlanság" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Átlátszatlanság (%)" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Szín mentése" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Adj meg egy teljes hexadecimális színkódot" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "A jelenlegi többszínű kijelölés megmarad, amíg másik színt nem választasz." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Legfeljebb %d szín támogatott." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmazsin" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Narancsvörös" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Paradicsom" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Narancs" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Sötét narancs" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Arany" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Fabarna" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Biszkvit" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Ködös rózsa" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Világossárga" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Citromhab" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Bézs" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Világos aranyvesszősárga" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Halvány aranyvessző" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Khaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Sötét khaki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Barackhab" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mokaszin" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papayakrém" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Hámozott mandula" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antik fehér" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navajo fehér" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Búza" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Aranyvessző" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Csokoládé" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Téglavörös" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Nyeregbarna" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Barna" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Rózsás barna" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Lazac" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Világos lazac" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Sötét lazac" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Homokbarna" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Korall" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Világos korall" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Indiánvörös" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Sötétvörös" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Bordó" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Zöldessárga" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Sárgászöld" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Gyepzöld" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Limezöld" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Tavaszi zöld" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Közepes tavaszi zöld" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Lime" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Erdőzöld" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Sötétzöld" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Tompa olívazöld" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Olíva" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Sötét olívazöld" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Halványzöld" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Világoszöld" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Közepes tengerzöld" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Tengerzöld" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Sötét tengerzöld" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Kadétkék" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Közepes akvamarin" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Türkiz" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Közepes türkiz" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Sötét türkiz" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Halvány türkiz" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Világos cián" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Mentakrém" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Mézharmat" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Akvamarin" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Világos tengerzöld" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Sötét cián" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Pávakék" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Sötét palaszürke" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Világos palaszürke" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Palaszürke" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Mély égkék" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodger-kék" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Égkék" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Világos égkék" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Világoskék" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Púderkék" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Világos acélkék" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Acélkék" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Búzavirágkék" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Királykék" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Közepes kék" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Éjkék" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Sötétkék" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Tengerészkék" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Palakék" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Sötét palakék" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Közepes palakék" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Kékibolya" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigó" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Sötét ibolya" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Sötét orchidea" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Közepes orchidea" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidea" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Ibolya" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Közepes lila" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Lila" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebecca-lila" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Közepes ibolyavörös" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Halvány ibolyavörös" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Mély rózsaszín" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Élénk rózsaszín" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Világos rózsaszín" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rózsaszín" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Szilva" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Bogáncs" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fukszia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Sötét magenta" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Vászon" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Régi csipke" +# AI Translated +# Needs human review: CSS color 'seashell'; Shell glossary warning is a false match (not the print shell) msgid "Sea shell" -msgstr "" +msgstr "Kagyló" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Elefántcsont" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Virágfehér" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Levendulapír" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Szellemfehér" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Alice-kék" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Levendula" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Füstfehér" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Fekete" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Korallparázs" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Tengerirózsa" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Mély szakadék" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Homárvörös" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Homokos agyag" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Uszadékfa" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Homoktövis" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Naplementés zátony" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tigriskorall" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Rózsaszín korall" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Kagylófény" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Homok" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Arany moszat" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Napsütötte dűne" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Borostyán nautilus" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Tengeri citrom" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Halvány tengericsillag" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Tavaszi dagály" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Limezöld alga" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Tengeri fű" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neon plankton" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Moszaterdő" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Smaragd hullám" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Bálnaárnyék" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Tengeri teknős" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagúna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Trópusi áramlat" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Éjféli árok" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Sötét moszat" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Kristályhullám" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Türkiz öböl" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Zátony feletti ég" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Sekélyvízi ég" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektromos kék" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfin" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Óceánmélység" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Bálna" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indigó szakadék" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Tengeri sün" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Levendula korall" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Ibolya dagály" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Mélytengeri orchidea" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neon medúza" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fukszia korall" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Rózsaszín medúza" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Hab" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Kagylófehér" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Kavicsszürke" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Viharfelhő" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Tintafekete" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Zöldesbézs" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Homoksárga" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Jelzősárga" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Aranysárga" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Mézsárga" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Kukoricasárga" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Nárciszsárga" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Barnabézs" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Citromsárga" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Osztrigafehér" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Világos elefántcsont" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Cinksárga" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Szürkebézs" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Olívasárga" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Repcesárga" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Forgalmi sárga" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Okkersárga" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Forgalmi narancssárga" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Dinnyesárga" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Rekettyesárga" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Dáliasárga" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pasztellsárga" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Gyöngybézs" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Gyöngyarany" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Napsárga" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Sárgásnarancs" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Mély narancs" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Cinóber" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Gyöngynarancs" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Tiszta narancs" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Világító narancs" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Világító élénk narancs" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Élénk vörösnarancs" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Forgalmi narancs" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Jelzőnarancs" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Lazacnarancs" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Gyöngyrózsaszín" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Réznarancs" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Jelzőbarna" +# AI Translated +# Needs human review: RAL 2018 name; 'Fir' rendered as jegenyefenyő; check against the Hungarian RAL chart msgid "Fir orange" -msgstr "" +msgstr "Jegenyefenyő-narancs" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Jelzővörös" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Világító vörös" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karminvörös" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Gyöngykarminvörös" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Tiszta vörös" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Világító mélyvörös" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Ribizlivörös" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Gyöngyrubinvörös" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Tűzvörös" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rubinvörös" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Lilásvörös" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Borvörös" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Feketésvörös" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oxidvörös" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Barnásvörös" +# AI Translated +# Needs human review: RAL 3012 name; check against the Hungarian RAL chart msgid "Pine red" -msgstr "" +msgstr "Fenyővörös" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Paradicsomvörös" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Antik rózsaszín" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Korallvörös" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rózsa" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Epervörös" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Forgalmi vörös" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Lazacrózsaszín" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Világító rózsa" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Világító élénkvörös" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Málnavörös" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Keleti vörös" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Gyöngyrubin" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Vöröslila" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Vörösibolya" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Hangaibolya" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordóibolya" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Mahagóni" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Szürkéslila" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Jelzőibolya" +# AI Translated +# Needs human review: Used for both RAL 4009 and 6009 (source reuses one msgid); check against the Hungarian RAL chart msgid "Fir green" -msgstr "" +msgstr "Jegenyefenyő-zöld" +# AI Translated +# Needs human review: RAL 4010 name (a violet-grey); unclear source term, check against the Hungarian RAL chart msgid "Sabine grey" -msgstr "" +msgstr "Szabin szürke" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Gyöngyibolya" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Gyöngyszeder" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Zöldeskék" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarinkék" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Zafírkék" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Feketéskék" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Jelzőkék" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Ragyogó kék" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Szürkéskék" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azúrkék" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Enciánkék" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobaltkék" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Galambkék" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Forgalmi kék" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Türkizkék" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Caprikék" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Óceánkék" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Vízkék" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Éjszakai kék" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Távoli kék" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pasztellkék" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Gyöngyenciánkék" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Gyöngyéjkék" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patinazöld" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Smaragdzöld" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Levélzöld" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Olívazöld" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Kékeszöld" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Mohazöld" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Szürkeolíva" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Fenyőzöld" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Fenyőbarna" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Fűzöld" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Rezedazöld" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Barnászöld" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Nádzöld" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Feketészöld" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Türkizzöld" +# AI Translated msgid "May green" -msgstr "" +msgstr "Májusi zöld" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Krómoxidzöld" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Forgalmi zöld" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Páfránzöld" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opálzöld" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Mentazöld" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Bronzzöld" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Gyöngyzöld" +# AI Translated msgid "Sax turquoise" -msgstr "" +msgstr "Szász türkiz" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Gyöngytürkiz" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Gyöngyjáde" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Tiszta zöld" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Világító zöld" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Mókusszürke" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Ezüstszürke" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Olívaszürke" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Mohaszürke" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Jelzőszürke" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Egérszürke" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Bézsszürke" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Khakiszürke" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Zöldesszürke" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Ponyvaszürke" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Vasszürke" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Bazaltszürke" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Barnásszürke" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Palaszürke" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antracitszürke" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Világosszürke" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umbraszürke" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Betonszürke" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafitszürke" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Gránitszürke" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Kőszürke" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Kavicsszürke" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Cementszürke" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Sárgásszürke" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platinaszürke" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Porszürke" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Achátszürke" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Kvarcszürke" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Ablakszürke" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Forgalmi szürke A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Forgalmi szürke B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Selyemszürke" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Távközlési szürke 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Távközlési szürke 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Távközlési szürke 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Gyöngyegérszürke" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Zöldesbarna" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Okkerbarna" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Agyagbarna" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Rézbarna" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Csokoládébarna" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Olívabarna" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Dióbarna" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Vörösesbarna" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Szépiabarna" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Gesztenyebarna" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Mahagónibarna" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Szürkésbarna" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Gyöngyréz" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Bézsbarna" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Gyöngymokkabarna" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Földbarna" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Gyöngybarna" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Krém" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Szürkésfehér" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Jelzőfehér" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Jelzőfekete" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Koromfekete" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Fehér alumínium" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Szürke alumínium" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Tiszta fehér" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Grafitfekete" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Forgalmi fehér" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Forgalmi fekete" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papiruszfehér" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Gyöngyvilágosszürke" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Fém: Ezüst" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Fém: Sárgaréz" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Fém: Arany" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Fém: Réz" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Fém: Bronz" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Természet: Gyöngy" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Természet: Szivárvány" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Természet: Derült ég" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Természet: Naplemente" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Fa: Sötét" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Fa: Közepes" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Fa: Világos" # AI Translated msgid "Alternate nozzles:" @@ -32541,13 +32980,25 @@ msgstr "Eltávolítás a Saját textúrák közül" msgid "Built-in" msgstr "Beépített" +# AI Translated +msgid "My textures" +msgstr "Saját textúrák" + # AI Translated msgid "No textures found." msgstr "Nem található textúra." # AI Translated -msgid "My textures" -msgstr "Saját textúrák" +msgid "Texture libraries" +msgstr "Textúratárak" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "További textúratárak felfedezése" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Megnyitja az OrcaCloudot a Kezdőlapon a bővítmények böngészéséhez." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32950,11 +33401,15 @@ msgstr "A modell saját UV-elrendezése szerint leképezve, ami már maga az elh msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "A textúra egy példányának szélessége a modellen. Kisebb értéknél a minta gyakrabban ismétlődik, és a részletei finomabbak; kikapcsolt Csempézésnél ez az egyetlen példány mérete." +# AI Translated +# Needs human review: Caption under a tile-size picture in the Texture displacement gizmo; check it fits msgid "Larger" -msgstr "" +msgstr "Nagyobb" +# AI Translated +# Needs human review: Caption under a tile-size picture in the Texture displacement gizmo; check it fits msgid "Smaller" -msgstr "" +msgstr "Kisebb" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33030,11 +33485,15 @@ msgstr "Kevert színek" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "A beégetés által legfeljebb hozzáadható kevert filamentek száma. A textúra színeiből választódnak ki, és csak azok jönnek létre, amelyeket a beégetés ténylegesen használ." +# AI Translated +# Needs human review: Caption under a mixed-colors picture in the Texture displacement gizmo; check it fits msgid "Few" -msgstr "" +msgstr "Kevés" +# AI Translated +# Needs human review: Caption under a mixed-colors picture in the Texture displacement gizmo; check it fits msgid "Many" -msgstr "" +msgstr "Sok" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33390,11 +33849,15 @@ msgstr "Újrahálózás" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Háromszögméret, amellyel a teljes modell újraépül, milliméterben. A domborítás egyenletes hálón működik a legjobban; ez készít ilyet egy egyenetlen importált modellből." +# AI Translated +# Needs human review: Caption under the remesh before/after picture; check it fits msgid "Before" -msgstr "" +msgstr "Előtte" +# AI Translated +# Needs human review: Caption under the remesh before/after picture; check it fits msgid "After" -msgstr "" +msgstr "Utána" # AI Translated msgid "Keep sharp edges" @@ -35272,6 +35735,10 @@ msgstr "Szkript" msgid "Slicing Pipeline" msgstr "Szeletelési folyamat" +# AI Translated +msgid "Resource Texture" +msgstr "Erőforrás-textúra" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "A bővítmény konfigurációs felülete üres volt. Az alapértelmezett szerkesztő jelenik meg." @@ -35419,6 +35886,30 @@ msgstr "A bővítmény könyvtára .py és .whl belépési fájlt is tartalmaz" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "A bővítmény könyvtára nem tartalmaz .py vagy .whl belépési fájlt" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Az erőforrás-textúra mappája nincs megadva" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Az erőforrás-textúra mappáját nem sikerült feloldani" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Az erőforrás-textúra útvonala nem mappa" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "A bővítmény mappáját nem sikerült feloldani" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Az erőforrás-textúra mappája a bővítmény mappáján kívül van" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Az erőforrás-textúra mappáját nem sikerült beolvasni" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -35877,7 +36368,7 @@ msgstr "Nem sikerült betölteni a(z) \"%1%\" konfigurációs fájlt: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Nem a(z) %1% által generált G-code fájl." # AI Translated @@ -35997,7 +36488,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Nem sikerült ideiglenes másolatot készíteni a(z) %1% G-code fájlról az utófeldolgozó szkript futtatása előtt: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Az utófeldolgozó nem találja az exportált G-code fájlt" # AI Translated @@ -36367,6 +36858,27 @@ msgstr "" "Kunkorodás elkerülése\n" "Tudtad, hogy a kunkorodásra hajlamos anyagok (például ABS) nyomtatásakor az asztal hőmérsékletének növelése csökkentheti a kunkorodás valószínűségét?" +# AI Translated +# Needs human review: Source likely a typo for RAL 1007 Daffodil yellow; translated as daffodil +#~ msgid "Dalmatian yellow" +#~ msgstr "Nárciszsárga" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Kapszantinibolya" + +# AI Translated +#~ msgid "Olivestone" +#~ msgstr "Olívakő" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Az ablakban bárhol elérhető, szövegmezőbe gépelés közben is." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "A globális gyorsbillentyűk gépelés közben is működnek." + #~ msgid "Please choose the filament color" #~ msgstr "Kérlek, válaszd ki a filament színét" @@ -36845,10 +37357,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "nincs beállított szerszám" -# AI Translated -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Befejező G-code az egész nyomtatás befejezésekor" - #~ msgid "Maximum X speed" #~ msgstr "Maximális X sebesség" @@ -36865,26 +37373,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "A szeletelési folyamat minden lépésénél meghívott Python bővítmény(ek), amelyek beolvassák és módosítják a köztes szeletelési adatokat, beleértve egy záró G-code utófeldolgozási lépést is. Kutatási/kísérleti célra." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Ha engedélyezve van, a szeletelő úgy állítja elő a G-code-ot, hogy az elsődleges zóna tartalma az asztal origójára (0,0) van középre igazítva. A másolatok/tükörképek elhelyezése az egyes fizikai zónapozíciókba a nyomtató firmware-ének feladata. Csak olyan nyomtatókon engedélyezd, amelyek firmware-e másolat/tükör módban saját zónaeltolásokat alkalmaz (pl. RepRapFirmware IDEX duplikációs mód). Elsődleges (Primary) módban nincs hatása." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Tálcánkénti felülbírálás, amely a fizikai fejeket filamenthelyekhez rendeli (1-től számozva). Üresen a pem-inverzióból származó alapértelmezéseket használja." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Az a tengely, amely körül a háló szeletelés előtt elfordul. Ez a szalagos nyomtató dőlése: izometrikus (torzításmentes) forgatás, amely az asztal megjelenítését és a támaszok gravitációs dőlését is meghatározza, és amelyet a G-code visszatranszformáció megfordít a gépi koordináta-rendszerbe történő nyírás/skálázás és tengelyleképezés előtt. Jellemzően X a portál dőlési tengelye (a szalag Y irányban halad)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Szakértői felülbírálás: a gépi koordináta-rendszer (G-code nyírás/skálázás) dőlésszöge a szeletelés előtti forgatási szögtől függetlenül állítható be. Ha ki van kapcsolva, a gépi koordináta-rendszer transzformációja a szalag dőlésszögéből származik, így egyetlen szög vezérli mindkét lépést. Csak akkor engedélyezd, ha olyan gépet kell kompenzálni, amelynek fizikai portáldőlése eltér a szeletelési forgatástól." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "A megengedett legnagyobb eltérés a „Maximális falfelbontás” beállítás felbontásának csökkentésekor. Ha ezt növeled, a nyomtatás kevésbé lesz pontos, de a G-code kisebb lesz. A „maximális faleltérés” korlátozza a „maximális falfelbontást”, így ha a kettő ütközik, a „Maximális faleltérés” élvez elsőbbséget." - #~ msgid " not in range " #~ msgstr " nincs a tartományban " diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index 960cbf4bec..8fe101ae71 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -784,18 +784,22 @@ msgstr "Selezione" msgid "Plate" msgstr "Piatto" +# AI Translated +# Needs human review: Distribute has no glossary rendering yet; check the term. msgid "Distribute" -msgstr "" +msgstr "Distribuisci" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Sistema di coordinate utilizzato per le azioni di trasformazione." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Riferimento per l'allineamento" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Seleziona almeno 3 parti o oggetti" # AI Translated msgid "Align left" @@ -848,8 +852,9 @@ msgstr "Distribuisci alto-basso" msgid "Drop" msgstr "Lascia" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Sposta la selezione lungo Z in modo che il suo punto più basso tocchi il piatto." # AI Translated msgid "Absolute" @@ -1749,7 +1754,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Il tratto della forma (%1%) contiene un'immagine non supportata: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Stato non valido, segnala su GitHub i passaggi per riprodurlo" # AI Translated @@ -1757,11 +1762,11 @@ msgid "No embossed file" msgstr "Nessun file in rilievo" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "File SVG mancante nella forma in rilievo" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Dati del file SVG mancanti" msgid "Face the camera" @@ -2090,17 +2095,21 @@ msgstr "Attivazione strumento Assemblaggio" msgid "Leaving Assembly gizmo" msgstr "Uscita dallo strumento Assemblaggio" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Le parti di un oggetto tagliato non possono essere spostate" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "L'allineamento al piatto è disponibile solo in X e Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Disattiva il Rilascio automatico per gli oggetti selezionati per spostarli in Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Tutti gli oggetti selezionati devono trovarsi sullo stesso piatto" msgid "Shift+" msgstr "Maiusc+" @@ -4975,7 +4984,7 @@ msgstr "Salva il progetto e riavvia l'applicazione." msgid "Unknown C++ exception." msgstr "Eccezione C++ sconosciuta." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Elaborazione G-Code dal file precedente..." msgid "Slicing complete" @@ -6507,8 +6516,10 @@ msgstr "Assi" msgid "Gridlines" msgstr "Linee griglia" +# AI Translated +# Needs human review: Name of a view mode hiding the surrounding UI; glossary cell is empty, check the term. msgid "Focus mode" -msgstr "" +msgstr "Modalità focus" msgid "Labels" msgstr "Etichette" @@ -6570,7 +6581,7 @@ msgstr "Volume:" msgid "Size:" msgstr "Dimensione:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Sono stati trovati conflitti di percorsi nel G-code sullo strato %d, Z = %.2lfmm. Si prega di separare gli oggetti in conflitto (%s <-> %s)." @@ -10918,11 +10929,13 @@ msgstr "Mostra i profili non supportati" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Mostra i profili incompatibili/non supportati negli elenchi a discesa di stampante e filamento. Questi profili non possono essere selezionati." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Esporta statistiche con il G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Se attivato, l'esportazione di un file G-code scrive anche le sue statistiche come JSON accanto ad esso, come .statistics.json, e un file 3MF elaborato esportato le contiene al suo interno: tempo di stampa, totali di filamento e per tipo linea, e gli stessi dati per strato e per oggetto." # AI Translated msgid "Experimental Features" @@ -11785,6 +11798,10 @@ msgstr "Caricamento del file nella memoria della stampante non riuscito. Riprova msgid "Send Failed" msgstr "Invio non riuscito" +# AI Translated +msgid "No available printers" +msgstr "Nessuna stampante disponibile" + msgid "The name length exceeds the limit." msgstr "La lunghezza del nome supera il limite." @@ -13616,8 +13633,8 @@ msgid "Left mouse" msgstr "Tasto sinistro mouse" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Disponibile ovunque nella finestra, anche durante la digitazione in un campo di testo." +msgid "Available anywhere in the window." +msgstr "Disponibile in qualsiasi punto della finestra." # AI Translated msgid "Run favorite 1 to 10" @@ -13729,10 +13746,6 @@ msgstr "%s è assegnato a %s. Riassegnarlo a %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Il tasto predefinito %s è assegnato a %s. Riassegnarlo a %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Le scorciatoie globali valgono anche durante la digitazione." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Un tasto che digita un carattere non può essere una scorciatoia globale." @@ -14181,9 +14194,10 @@ msgstr "il modificatore \"%1%\" di \"%2%\" (%3% in totale) non ha avuto effetto msgid "Seam placement may differ from expected." msgstr "Il posizionamento della cucitura potrebbe differire da quanto previsto." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Impossibile scrivere le statistiche del G-code in %1%." msgid "Internal Bridge" msgstr "Ponte interno" @@ -17575,6 +17589,14 @@ msgstr "Escludi oggetti" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Abilita questa opzione per aggiungere il comando EXCLUDE OBJECT nel G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Tolleranza del contorno" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Deviazione massima del contorno dell'oggetto scritto in EXCLUDE_OBJECT_DEFINE rispetto al contorno originale. Valori più alti producono meno punti, il che aiuta il firmware che si blocca durante l'analisi di G-code con molti oggetti. 0 mantiene tutti i punti." + msgid "Verbose G-code" msgstr "G-code verboso" @@ -20784,11 +20806,13 @@ msgstr "Cartella di destinazione" msgid "This is the output directory for exported files." msgstr "Questa è la cartella di destinazione per i file esportati." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Esporta statistiche" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Scrive le statistiche di ogni piatto elaborato come JSON, come plate_N.statistics.json accanto al suo G-code nella directory di output e all'interno del 3MF di --export-3mf: tempo di stampa, totali di filamento e per tipo linea, e gli stessi dati per strato e per oggetto." msgid "Debug level" msgstr "Livello di debug" @@ -23205,7 +23229,7 @@ msgstr "avvio test %s..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "test %s IP risolto = %s" # AI Translated @@ -30696,1231 +30720,1648 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "L'elenco filamenti attuale non contiene %s. Dopo la scomposizione verrà creato automaticamente un filamento del progetto richiesto dal filamento misto." msgstr[1] "L'elenco filamenti attuale non contiene %s. Dopo la scomposizione verranno creati automaticamente i filamenti del progetto richiesti dal filamento misto." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Selettore colore" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Colori di base" +# AI Translated +# Needs human review: Palette has no glossary rendering yet; check the term. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Tavolozza Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Classic" + +# AI Translated +# Needs human review: Gradient has no glossary rendering in this language; used the catalog's color-gradient term. msgid "Gradients" -msgstr "" +msgstr "Gradienti" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Tinta unita" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Gradiente" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Inizio del gradiente" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Fine del gradiente" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Colore del gradiente" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Aggiungi colore" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Rimuovi colore" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Saturazione" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Colore originale" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Salva colore attuale" +# AI Translated +# Needs human review: Palette has no glossary rendering yet; check the term. msgid "Palettes" -msgstr "" +msgstr "Tavolozze" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Cerca colori" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtra colori" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Nessun colore corrispondente" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Colore esadecimale" # AI Translated msgid "Opacity" msgstr "Opacità" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Percentuale di opacità" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Salva colore" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Inserisci un colore esadecimale completo" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "La selezione multicolore attuale viene mantenuta finché non scegli un altro colore." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Sono supportati fino a %d colori." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Cremisi" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Rosso arancione" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Pomodoro" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Arancione" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Arancione scuro" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Oro" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Legno chiaro" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Biscotto" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Rosa nebbia" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Giallo chiaro" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Chiffon limone" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beige" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Giallo verga d'oro chiaro" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Verga d'oro pallido" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Cachi" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Cachi scuro" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Pesca tenue" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mocassino" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Crema di papaya" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Mandorla sbollentata" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Bianco antico" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Bianco navajo" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Grano" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Verga d'oro" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Cioccolato" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Perù" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Mattone refrattario" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Terra di Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Marrone cuoio" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Marrone" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Marrone rosato" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Salmone" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Salmone chiaro" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Salmone scuro" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Marrone sabbia" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Corallo" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Corallo chiaro" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Rosso indiano" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Rosso scuro" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Bordeaux" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Verde giallastro" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Giallo verdastro" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Verde prato" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Verde lime" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Verde primavera" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Verde primavera medio" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Lime" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Verde foresta" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Verde scuro" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Verde oliva opaco" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliva" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Verde oliva scuro" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Verde pallido" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Verde chiaro" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Verde mare medio" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Verde mare" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Verde mare scuro" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Blu cadetto" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Acquamarina medio" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turchese" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Turchese medio" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Turchese scuro" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Turchese pallido" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Acqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Ciano chiaro" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Crema di menta" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Rugiada di miele" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Acquamarina" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Verde mare chiaro" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Ciano scuro" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Verde petrolio" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Grigio ardesia scuro" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Grigio ardesia chiaro" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Grigio ardesia" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Celeste intenso" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Blu Dodger" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Celeste" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Celeste chiaro" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Blu chiaro" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Blu polvere" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Blu acciaio chiaro" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Blu acciaio" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Blu fiordaliso" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Blu reale" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Blu medio" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Blu mezzanotte" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Blu scuro" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Blu navy" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Blu ardesia" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Blu ardesia scuro" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Blu ardesia medio" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Blu violaceo" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indaco" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Violetto scuro" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Orchidea scura" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Orchidea media" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidea" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violetto" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Porpora medio" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Porpora" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Porpora Rebecca" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Rosso violetto medio" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Rosso violetto pallido" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Rosa intenso" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Rosa acceso" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Rosa chiaro" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rosa" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Prugna" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Cardo" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fucsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Magenta scuro" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lino" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Pizzo antico" +# AI Translated +# Needs human review: CSS color Seashell (a sea shell); glossary Shell warning is a false match. msgid "Sea shell" -msgstr "" +msgstr "Conchiglia" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Avorio" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Bianco floreale" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavanda rosata" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Bianco fantasma" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Blu Alice" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavanda" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Fumo bianco" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Nero" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Fuoco di corallo" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Anemone di mare" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Abisso profondo" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Rosso aragosta" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Argilla sabbiosa" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Legno di mare" +# AI Translated +# Needs human review: Ocean-themed color name; check the plant name. msgid "Sea buckthorn" -msgstr "" +msgstr "Olivello spinoso" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Barriera al tramonto" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Corallo tigre" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Corallo rosa" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Bagliore di conchiglia" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Sabbia" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Kelp dorato" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Duna al sole" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Nautilus ambra" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Limone di mare" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Stella marina pallida" +# AI Translated +# Needs human review: Ocean-themed color name; check the sense (tide vs spring season). msgid "Spring tide" -msgstr "" +msgstr "Marea di primavera" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Alga lime" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Erba marina" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Plancton neon" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Foresta di kelp" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Onda smeraldo" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Ombra di balena" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Tartaruga marina" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Laguna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Corrente tropicale" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Fossa di mezzanotte" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Kelp scuro" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Risacca cristallina" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Baia turchese" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Cielo sopra la barriera" +# AI Translated +# Needs human review: Ocean-themed color name; check it reads as a pale sky blue. msgid "Shallow sky" -msgstr "" +msgstr "Cielo di acque basse" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Blu elettrico" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfino" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Profondità oceaniche" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Balena" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Abisso indaco" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Riccio di mare" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Corallo lavanda" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Marea violetta" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Orchidea di mare profondo" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Medusa neon" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Corallo fucsia" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Medusa rosa" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Schiuma" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Bianco conchiglia" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Grigio ciottolo" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Nuvola temporalesca" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Nero inchiostro" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Beige verdastro" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Giallo sabbia" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Giallo segnale" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Giallo oro" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Giallo miele" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Giallo mais" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Giallo narciso" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Beige brunastro" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Giallo limone" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Bianco ostrica" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Avorio chiaro" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Giallo zinco" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Beige grigiastro" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Giallo oliva" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Giallo colza" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Giallo traffico" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Giallo ocra" +# AI Translated +# Needs human review: RAL name; unusual source name, translated by its parts. msgid "Traffic orange yellow" -msgstr "" +msgstr "Giallo arancione traffico" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Giallo melone" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Giallo ginestra" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Giallo dalia" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Giallo pastello" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Beige perlato" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Oro perlato" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Giallo sole" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Arancione giallastro" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Arancione intenso" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Vermiglio" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Arancione perlato" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Arancione puro" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Arancione luminoso" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Arancione chiaro luminoso" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Rosso arancione chiaro" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Arancione traffico" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Arancione segnale" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Arancione salmone" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Rosa perlato" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Arancione rame" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Marrone segnale" +# AI Translated +# Needs human review: RAL name; 'Fir orange' looks odd in the source, translated literally. msgid "Fir orange" -msgstr "" +msgstr "Arancione abete" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Rosso segnale" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Rosso luminoso" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Rosso carminio" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Rosso carminio perlato" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Rosso puro" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Rosso intenso luminoso" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Rosso ribes" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Rosso rubino perlato" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Rosso fuoco" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rosso rubino" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Rosso porpora" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Rosso vino" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Rosso nerastro" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Rosso ossido" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Rosso brunastro" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Rosso pino" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Rosso pomodoro" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Rosa antico" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Rosso corallo" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rosa" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Rosso fragola" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Rosso traffico" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Rosa salmone" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Rosa luminoso" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Rosso chiaro luminoso" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Rosso lampone" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Rosso orientale" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Rubino perlato" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Porpora rossastro" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Violetto rossastro" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Violetto erica" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Violetto bordeaux" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Mogano" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Porpora grigiastro" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Violetto segnale" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Verde abete" +# AI Translated msgid "Sabine grey" -msgstr "" +msgstr "Grigio sabino" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Violetto perlato" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Mora perlata" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Blu verdastro" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Blu oltremare" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Blu zaffiro" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Blu nerastro" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Blu segnale" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Blu brillante" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Blu grigiastro" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Blu azzurro" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Blu genziana" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Blu cobalto" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Blu colombo" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Blu traffico" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Blu turchese" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Blu Capri" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Blu oceano" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Blu acqua" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Blu notte" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Blu lontano" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Blu pastello" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Blu genziana perlato" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Blu mezzanotte perlato" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Verde patina" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Verde smeraldo" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Verde foglia" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Verde oliva" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Verde bluastro" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Verde muschio" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Oliva grigiastro" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Verde pino" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Marrone pino" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Verde erba" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Verde reseda" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Verde brunastro" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Verde canna" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Verde nerastro" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Verde turchese" +# AI Translated msgid "May green" -msgstr "" +msgstr "Verde maggio" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Verde ossido di cromo" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Verde traffico" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Verde felce" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Verde opale" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Verde menta" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Verde bronzo" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Verde perlato" +# AI Translated +# Needs human review: RAL name (Saxe blue-like turquoise); check the rendering. msgid "Sax turquoise" -msgstr "" +msgstr "Turchese sassone" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Turchese perlato" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Giada perlata" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Verde puro" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Verde luminoso" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Grigio scoiattolo" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Grigio argento" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Grigio oliva" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Grigio muschio" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Grigio segnale" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Grigio topo" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Grigio beige" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Grigio cachi" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Grigio verdastro" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Grigio telone" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Grigio ferro" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Grigio basalto" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Grigio brunastro" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Grigio ardesia" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Grigio antracite" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Grigio chiaro" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Grigio terra d'ombra" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Grigio calcestruzzo" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grigio grafite" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Grigio granito" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Grigio pietra" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Grigio ciottolo" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Grigio cemento" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Grigio giallastro" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Grigio platino" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Grigio polvere" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Grigio agata" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Grigio quarzo" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Grigio finestra" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Grigio traffico A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Grigio traffico B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Grigio seta" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegrigio 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegrigio 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegrigio 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Grigio topo perlato" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Marrone verdastro" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Marrone ocra" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Marrone argilla" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Marrone rame" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Marrone cioccolato" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Marrone oliva" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Marrone noce" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Marrone rossastro" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Marrone seppia" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Marrone castagna" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Marrone mogano" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Marrone grigiastro" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Rame perlato" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Marrone beige" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Marrone moka perlato" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Marrone terra" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Marrone perlato" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Crema" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Bianco grigiastro" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Bianco segnale" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Nero segnale" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Nero corvino" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Alluminio bianco" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Alluminio grigio" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Bianco puro" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Nero grafite" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Bianco traffico" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Nero traffico" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Bianco papiro" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Grigio chiaro perlato" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metallo: Argento" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metallo: Ottone" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metallo: Oro" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metallo: Rame" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metallo: Bronzo" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Natura: Perla" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Natura: Arcobaleno" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natura: Cielo sereno" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Natura: Tramonto" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Legno: Scuro" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Legno: Medio" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Legno: Chiaro" # AI Translated msgid "Alternate nozzles:" @@ -32396,13 +32837,25 @@ msgstr "Rimuovi da Le mie trame" msgid "Built-in" msgstr "Predefinite" +# AI Translated +msgid "My textures" +msgstr "Le mie trame" + # AI Translated msgid "No textures found." msgstr "Nessuna trama trovata." # AI Translated -msgid "My textures" -msgstr "Le mie trame" +msgid "Texture libraries" +msgstr "Librerie di trame" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Esplora altre librerie di trame" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Apre OrcaCloud nella pagina iniziale per esplorare i plugin." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32805,11 +33258,15 @@ msgstr "Mappata in base al layout UV del modello stesso, che è già il posizion msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Larghezza di una copia della trama sul modello. Valori più piccoli ripetono il motivo più spesso e ne rendono i dettagli più fini; con Tassellatura disattivata, è la dimensione della singola copia." +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Larger" -msgstr "" +msgstr "Più grande" +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Smaller" -msgstr "" +msgstr "Più piccolo" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -32885,11 +33342,15 @@ msgstr "Colori misti" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Numero massimo di filamenti misti che l'integrazione può aggiungere. Vengono scelti tra i colori della trama, e vengono creati solo quelli effettivamente usati dall'integrazione." +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Few" -msgstr "" +msgstr "Pochi" +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Many" -msgstr "" +msgstr "Molti" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33245,11 +33706,15 @@ msgstr "Ricostruzione della mesh" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Dimensione dei triangoli con cui viene ricostruito l'intero modello, in millimetri. Il rilievo funziona meglio su una mesh uniforme; questo valore permette di ottenerla da un modello importato irregolare." +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "Before" -msgstr "" +msgstr "Prima" +# AI Translated +# Needs human review: Short label, role only visible in the app; check it reads right on its control. msgid "After" -msgstr "" +msgstr "Dopo" # AI Translated msgid "Keep sharp edges" @@ -35100,6 +35565,10 @@ msgstr "Script" msgid "Slicing Pipeline" msgstr "Pipeline di slicing" +# AI Translated +msgid "Resource Texture" +msgstr "Trama di risorsa" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "L'interfaccia di configurazione del plugin era vuota. Viene mostrato l'editor predefinito." @@ -35247,6 +35716,30 @@ msgstr "La cartella del plugin contiene sia file di ingresso .py che .whl" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "La cartella del plugin non contiene un file di ingresso .py o .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "La cartella della trama di risorsa non è impostata" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Impossibile risolvere la cartella della trama di risorsa" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Il percorso della trama di risorsa non è una cartella" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Impossibile risolvere la cartella del plugin" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "La cartella della trama di risorsa si trova fuori dalla cartella del plugin" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Impossibile leggere la cartella della trama di risorsa" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -35707,7 +36200,7 @@ msgstr "Caricamento del file di configurazione \"%1%\" non riuscito: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Non è un file G-code generato da %1%." # AI Translated @@ -35827,7 +36320,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Impossibile creare una copia temporanea del file G-code %1% prima di eseguire uno script di post-elaborazione: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Il post-processore non trova il file G-code esportato" # AI Translated @@ -36196,6 +36689,27 @@ msgstr "" "Evita le deformazioni\n" "Sapevi che quando si stampano materiali soggetti a deformazioni come l'ABS, aumentare in modo appropriato la temperatura del piano riscaldato può ridurre la probabilità di deformazione?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Giallo dalmata" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Violetto capsantina" + +# AI Translated +# Needs human review: RAL grey name, single coined word; translated literally. +#~ msgid "Olivestone" +#~ msgstr "Pietra oliva" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Disponibile ovunque nella finestra, anche durante la digitazione in un campo di testo." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Le scorciatoie globali valgono anche durante la digitazione." + #~ msgid "Please choose the filament color" #~ msgstr "Scegliere il colore del filamento" @@ -36668,9 +37182,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "nessuna testina configurata" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "G-code finale quando si termina la stampa." - #~ msgid "Maximum X speed" #~ msgstr "Velocità massima X" @@ -36687,25 +37198,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Plugin Python richiamati a ogni fase della pipeline di slicing per leggere e modificare i dati di slicing intermedi, incluso un passaggio finale di post-elaborazione del G-code. Ricerca/sperimentale." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Se abilitata, lo slicer genera G-code con il contenuto della zona principale centrato sull'origine del piatto (0,0). Il firmware della stampante si occupa di posizionare le copie e le immagini speculari nella posizione fisica di ciascuna zona. Abilita solo su stampanti il cui firmware applica i propri offset di zona in modalità Copia/Specchio (ad es. la modalità di duplicazione IDEX di RepRapFirmware). Non ha effetto in modalità Principale (Primary)." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Associazione per piatto, che sostituisce quella predefinita, tra testine fisiche e slot filamento (numerati da 1). Vuota significa usare i valori predefiniti dell'inversione pem." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Asse attorno al quale la mesh viene ruotata prima dell'elaborazione. È l'inclinazione della stampante a nastro: una rotazione isometrica (senza distorsione) che determina anche la visualizzazione del piatto e l'inclinazione della gravità per i supporti, e che la trasformazione inversa del G-code annulla prima di taglio/scala e rimappatura nel sistema di riferimento macchina. X è l'inclinazione tipica del portale (il nastro scorre lungo Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Opzione per esperti: imposta l'angolo di inclinazione del sistema di riferimento macchina (taglio/scala del G-code) indipendentemente dall'angolo di rotazione pre-elaborazione. Se disabilitata, la trasformazione del sistema di riferimento macchina deriva dall'angolo di inclinazione del nastro, quindi un unico angolo governa entrambe le fasi. Abilita solo per compensare una macchina la cui inclinazione fisica del portale differisce dalla rotazione di elaborazione." - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Deviazione massima consentita quando si riduce la risoluzione tramite l'impostazione \"Risoluzione massima parete\". Se si aumenta questo valore, la stampa sarà meno precisa, ma il G-Code sarà più contenuto. \"Deviazione massima parete\" limita \"Risoluzione massima parete\", quindi in caso di conflitto tra i due valori, \"Deviazione massima parete\" ha la precedenza." - #~ msgid " not in range " #~ msgstr " fuori portata " diff --git a/localization/i18n/ja/OrcaSlicer_ja.po b/localization/i18n/ja/OrcaSlicer_ja.po index 6a7d913431..2601a61eba 100644 --- a/localization/i18n/ja/OrcaSlicer_ja.po +++ b/localization/i18n/ja/OrcaSlicer_ja.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -780,18 +780,21 @@ msgstr "選択" msgid "Plate" msgstr "プレート" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "均等配置" # AI Translated msgid "Coordinate system used for transform actions." msgstr "変換操作に使用する座標系です。" +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "整列の基準" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "パーツまたはオブジェクトを3つ以上選択してください" # AI Translated msgid "Align left" @@ -844,8 +847,9 @@ msgstr "上下に均等配置" msgid "Drop" msgstr "ドロップ" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "最下点がベッドに接するように、選択をZ方向に移動します。" # AI Translated msgid "Absolute" @@ -1738,7 +1742,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "形状 (%1%) のストロークにサポートされていないものが含まれています: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "無効な状態です。再現手順をGitHubで報告してください" # AI Translated @@ -1746,11 +1750,11 @@ msgid "No embossed file" msgstr "エンボス対象のファイルがありません" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "エンボス形状にSVGファイルがありません" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "SVGファイルのデータがありません" msgid "Face the camera" @@ -2074,17 +2078,21 @@ msgstr "組み立てギズモを開始" msgid "Leaving Assembly gizmo" msgstr "組み立てギズモを終了" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "切断されたオブジェクトのパーツは移動できません" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "プレートへの整列はXとYのみ可能です" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Z方向に移動するには、選択したオブジェクトの自動ドロップをオフにしてください" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "選択したオブジェクトはすべて同じプレート上にある必要があります" msgid "Shift+" msgstr "Shift+" @@ -4972,7 +4980,7 @@ msgid "Unknown C++ exception." msgstr "不明なC++例外です。" # AI Translated -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "前のファイルのG-codeを処理中…" msgid "Slicing complete" @@ -6520,8 +6528,10 @@ msgstr "軸" msgid "Gridlines" msgstr "グリッドライン" +# AI Translated +# Needs human review: Mode name that hides the surrounding UI to focus on the 3D canvas; glossary has no entry, check the wording. msgid "Focus mode" -msgstr "" +msgstr "フォーカスモード" msgid "Labels" msgstr "ラベル" @@ -6582,7 +6592,7 @@ msgstr "ボリューム" msgid "Size:" msgstr "サイズ:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "レイヤー%d、Z = %.2lfmmでG-codeパスの衝突が検出されました。衝突するオブジェクトをもっと離してください(%s <-> %s)。" @@ -10930,11 +10940,14 @@ msgstr "非対応のプリセットを表示" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "プリンターとフィラメントのドロップダウンリストに、互換性のない/非対応のプリセットを表示します。これらのプリセットは選択できません。" +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "G-codeと一緒に統計をエクスポート" +# AI Translated +# Needs human review: "feature" here is the G-code feature (line) type, not the Design-tab Feature; rendered as line type, check. msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "有効にすると、G-codeファイルのエクスポート時にその統計もJSON形式で .statistics.json として隣に書き出され、エクスポートしたスライス済み3MFファイルにも統計が含まれます。内容は、印刷時間、フィラメントと線種ごとの合計、および積層ごと・オブジェクトごとの同じ項目です。" # AI Translated msgid "Experimental Features" @@ -11796,6 +11809,10 @@ msgstr "プリンターのストレージへのファイルのアップロード msgid "Send Failed" msgstr "送信失敗" +# AI Translated +msgid "No available printers" +msgstr "利用可能なプリンターがありません" + msgid "The name length exceeds the limit." msgstr "名前の長さが制限を超えています。" @@ -13651,8 +13668,8 @@ msgid "Left mouse" msgstr "マウス左ボタン" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "テキストフィールドへの入力中も含め、ウィンドウ内のどこでも使用できます。" +msgid "Available anywhere in the window." +msgstr "ウィンドウ内のどこでも使用できます。" # AI Translated msgid "Run favorite 1 to 10" @@ -13764,10 +13781,6 @@ msgstr "%sは%sに割り当てられています。%sに再割り当てします msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "デフォルトの%sは%sに割り当てられています。%sに再割り当てしますか?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "グローバルショートカットは文字入力中も有効です。" - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "文字を入力するキーはグローバルショートカットにできません。" @@ -14221,9 +14234,10 @@ msgstr "「%2%」のモディファイア「%1%」(合計%3%個) は継ぎ目に msgid "Seam placement may differ from expected." msgstr "継ぎ目の位置が想定と異なる可能性があります。" +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "G-codeの統計を %1% に書き込めませんでした。" msgid "Internal Bridge" msgstr "内部ブリッジ" @@ -17798,6 +17812,14 @@ msgstr "オブジェクトを除外" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "G-codeにEXCLUDE OBJECTコマンドを追加するには、このオプションを有効にします。" +# AI Translated +msgid "Outline tolerance" +msgstr "アウトライン許容差" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "EXCLUDE_OBJECT_DEFINE に書き込まれるオブジェクトのアウトラインと元のアウトラインとの最大偏差です。値を大きくすると点の数が減り、オブジェクトの多いG-codeの解析中に停止するファームウェアで効果があります。0にするとすべての点を保持します。" + # AI Translated msgid "Verbose G-code" msgstr "コメント付きG-code" @@ -21267,11 +21289,14 @@ msgstr "出力先フォルダ" msgid "This is the output directory for exported files." msgstr "エクスポートの出力先フォルダです。" +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "統計をエクスポート" +# AI Translated +# Needs human review: "feature" here is the G-code feature (line) type, not the Design-tab Feature; rendered as line type, check. msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "スライスした各プレートの統計をJSON形式で、出力ディレクトリ内のG-codeの隣に plate_N.statistics.json として書き出し、--export-3mf で出力する3MFにも含めます。内容は、印刷時間、フィラメントと線種ごとの合計、および積層ごと・オブジェクトごとの同じ項目です。" msgid "Debug level" msgstr "デバッグ レベル" @@ -23766,7 +23791,7 @@ msgstr "%s のテストを開始..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "%s のテスト: IP解決 = %s" # AI Translated @@ -31234,1231 +31259,1644 @@ msgid "The current filament list does not contain %s. A project filament require msgid_plural "The current filament list does not contain %s. Project filaments required by the mixed filament will be created automatically after decomposition." msgstr[0] "現在のフィラメントリストに%sが含まれていません。混合フィラメントに必要なプロジェクトフィラメントは、分解後に自動的に作成されます。" +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "カラーピッカー" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "基本色" +# AI Translated +# Needs human review: Glossary has no Palette entry; rendered as a named color collection. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca パレット" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL クラシック" + +# AI Translated +# Needs human review: Name of the gradient color set tab in the color picker; check it reads right as a tab label. msgid "Gradients" -msgstr "" +msgstr "グラデーション" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "単色" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "グラデーション" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "グラデーション開始" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "グラデーション終了" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "グラデーションの色" +# AI Translated msgid "Add color" -msgstr "" +msgstr "色を追加" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "色を削除" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "彩度" +# AI Translated msgid "Original color" -msgstr "" +msgstr "元の色" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "現在の色を保存" +# AI Translated msgid "Palettes" -msgstr "" +msgstr "パレット" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "色を検索" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "色をフィルター" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "一致する色がありません" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "16進カラー" # AI Translated msgid "Opacity" msgstr "不透明度" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "不透明度 (%)" +# AI Translated msgid "Save color" -msgstr "" +msgstr "色を保存" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "16進カラーコードを最後まで入力してください" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "別の色を選択するまで、現在のマルチカラー選択が保持されます。" +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "最大 %d 色に対応しています。" +# AI Translated msgid "Crimson" -msgstr "" +msgstr "クリムゾン" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "オレンジレッド" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "トマト" +# AI Translated msgid "Orange" -msgstr "" +msgstr "オレンジ" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "ダークオレンジ" +# AI Translated msgid "Gold" -msgstr "" +msgstr "ゴールド" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "バーリーウッド" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "ビスク" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "ミスティローズ" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "ライトイエロー" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "レモンシフォン" +# AI Translated msgid "Beige" -msgstr "" +msgstr "ベージュ" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "ライトゴールデンロッドイエロー" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "ペールゴールデンロッド" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "カーキ" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "ダークカーキ" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "ピーチパフ" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "モカシン" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "パパイヤホイップ" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "ブランチドアーモンド" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "アンティークホワイト" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "ナバホホワイト" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "ウィート" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "ゴールデンロッド" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "チョコレート" +# AI Translated msgid "Peru" -msgstr "" +msgstr "ペルー" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "ファイアブリック" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "シエナ" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "サドルブラウン" +# AI Translated msgid "Brown" -msgstr "" +msgstr "ブラウン" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "ロージーブラウン" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "サーモン" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "ライトサーモン" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "ダークサーモン" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "サンディブラウン" +# AI Translated msgid "Coral" -msgstr "" +msgstr "コーラル" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "ライトコーラル" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "インディアンレッド" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "ダークレッド" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "マルーン" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "グリーンイエロー" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "イエローグリーン" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "シャルトルーズ" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "ローングリーン" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "ライムグリーン" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "スプリンググリーン" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "ミディアムスプリンググリーン" +# AI Translated msgid "Lime" -msgstr "" +msgstr "ライム" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "フォレストグリーン" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "ダークグリーン" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "オリーブドラブ" +# AI Translated msgid "Olive" -msgstr "" +msgstr "オリーブ" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "ダークオリーブグリーン" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "ペールグリーン" +# AI Translated msgid "Light green" -msgstr "" +msgstr "ライトグリーン" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "ミディアムシーグリーン" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "シーグリーン" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "ダークシーグリーン" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "カデットブルー" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "ミディアムアクアマリン" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "ターコイズ" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "ミディアムターコイズ" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "ダークターコイズ" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "ペールターコイズ" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "アクア" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "ライトシアン" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "ミントクリーム" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "ハニーデュー" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "アクアマリン" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "ライトシーグリーン" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "ダークシアン" +# AI Translated msgid "Teal" -msgstr "" +msgstr "ティール" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "ダークスレートグレー" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "ライトスレートグレー" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "スレートグレー" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "ディープスカイブルー" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "ドジャーブルー" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "スカイブルー" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "ライトスカイブルー" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "ライトブルー" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "パウダーブルー" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "ライトスチールブルー" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "スチールブルー" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "コーンフラワーブルー" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "ロイヤルブルー" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "ミディアムブルー" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "ミッドナイトブルー" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "ダークブルー" +# AI Translated msgid "Navy" -msgstr "" +msgstr "ネイビー" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "スレートブルー" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "ダークスレートブルー" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "ミディアムスレートブルー" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "ブルーバイオレット" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "インディゴ" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "ダークバイオレット" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "ダークオーキッド" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "ミディアムオーキッド" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "オーキッド" +# AI Translated msgid "Violet" -msgstr "" +msgstr "バイオレット" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "ミディアムパープル" +# AI Translated msgid "Purple" -msgstr "" +msgstr "パープル" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "レベッカパープル" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "ミディアムバイオレットレッド" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "ペールバイオレットレッド" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "ディープピンク" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "ホットピンク" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "ライトピンク" +# AI Translated msgid "Pink" -msgstr "" +msgstr "ピンク" +# AI Translated msgid "Plum" -msgstr "" +msgstr "プラム" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "シスル" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "フクシア" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "ダークマゼンタ" +# AI Translated msgid "Linen" -msgstr "" +msgstr "リネン" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "オールドレース" +# AI Translated msgid "Sea shell" -msgstr "" +msgstr "シーシェル" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "アイボリー" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "フローラルホワイト" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "ラベンダーブラッシュ" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "ゴーストホワイト" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "アリスブルー" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "ラベンダー" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "ホワイトスモーク" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "ゲインズボロ" +# AI Translated msgid "Black" -msgstr "" +msgstr "ブラック" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "コーラルファイア" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "シーアネモネ" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "ディープアビス" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "ロブスターレッド" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "サンディクレイ" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "ドリフトウッド" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "シーバックソーン" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "サンセットリーフ" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "タイガーコーラル" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "ピンクコーラル" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "シーシェルグロウ" +# AI Translated msgid "Sand" -msgstr "" +msgstr "サンド" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "ゴールデンケルプ" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "サンリットデューン" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "アンバーノーチラス" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "シーレモン" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "ペールスターフィッシュ" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "スプリングタイド" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "ライムアルジー" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "シーグラス" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "ネオンプランクトン" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "ケルプフォレスト" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "エメラルドウェーブ" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "ホエールシャドウ" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "シータートル" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "ラグーン" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "トロピカルカレント" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "ミッドナイトトレンチ" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "ダークケルプ" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "クリスタルサーフ" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "ターコイズベイ" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "スカイオーバーリーフ" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "シャロースカイ" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "エレクトリックブルー" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "ドルフィン" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "オーシャンデプス" +# AI Translated msgid "Whale" -msgstr "" +msgstr "ホエール" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "インディゴアビス" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "シーアーチン" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "ラベンダーコーラル" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "バイオレットタイド" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "ディープシーオーキッド" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "ネオンジェリー" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "フクシアコーラル" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "ピンクジェリーフィッシュ" +# AI Translated msgid "Foam" -msgstr "" +msgstr "フォーム" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "シーシェルホワイト" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "ペブルグレー" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "ストームクラウド" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "インクブラック" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "グリーンベージュ" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "サンドイエロー" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "シグナルイエロー" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "ゴールデンイエロー" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "ハニーイエロー" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "メイズイエロー" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "ダフォディルイエロー" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "ブラウンベージュ" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "レモンイエロー" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "オイスターホワイト" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "ライトアイボリー" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "ジンクイエロー" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "グレーベージュ" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "オリーブイエロー" +# AI Translated +# Needs human review: RAL name (rapeseed); check the plant name reads naturally as a color. msgid "Rape yellow" -msgstr "" +msgstr "ナタネイエロー" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "トラフィックイエロー" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "オーカーイエロー" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "トラフィックオレンジイエロー" +# AI Translated msgid "Curry" -msgstr "" +msgstr "カレー" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "メロンイエロー" +# AI Translated +# Needs human review: RAL name (broom, the plant); check the rendering. msgid "Broom yellow" -msgstr "" +msgstr "エニシダイエロー" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "ダリアイエロー" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "パステルイエロー" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "パールベージュ" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "パールゴールド" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "サンイエロー" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "イエローオレンジ" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "ディープオレンジ" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "バーミリオン" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "パールオレンジ" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "ピュアオレンジ" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "ルミナスオレンジ" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "ルミナスブライトオレンジ" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "ブライトレッドオレンジ" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "トラフィックオレンジ" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "シグナルオレンジ" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "サーモンオレンジ" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "パールピンク" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "カッパーオレンジ" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "シグナルブラウン" +# AI Translated +# Needs human review: Source name is odd (RAL has Fir green); fir rendered as the tree. msgid "Fir orange" -msgstr "" +msgstr "モミオレンジ" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "シグナルレッド" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "ルミナスレッド" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "カーマインレッド" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "パールカーマインレッド" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "ピュアレッド" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "ルミナスディープレッド" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "カラントレッド" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "パールルビーレッド" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "ファイアレッド" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "ルビーレッド" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "パープルレッド" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "ワインレッド" +# AI Translated msgid "Black red" -msgstr "" +msgstr "ブラックレッド" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "オキサイドレッド" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "ブラウンレッド" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "パインレッド" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "トマトレッド" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "アンティークピンク" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "コーラルレッド" +# AI Translated msgid "Rose" -msgstr "" +msgstr "ローズ" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "ストロベリーレッド" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "トラフィックレッド" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "サーモンピンク" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "ルミナスローズ" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "ルミナスブライトレッド" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "ラズベリーレッド" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "オリエントレッド" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "パールルビー" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "レッドパープル" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "レッドバイオレット" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "ヘザーバイオレット" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "ボルドーバイオレット" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "マホガニー" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "グレーパープル" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "シグナルバイオレット" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "モミグリーン" +# AI Translated +# Needs human review: Source name unclear (Sabine); transliterated. msgid "Sabine grey" -msgstr "" +msgstr "サビーヌグレー" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "パールバイオレット" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "パールブラックベリー" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "グリーンブルー" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "ウルトラマリンブルー" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "サファイアブルー" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "ブラックブルー" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "シグナルブルー" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "ブリリアントブルー" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "グレーブルー" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "アズールブルー" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "ゲンチアナブルー" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "コバルトブルー" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "ピジョンブルー" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "トラフィックブルー" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "ターコイズブルー" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "カプリブルー" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "オーシャンブルー" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "ウォーターブルー" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "ナイトブルー" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "ディスタントブルー" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "パステルブルー" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "パールゲンチアナブルー" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "パールミッドナイトブルー" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "パティナグリーン" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "エメラルドグリーン" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "リーフグリーン" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "オリーブグリーン" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "ブルーグリーン" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "モスグリーン" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "グレーオリーブ" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "パイングリーン" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "パインブラウン" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "グラスグリーン" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "レセダグリーン" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "ブラウングリーン" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "リードグリーン" +# AI Translated msgid "Black green" -msgstr "" +msgstr "ブラックグリーン" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "ターコイズグリーン" +# AI Translated msgid "May green" -msgstr "" +msgstr "メイグリーン" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "クロムオキサイドグリーン" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "トラフィックグリーン" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "ファーングリーン" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "オパールグリーン" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "ミントグリーン" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "ブロンズグリーン" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "パールグリーン" +# AI Translated msgid "Sax turquoise" -msgstr "" +msgstr "サックスターコイズ" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "パールターコイズ" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "パールジェイド" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "ピュアグリーン" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "ルミナスグリーン" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "スクワレルグレー" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "シルバーグレー" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "オリーブグレー" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "モスグレー" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "シグナルグレー" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "マウスグレー" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "ベージュグレー" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "カーキグレー" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "グリーングレー" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "ターポリングレー" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "アイアングレー" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "バサルトグレー" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "ブラウングレー" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "スレートグレー" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "アンスラサイトグレー" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "ライトグレー" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "アンバーグレー" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "コンクリートグレー" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "グラファイトグレー" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "グラナイトグレー" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "ストーングレー" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "ペブルグレー" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "セメントグレー" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "イエローグレー" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "プラチナグレー" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "ダスティグレー" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "アゲートグレー" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "クォーツグレー" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "ウィンドウグレー" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "トラフィックグレーA" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "トラフィックグレーB" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "シルクグレー" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "テレグレー1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "テレグレー2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "テレグレー4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "パールマウスグレー" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "グリーンブラウン" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "オーカーブラウン" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "クレイブラウン" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "カッパーブラウン" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "チョコレートブラウン" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "オリーブブラウン" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "ナッツブラウン" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "レッドブラウン" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "セピアブラウン" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "チェスナットブラウン" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "マホガニーブラウン" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "グレーブラウン" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "パールカッパー" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "ベージュブラウン" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "パールモカブラウン" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "アースブラウン" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "パールブラウン" +# AI Translated msgid "Cream" -msgstr "" +msgstr "クリーム" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "グレーホワイト" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "シグナルホワイト" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "シグナルブラック" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "ジェットブラック" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "ホワイトアルミニウム" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "グレーアルミニウム" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "ピュアホワイト" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "グラファイトブラック" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "トラフィックホワイト" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "トラフィックブラック" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "パピルスホワイト" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "パールライトグレー" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "メタル: シルバー" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "メタル: ブラス" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "メタル: ゴールド" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "メタル: カッパー" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "メタル: ブロンズ" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "ネイチャー: パール" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "ネイチャー: レインボー" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "ネイチャー: クリアスカイ" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "ネイチャー: サンセット" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "ウッド: ダーク" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "ウッド: ミディアム" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "ウッド: ライト" # AI Translated msgid "Alternate nozzles:" @@ -32933,13 +33371,25 @@ msgstr "マイテクスチャから削除" msgid "Built-in" msgstr "内蔵" +# AI Translated +msgid "My textures" +msgstr "マイテクスチャ" + # AI Translated msgid "No textures found." msgstr "テクスチャが見つかりません。" # AI Translated -msgid "My textures" -msgstr "マイテクスチャ" +msgid "Texture libraries" +msgstr "テクスチャライブラリ" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "さらにテクスチャライブラリを探す" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "ホームページで OrcaCloud を開き、プラグインを探します。" # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33342,11 +33792,15 @@ msgstr "モデル自身のUVレイアウトでマッピングされます。こ msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "モデル上でのテクスチャ1枚分の幅です。小さくするとパターンの繰り返しが増え、ディテールが細かくなります。「タイル」がオフの場合は、1枚だけ配置されるテクスチャのサイズになります。" +# AI Translated +# Needs human review: Image caption in the tile-size tip (larger tiles); check wording. msgid "Larger" -msgstr "" +msgstr "大きい" +# AI Translated +# Needs human review: Image caption in the tile-size tip (smaller tiles); check wording. msgid "Smaller" -msgstr "" +msgstr "小さい" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33422,11 +33876,15 @@ msgstr "混合色" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "焼付けで追加できる混合フィラメントの最大数です。テクスチャの色から選ばれ、焼付けで実際に使用されるものだけが作成されます。" +# AI Translated +# Needs human review: Image caption comparing few vs many mixed colors; check wording. msgid "Few" -msgstr "" +msgstr "少ない" +# AI Translated +# Needs human review: Image caption comparing few vs many mixed colors; check wording. msgid "Many" -msgstr "" +msgstr "多い" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33777,11 +34235,15 @@ msgstr "リメッシュ" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "モデル全体を再構築する際の三角形のサイズ (mm) です。変位は均一なメッシュで最もよく機能します。不均一なインポートモデルから均一なメッシュを作るための設定です。" +# AI Translated +# Needs human review: Image caption of the remesh comparison (before/after remeshing); check wording. msgid "Before" -msgstr "" +msgstr "適用前" +# AI Translated +# Needs human review: Image caption of the remesh comparison (before/after remeshing); check wording. msgid "After" -msgstr "" +msgstr "適用後" # AI Translated msgid "Keep sharp edges" @@ -35629,6 +36091,10 @@ msgstr "スクリプト" msgid "Slicing Pipeline" msgstr "スライスパイプライン" +# AI Translated +msgid "Resource Texture" +msgstr "リソーステクスチャ" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "プラグインの設定UIが空でした。デフォルトのエディターを表示します。" @@ -35776,6 +36242,30 @@ msgstr "プラグインのディレクトリに.pyと.whlの両方のエント msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "プラグインのディレクトリに.pyまたは.whlのエントリファイルがありません" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "リソーステクスチャのディレクトリが設定されていません" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "リソーステクスチャのディレクトリを特定できませんでした" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "リソーステクスチャのパスがディレクトリではありません" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "プラグインフォルダーを特定できませんでした" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "リソーステクスチャのディレクトリがプラグインフォルダーの外にあります" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "リソーステクスチャのディレクトリを読み取れませんでした" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36234,7 +36724,7 @@ msgstr "設定ファイル「%1%」の読み込みに失敗しました: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "%1%で生成されたG-codeファイルではありません。" # AI Translated @@ -36354,7 +36844,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "後処理スクリプトの実行前にG-codeファイル%1%の一時コピーを作成できませんでした: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "後処理でエクスポートされたG-codeファイルが見つかりません" # AI Translated @@ -36734,6 +37224,26 @@ msgstr "" "反りを避ける\n" "ABSのような反りやすい素材を印刷する場合、ヒートベッドの温度を適切に上げることで、反りが発生する確率を下げることができることをご存知ですか?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "ダルメシアンイエロー" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "カプサンチンバイオレット" + +# AI Translated +#~ msgid "Olivestone" +#~ msgstr "オリーブストーン" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "テキストフィールドへの入力中も含め、ウィンドウ内のどこでも使用できます。" + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "グローバルショートカットは文字入力中も有効です。" + #~ msgid "Please choose the filament color" #~ msgstr "フィラメントの色を選択してください" @@ -37219,9 +37729,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "未設定のツール" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "造形完了時のG-codeを追加" - #~ msgid "Maximum X speed" #~ msgstr "最大速度 X" @@ -37238,27 +37745,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "スライスパイプラインの各ステップで呼び出され、中間のスライスデータを読み取り・変更するPythonプラグインです。最終的なG-codeの後処理ステップも含みます。研究/実験用です。" -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "有効にすると、スライサーはプライマリゾーンの内容をベッド原点 (0,0) を中心に配置したG-codeを出力します。各物理ゾーン位置へのコピー/ミラーの配置はプリンターのファームウェアが行います。コピー/ミラーモードでファームウェアが独自のゾーンオフセットを適用するプリンター (例: RepRapFirmwareのIDEX複製モード) でのみ有効にしてください。プライマリ (Primary) モードでは効果がありません。" - # AI Translated # Needs human review: 'pem-inversion' is developer jargon (inverse of the physical extruder map); check the wording is understandable. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "物理ヘッドをフィラメントスロットに対応付ける、プレートごとのオーバーライドです (1始まり)。空の場合はpem反転によるデフォルトを使用します。" -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "スライス前にメッシュを回転させる軸です。これはベルトプリンターの傾斜で、歪みのない等長回転です。ベッドの描画とサポートの重力方向の傾斜にも使用され、G-codeの逆変換では、機械座標系のせん断/スケールとリマップの前にこの回転が元に戻されます。一般的なガントリーの傾斜はXです (ベルトはY方向に移動)。" - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "エキスパート向けの上書き設定: 機械座標系 (G-codeのせん断/スケール) の傾斜角度を、スライス前の回転角度とは独立して設定します。無効の場合、機械座標系の変換はベルト傾斜角度から導出されるため、1つの角度で両方の段階を制御します。物理的なガントリーの傾斜がスライス時の回転と異なるマシンを補正する場合にのみ有効にしてください。" - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "「最大壁解像度」設定で解像度を下げる際に許容される最大偏差です。これを大きくすると印刷の精度は下がりますが、G-Codeは小さくなります。「最大壁偏差」は「最大壁解像度」を制限するため、両者が競合する場合は「最大壁偏差」が優先されます。" - #~ msgid " not in range " #~ msgstr "範囲外 " diff --git a/localization/i18n/ko/OrcaSlicer_ko.po b/localization/i18n/ko/OrcaSlicer_ko.po index 4358072734..fe7341daad 100644 --- a/localization/i18n/ko/OrcaSlicer_ko.po +++ b/localization/i18n/ko/OrcaSlicer_ko.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2025-06-02 17:12+0900\n" "Last-Translator: crwusiz \n" "Language-Team: \n" @@ -786,18 +786,21 @@ msgstr "선택" msgid "Plate" msgstr "플레이트" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "분배" # AI Translated msgid "Coordinate system used for transform actions." msgstr "변형 작업에 사용되는 좌표계입니다." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "정렬 기준" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "부품 또는 객체를 3개 이상 선택하세요" # AI Translated msgid "Align left" @@ -850,8 +853,9 @@ msgstr "상하 균등 분배" msgid "Drop" msgstr "내리기" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "선택 항목의 가장 낮은 지점이 베드에 닿도록 Z축 방향으로 이동합니다." # AI Translated msgid "Absolute" @@ -1747,7 +1751,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "모양의 획(%1%)에는 지원되지 않는 %2%가 포함되어 있습니다." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "유효하지 않은 상태입니다. GitHub에 재현 단계를 보고해 주세요" # AI Translated @@ -1755,11 +1759,11 @@ msgid "No embossed file" msgstr "양각 파일 없음" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "양각 형상에 SVG 파일이 없습니다" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "SVG 파일 데이터가 없습니다" msgid "Face the camera" @@ -2088,17 +2092,21 @@ msgstr "조립 변형도구 진입" msgid "Leaving Assembly gizmo" msgstr "조립 변형도구 나가기" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "절단된 객체의 부품은 이동할 수 없습니다" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "플레이트에 정렬은 X와 Y에서만 사용할 수 있습니다" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Z축으로 이동하려면 선택한 객체의 자동 내려놓기를 끄세요" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "선택한 객체는 모두 같은 플레이트에 있어야 합니다" msgid "Shift+" msgstr "Shift+" @@ -5010,7 +5018,7 @@ msgid "Unknown C++ exception." msgstr "알 수 없는 C++ 예외입니다." # AI Translated -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "이전 파일의 G-code를 처리하는 중..." msgid "Slicing complete" @@ -6559,8 +6567,10 @@ msgstr "축" msgid "Gridlines" msgstr "그리드 라인" +# AI Translated +# Needs human review: Mode name that hides the surrounding UI to focus on the 3D canvas; glossary has no entry, check the wording. msgid "Focus mode" -msgstr "" +msgstr "집중 모드" msgid "Labels" msgstr "레이블" @@ -6622,7 +6632,7 @@ msgid "Size:" msgstr "크기:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "레이어 %d, Z = %.2lf mm에서 G-code 경로 충돌이 발견되었습니다. 충돌하는 객체를 더 멀리 분리하세요 (%s <-> %s)." @@ -11072,11 +11082,14 @@ msgstr "지원되지 않는 사전 설정 표시" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "프린터 및 필라멘트 드롭다운 목록에 호환되지 않거나 지원되지 않는 사전 설정을 표시합니다. 이러한 사전 설정은 선택할 수 없습니다." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "G-code와 함께 통계 내보내기" +# AI Translated +# Needs human review: "feature" here is the G-code feature (line) type, not the Design-tab Feature; rendered as line type, check. msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "활성화하면 G-code 파일을 내보낼 때 해당 통계도 JSON 형식의 .statistics.json으로 옆에 함께 기록되고, 내보낸 슬라이스된 3MF 파일에는 통계가 내부에 포함됩니다. 내용은 출력 시간, 필라멘트 및 선 유형별 합계와 레이어별, 객체별 동일 항목입니다." # AI Translated msgid "Experimental Features" @@ -11946,6 +11959,10 @@ msgstr "프린터 저장소에 파일을 업로드하지 못했습니다. 다시 msgid "Send Failed" msgstr "전송 실패" +# AI Translated +msgid "No available printers" +msgstr "사용 가능한 프린터가 없습니다" + msgid "The name length exceeds the limit." msgstr "이름 길이가 제한을 초과합니다." @@ -13842,8 +13859,8 @@ msgid "Left mouse" msgstr "마우스 왼쪽 버튼" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "텍스트 필드에 입력하는 중에도 창 어디에서나 사용할 수 있습니다." +msgid "Available anywhere in the window." +msgstr "창 어디에서나 사용할 수 있습니다." # AI Translated msgid "Run favorite 1 to 10" @@ -13956,10 +13973,6 @@ msgstr "%s은(는) %s에 할당되어 있습니다. %s에 다시 할당하시겠 msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "기본 %s은(는) %s에 할당되어 있습니다. %s에 다시 할당하시겠습니까?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "전역 단축키는 텍스트를 입력하는 중에도 적용됩니다." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "문자를 입력하는 키는 전역 단축키가 될 수 없습니다." @@ -14416,9 +14429,10 @@ msgstr "\"%2%\"의 수정자 \"%1%\"(총 %3%개)이(가) 재봉선에 영향을 msgid "Seam placement may differ from expected." msgstr "재봉선 위치가 예상과 다를 수 있습니다." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "G-code 통계를 %1%에 쓰지 못했습니다." msgid "Internal Bridge" msgstr "내부 브릿지" @@ -17928,6 +17942,14 @@ msgstr "객체 제외" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "G-code에 객체 제외 명령을 추가하려면 이 옵션을 활성화하세요." +# AI Translated +msgid "Outline tolerance" +msgstr "외곽선 공차" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "EXCLUDE_OBJECT_DEFINE에 기록되는 객체 외곽선과 원래 외곽선 사이의 최대 편차입니다. 값이 클수록 점의 수가 줄어들어, 객체가 많은 G-code를 파싱하는 동안 멈추는 펌웨어에 도움이 됩니다. 0이면 모든 점을 유지합니다." + # AI Translated msgid "Verbose G-code" msgstr "상세한 G-code" @@ -21256,11 +21278,14 @@ msgstr "출력 디렉토리" msgid "This is the output directory for exported files." msgstr "내보내기 파일의 출력 디렉토리입니다." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "통계 내보내기" +# AI Translated +# Needs human review: "feature" here is the G-code feature (line) type, not the Design-tab Feature; rendered as line type, check. msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "슬라이스한 각 플레이트의 통계를 JSON 형식으로, 출력 디렉터리의 G-code 옆에 plate_N.statistics.json으로 기록하고 --export-3mf로 내보내는 3MF 내부에도 포함합니다. 내용은 출력 시간, 필라멘트 및 선 유형별 합계와 레이어별, 객체별 동일 항목입니다." msgid "Debug level" msgstr "디버그 수준" @@ -23736,7 +23761,7 @@ msgstr "%s 테스트 시작..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "%s 테스트 IP 확인됨 = %s" # AI Translated @@ -31225,1231 +31250,1645 @@ msgid "The current filament list does not contain %s. A project filament require msgid_plural "The current filament list does not contain %s. Project filaments required by the mixed filament will be created automatically after decomposition." msgstr[0] "현재 필라멘트 목록에 %s이(가) 없습니다. 분해 후 혼합 필라멘트에 필요한 프로젝트 필라멘트가 자동으로 생성됩니다." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "색상 선택기" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "기본 색상" +# AI Translated +# Needs human review: Glossary has no Palette entry; rendered as a named color collection. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca 팔레트" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL 클래식" + +# AI Translated +# Needs human review: Name of the gradient color set tab in the color picker; check it reads right as a tab label. msgid "Gradients" -msgstr "" +msgstr "그라데이션" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "단색" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "그라데이션" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "그라데이션 시작" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "그라데이션 끝" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "그라데이션 색상" +# AI Translated msgid "Add color" -msgstr "" +msgstr "색상 추가" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "색상 제거" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "채도" +# AI Translated msgid "Original color" -msgstr "" +msgstr "원래 색상" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "현재 색상 저장" +# AI Translated msgid "Palettes" -msgstr "" +msgstr "팔레트" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "색상 검색" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "색상 필터" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "일치하는 색상이 없습니다" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "16진수 색상" # AI Translated msgid "Opacity" msgstr "불투명도" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "불투명도(%)" +# AI Translated msgid "Save color" -msgstr "" +msgstr "색상 저장" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "전체 16진수 색상 값을 입력하세요" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "다른 색상을 선택할 때까지 현재 다중 색상 선택이 유지됩니다." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "최대 %d개 색상을 지원합니다." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "크림슨" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "오렌지 레드" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "토마토" +# AI Translated msgid "Orange" -msgstr "" +msgstr "오렌지" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "다크 오렌지" +# AI Translated msgid "Gold" -msgstr "" +msgstr "골드" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "벌리우드" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "비스크" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "미스티 로즈" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "라이트 옐로" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "레몬 시폰" +# AI Translated msgid "Beige" -msgstr "" +msgstr "베이지" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "라이트 골든로드 옐로" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "페일 골든로드" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "카키" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "다크 카키" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "피치 퍼프" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "모카신" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "파파야 휩" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "블랜치드 아몬드" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "앤티크 화이트" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "나바호 화이트" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "휘트" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "골든로드" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "초콜릿" +# AI Translated msgid "Peru" -msgstr "" +msgstr "페루" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "파이어브릭" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "시에나" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "새들 브라운" +# AI Translated msgid "Brown" -msgstr "" +msgstr "브라운" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "로지 브라운" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "살몬" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "라이트 살몬" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "다크 살몬" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "샌디 브라운" +# AI Translated msgid "Coral" -msgstr "" +msgstr "코랄" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "라이트 코랄" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "인디언 레드" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "다크 레드" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "마룬" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "그린 옐로" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "옐로 그린" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "샤르트뢰즈" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "론 그린" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "라임 그린" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "스프링 그린" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "미디엄 스프링 그린" +# AI Translated msgid "Lime" -msgstr "" +msgstr "라임" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "포레스트 그린" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "다크 그린" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "올리브 드랩" +# AI Translated msgid "Olive" -msgstr "" +msgstr "올리브" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "다크 올리브 그린" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "페일 그린" +# AI Translated msgid "Light green" -msgstr "" +msgstr "라이트 그린" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "미디엄 시 그린" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "시 그린" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "다크 시 그린" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "카뎃 블루" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "미디엄 아쿠아마린" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "터콰이즈" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "미디엄 터콰이즈" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "다크 터콰이즈" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "페일 터콰이즈" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "아쿠아" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "라이트 시안" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "민트 크림" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "허니듀" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "아쿠아마린" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "라이트 시 그린" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "다크 시안" +# AI Translated msgid "Teal" -msgstr "" +msgstr "틸" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "다크 슬레이트 그레이" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "라이트 슬레이트 그레이" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "슬레이트 그레이" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "딥 스카이 블루" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "다저 블루" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "스카이 블루" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "라이트 스카이 블루" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "라이트 블루" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "파우더 블루" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "라이트 스틸 블루" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "스틸 블루" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "콘플라워 블루" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "로열 블루" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "미디엄 블루" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "미드나이트 블루" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "다크 블루" +# AI Translated msgid "Navy" -msgstr "" +msgstr "네이비" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "슬레이트 블루" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "다크 슬레이트 블루" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "미디엄 슬레이트 블루" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "블루 바이올렛" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "인디고" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "다크 바이올렛" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "다크 오키드" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "미디엄 오키드" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "오키드" +# AI Translated msgid "Violet" -msgstr "" +msgstr "바이올렛" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "미디엄 퍼플" +# AI Translated msgid "Purple" -msgstr "" +msgstr "퍼플" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "레베카 퍼플" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "미디엄 바이올렛 레드" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "페일 바이올렛 레드" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "딥 핑크" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "핫 핑크" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "라이트 핑크" +# AI Translated msgid "Pink" -msgstr "" +msgstr "핑크" +# AI Translated msgid "Plum" -msgstr "" +msgstr "플럼" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "시슬" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "푸크시아" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "다크 마젠타" +# AI Translated msgid "Linen" -msgstr "" +msgstr "리넨" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "올드 레이스" +# AI Translated msgid "Sea shell" -msgstr "" +msgstr "시 쉘" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "아이보리" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "플로럴 화이트" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "라벤더 블러시" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "고스트 화이트" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "앨리스 블루" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "라벤더" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "화이트 스모크" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "게인즈버러" +# AI Translated msgid "Black" -msgstr "" +msgstr "블랙" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "코랄 파이어" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "시 아네모네" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "딥 어비스" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "랍스터 레드" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "샌디 클레이" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "드리프트우드" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "시 벅손" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "선셋 리프" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "타이거 코랄" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "핑크 코랄" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "시쉘 글로" +# AI Translated msgid "Sand" -msgstr "" +msgstr "샌드" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "골든 켈프" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "선릿 듄" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "앰버 노틸러스" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "시 레몬" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "페일 스타피시" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "스프링 타이드" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "라임 앨지" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "시 그래스" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "네온 플랑크톤" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "켈프 포레스트" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "에메랄드 웨이브" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "웨일 섀도" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "시 터틀" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "라군" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "트로피컬 커런트" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "미드나이트 트렌치" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "다크 켈프" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "크리스털 서프" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "터콰이즈 베이" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "스카이 오버 리프" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "섈로 스카이" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "일렉트릭 블루" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "돌핀" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "오션 뎁스" +# AI Translated msgid "Whale" -msgstr "" +msgstr "웨일" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "인디고 어비스" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "시 어친" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "라벤더 코랄" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "바이올렛 타이드" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "딥 시 오키드" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "네온 젤리" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "푸크시아 코랄" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "핑크 젤리피시" +# AI Translated msgid "Foam" -msgstr "" +msgstr "폼" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "시쉘 화이트" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "페블 그레이" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "스톰 클라우드" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "잉크 블랙" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "그린 베이지" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "샌드 옐로" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "시그널 옐로" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "골든 옐로" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "허니 옐로" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "메이즈 옐로" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +# Needs human review: Check the Korean name for daffodil: 수선화 (narcissus) is used; a transliteration such as 대포딜 is the alternative. +msgid "Daffodil yellow" +msgstr "수선화 옐로" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "브라운 베이지" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "레몬 옐로" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "오이스터 화이트" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "라이트 아이보리" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "징크 옐로" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "그레이 베이지" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "올리브 옐로" +# AI Translated +# Needs human review: RAL name (rapeseed); check the plant name reads naturally as a color. msgid "Rape yellow" -msgstr "" +msgstr "유채꽃 옐로" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "트래픽 옐로" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "오커 옐로" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "트래픽 오렌지 옐로" +# AI Translated msgid "Curry" -msgstr "" +msgstr "커리" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "멜론 옐로" +# AI Translated +# Needs human review: RAL name (broom, the plant); check the rendering. msgid "Broom yellow" -msgstr "" +msgstr "브룸 옐로" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "달리아 옐로" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "파스텔 옐로" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "펄 베이지" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "펄 골드" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "선 옐로" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "옐로 오렌지" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "딥 오렌지" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "버밀리언" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "펄 오렌지" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "퓨어 오렌지" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "루미너스 오렌지" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "루미너스 브라이트 오렌지" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "브라이트 레드 오렌지" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "트래픽 오렌지" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "시그널 오렌지" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "살몬 오렌지" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "펄 핑크" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "코퍼 오렌지" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "시그널 브라운" +# AI Translated +# Needs human review: Source name is odd (RAL has Fir green); fir rendered as the tree. msgid "Fir orange" -msgstr "" +msgstr "전나무 오렌지" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "시그널 레드" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "루미너스 레드" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "카민 레드" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "펄 카민 레드" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "퓨어 레드" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "루미너스 딥 레드" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "커런트 레드" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "펄 루비 레드" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "파이어 레드" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "루비 레드" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "퍼플 레드" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "와인 레드" +# AI Translated msgid "Black red" -msgstr "" +msgstr "블랙 레드" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "옥사이드 레드" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "브라운 레드" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "파인 레드" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "토마토 레드" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "앤티크 핑크" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "코랄 레드" +# AI Translated msgid "Rose" -msgstr "" +msgstr "로즈" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "스트로베리 레드" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "트래픽 레드" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "살몬 핑크" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "루미너스 로즈" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "루미너스 브라이트 레드" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "라즈베리 레드" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "오리엔트 레드" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "펄 루비" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "레드 퍼플" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "레드 바이올렛" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "헤더 바이올렛" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "보르도 바이올렛" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "마호가니" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "그레이 퍼플" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "시그널 바이올렛" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "전나무 그린" +# AI Translated +# Needs human review: Source name unclear (Sabine); transliterated. msgid "Sabine grey" -msgstr "" +msgstr "사빈 그레이" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "펄 바이올렛" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "펄 블랙베리" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "그린 블루" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "울트라마린 블루" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "사파이어 블루" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "블랙 블루" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "시그널 블루" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "브릴리언트 블루" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "그레이 블루" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "애저 블루" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "젠티안 블루" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "코발트 블루" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "피존 블루" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "트래픽 블루" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "터콰이즈 블루" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "카프리 블루" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "오션 블루" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "워터 블루" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "나이트 블루" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "디스턴트 블루" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "파스텔 블루" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "펄 젠티안 블루" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "펄 미드나이트 블루" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "파티나 그린" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "에메랄드 그린" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "리프 그린" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "올리브 그린" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "블루 그린" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "모스 그린" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "그레이 올리브" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "파인 그린" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "파인 브라운" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "그래스 그린" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "레세다 그린" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "브라운 그린" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "리드 그린" +# AI Translated msgid "Black green" -msgstr "" +msgstr "블랙 그린" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "터콰이즈 그린" +# AI Translated msgid "May green" -msgstr "" +msgstr "메이 그린" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "크롬 옥사이드 그린" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "트래픽 그린" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "펀 그린" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "오팔 그린" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "민트 그린" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "브론즈 그린" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "펄 그린" +# AI Translated msgid "Sax turquoise" -msgstr "" +msgstr "삭스 터콰이즈" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "펄 터콰이즈" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "펄 제이드" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "퓨어 그린" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "루미너스 그린" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "스쿼럴 그레이" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "실버 그레이" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "올리브 그레이" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "모스 그레이" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "시그널 그레이" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "마우스 그레이" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "베이지 그레이" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "카키 그레이" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "그린 그레이" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "타폴린 그레이" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "아이언 그레이" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "바솔트 그레이" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "브라운 그레이" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "슬레이트 그레이" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "앤트러사이트 그레이" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "라이트 그레이" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "엄버 그레이" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "콘크리트 그레이" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "그래파이트 그레이" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "그래나이트 그레이" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "스톤 그레이" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "페블 그레이" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "시멘트 그레이" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "옐로 그레이" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "플래티넘 그레이" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "더스티 그레이" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "아게이트 그레이" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "쿼츠 그레이" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "윈도 그레이" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "트래픽 그레이 A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "트래픽 그레이 B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "실크 그레이" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "텔레그레이 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "텔레그레이 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "텔레그레이 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "펄 마우스 그레이" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "그린 브라운" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "오커 브라운" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "클레이 브라운" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "코퍼 브라운" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "초콜릿 브라운" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "올리브 브라운" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "너트 브라운" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "레드 브라운" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "세피아 브라운" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "체스트넛 브라운" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "마호가니 브라운" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "그레이 브라운" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "펄 코퍼" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "베이지 브라운" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "펄 모카 브라운" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "어스 브라운" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "펄 브라운" +# AI Translated msgid "Cream" -msgstr "" +msgstr "크림" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "그레이 화이트" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "시그널 화이트" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "시그널 블랙" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "제트 블랙" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "화이트 알루미늄" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "그레이 알루미늄" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "퓨어 화이트" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "그래파이트 블랙" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "트래픽 화이트" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "트래픽 블랙" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "파피루스 화이트" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "펄 라이트 그레이" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "메탈: 실버" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "메탈: 브라스" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "메탈: 골드" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "메탈: 코퍼" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "메탈: 브론즈" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "네이처: 펄" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "네이처: 레인보우" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "네이처: 클리어 스카이" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "네이처: 선셋" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "우드: 다크" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "우드: 미디엄" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "우드: 라이트" # AI Translated msgid "Alternate nozzles:" @@ -32924,13 +33363,25 @@ msgstr "내 텍스처에서 제거" msgid "Built-in" msgstr "기본 제공" +# AI Translated +msgid "My textures" +msgstr "내 텍스처" + # AI Translated msgid "No textures found." msgstr "텍스처가 없습니다." # AI Translated -msgid "My textures" -msgstr "내 텍스처" +msgid "Texture libraries" +msgstr "텍스처 라이브러리" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "더 많은 텍스처 라이브러리 둘러보기" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "홈 페이지에서 OrcaCloud를 열어 플러그인을 찾아봅니다." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33333,11 +33784,15 @@ msgstr "모델 자체의 UV 레이아웃으로 매핑됩니다. 이 레이아웃 msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "모델 위에서 텍스처 한 장의 폭입니다. 작을수록 패턴이 더 자주 반복되고 디테일이 더 세밀해집니다. 타일이 꺼져 있으면 단일 텍스처의 크기입니다." +# AI Translated +# Needs human review: Image caption in the tile-size tip (larger tiles); check wording. msgid "Larger" -msgstr "" +msgstr "더 크게" +# AI Translated +# Needs human review: Image caption in the tile-size tip (smaller tiles); check wording. msgid "Smaller" -msgstr "" +msgstr "더 작게" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33413,11 +33868,15 @@ msgstr "혼합 색상" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "굽기에서 추가할 수 있는 혼합 필라멘트의 최대 개수입니다. 텍스처의 색상에서 선택되며, 굽기에서 실제로 사용하는 것만 생성됩니다." +# AI Translated +# Needs human review: Image caption comparing few vs many mixed colors; check wording. msgid "Few" -msgstr "" +msgstr "적음" +# AI Translated +# Needs human review: Image caption comparing few vs many mixed colors; check wording. msgid "Many" -msgstr "" +msgstr "많음" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33768,11 +34227,15 @@ msgstr "리메시" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "모델 전체를 다시 만들 때 사용할 삼각형 크기(밀리미터)입니다. 변위는 고른 메시에서 가장 잘 작동하며, 이 설정으로 고르지 않은 가져온 메시를 고르게 만듭니다." +# AI Translated +# Needs human review: Image caption of the remesh comparison (before/after remeshing); check wording. msgid "Before" -msgstr "" +msgstr "적용 전" +# AI Translated +# Needs human review: Image caption of the remesh comparison (before/after remeshing); check wording. msgid "After" -msgstr "" +msgstr "적용 후" # AI Translated msgid "Keep sharp edges" @@ -35616,6 +36079,10 @@ msgstr "스크립트" msgid "Slicing Pipeline" msgstr "슬라이스 파이프라인" +# AI Translated +msgid "Resource Texture" +msgstr "리소스 텍스처" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "플러그인의 구성 UI가 비어 있습니다. 기본 편집기를 표시합니다." @@ -35763,6 +36230,30 @@ msgstr "플러그인 디렉터리에 .py 및 .whl 진입 파일이 모두 있습 msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "플러그인 디렉터리에 .py 또는 .whl 진입 파일이 없습니다" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "리소스 텍스처 디렉터리가 설정되지 않았습니다" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "리소스 텍스처 디렉터리를 확인할 수 없습니다" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "리소스 텍스처 경로가 디렉터리가 아닙니다" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "플러그인 폴더를 확인할 수 없습니다" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "리소스 텍스처 디렉터리가 플러그인 폴더 밖에 있습니다" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "리소스 텍스처 디렉터리를 읽을 수 없습니다" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36223,7 +36714,7 @@ msgstr "구성 파일 \"%1%\" 로드에 실패했습니다: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "%1%에서 생성한 G-code 파일이 아닙니다." # AI Translated @@ -36343,7 +36834,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "후처리 스크립트를 실행하기 전에 G-code 파일 %1%의 임시 복사본을 만들지 못했습니다: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "후처리기가 내보낸 G-code 파일을 찾을 수 없습니다" # AI Translated @@ -36714,6 +37205,26 @@ msgstr "" "뒤틀림 방지\n" "ABS와 같이 뒤틀림이 발생하기 쉬운 소재를 출력할 때, 히트베드 온도를 적절하게 높이면 뒤틀림 가능성을 줄일 수 있다는 사실을 알고 계셨나요?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "달마시안 옐로" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "캡산틴 바이올렛" + +# AI Translated +#~ msgid "Olivestone" +#~ msgstr "올리브스톤" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "텍스트 필드에 입력하는 중에도 창 어디에서나 사용할 수 있습니다." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "전역 단축키는 텍스트를 입력하는 중에도 적용됩니다." + #~ msgid "Please choose the filament color" #~ msgstr "필라멘트 색상을 선택하세요" @@ -37190,10 +37701,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "구성되지 않은 도구" -# AI Translated -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "출력이 종료될 때의 G-code" - #~ msgid "Maximum X speed" #~ msgstr "X축 최대 속도" @@ -37210,26 +37717,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "슬라이싱 파이프라인의 각 단계에서 호출되어 중간 슬라이싱 데이터를 읽고 수정하는 Python 플러그인입니다. 마지막 G-code 후처리 단계도 포함됩니다. 연구/실험용입니다." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "활성화하면 슬라이서가 주 영역의 내용을 베드 원점(0,0)에 중심을 맞춘 G-code를 생성합니다. 각 물리 영역 위치에 복사본/미러본을 배치하는 것은 프린터 펌웨어가 담당합니다. 복사/미러 모드에서 펌웨어가 자체 영역 오프셋을 적용하는 프린터(예: RepRapFirmware IDEX 복제 모드)에서만 활성화하세요. 주(Primary) 모드에서는 효과가 없습니다." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "물리 헤드를 필라멘트 슬롯(1부터 시작)에 매핑하는 플레이트별 재정의입니다. 비어 있으면 pem 역변환 기본값을 사용합니다." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "슬라이스 전에 메시를 회전시키는 기준 축입니다. 벨트 프린터의 기울기에 해당하며, 왜곡 없는(등거리) 회전으로 베드 렌더링과 서포트 중력 기울기에도 적용됩니다. G-code 역변환은 기계 좌표계 전단/배율 및 재매핑 전에 이 회전을 되돌립니다. 일반적인 갠트리 기울기는 X입니다(벨트는 Y 방향으로 이동)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "전문가용 재정의: 기계 좌표계(G-code 전단/배율) 기울기 각도를 슬라이스 전 회전 각도와 별도로 설정합니다. 비활성화하면 기계 좌표계 변환이 벨트 기울기 각도에서 산출되므로 하나의 각도가 두 단계를 모두 결정합니다. 실제 갠트리 기울기가 슬라이스 회전과 다른 기계를 보정할 때만 활성화하세요." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "'최대 벽 해상도' 설정에 따라 해상도를 낮출 때 허용되는 최대 편차입니다. 이 값을 키우면 출력 정확도는 떨어지지만 G-code 크기는 작아집니다. '최대 벽 편차'는 '최대 벽 해상도'를 제한하므로, 두 설정이 충돌하면 '최대 벽 편차'가 우선합니다." - #~ msgid " not in range " #~ msgstr " 범위를 벗어남 " diff --git a/localization/i18n/lt/OrcaSlicer_lt.po b/localization/i18n/lt/OrcaSlicer_lt.po index 3385fec8ac..cd577e7064 100644 --- a/localization/i18n/lt/OrcaSlicer_lt.po +++ b/localization/i18n/lt/OrcaSlicer_lt.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-07-02 14:13+0300\n" "Last-Translator: Gintaras Kučinskas \n" "Language-Team: \n" @@ -798,17 +798,22 @@ msgstr "Pasirinkimas" msgid "Plate" msgstr "Spausdinimo plokštė" +# AI Translated +# Needs human review: Glossary cell empty for lt; reused the catalog's 'Paskirstyti' (Distribute left-right etc.) msgid "Distribute" -msgstr "" +msgstr "Paskirstyti" msgid "Coordinate system used for transform actions." msgstr "Transformavimo veiksmams naudojama koordinačių sistema." +# AI Translated +# Needs human review: Tooltip in the object manipulation panel; check it reads right next to the align buttons msgid "Reference for alignment" -msgstr "" +msgstr "Sulygiavimo atskaita" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Pasirinkite bent 3 dalis arba objektus" # AI Translated msgid "Align left" @@ -861,8 +866,9 @@ msgstr "Paskirstyti viršaus-apačios kryptimi" msgid "Drop" msgstr "Nuleisti" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Perkelti pasirinkimą išilgai Z ašies taip, kad žemiausias jo taškas liestų pagrindą." msgid "Absolute" msgstr "Absoliutus" @@ -1758,7 +1764,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Formos (%1%) kontūre yra nepalaikomų elementų: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Netinkama būsena. Praneškite atkūrimo veiksmus „GitHub“ svetainėje" # AI Translated @@ -1766,11 +1772,11 @@ msgid "No embossed file" msgstr "Nėra reljefinio failo" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Reljefinėje formoje trūksta SVG failo" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Trūksta SVG failo duomenų" msgid "Face the camera" @@ -2092,17 +2098,21 @@ msgstr "Įjungiamas surinkimo manipuliatorius" msgid "Leaving Assembly gizmo" msgstr "Išjungiamas surinkimo manipuliatorius" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Perpjauto objekto dalių perkelti negalima" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Sulygiuoti pagal plokštę galima tik X ir Y kryptimis" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Išjunkite pasirinktų objektų automatinį nuleidimą, kad galėtumėte juos perkelti Z kryptimi" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Visi pasirinkti objektai turi būti ant tos pačios plokštės" msgid "Shift+" msgstr "Shift+" @@ -4976,7 +4986,7 @@ msgid "Unknown C++ exception." msgstr "Nežinoma C++ išimtis." # AI Translated -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Apdorojamas G-code iš ankstesnio failo…" msgid "Slicing complete" @@ -6536,8 +6546,10 @@ msgstr "Ašys" msgid "Gridlines" msgstr "Tinklelio linijos" +# AI Translated +# Needs human review: Glossary cell empty for lt; check the term for this view mode msgid "Focus mode" -msgstr "" +msgstr "Fokuso režimas" msgid "Labels" msgstr "Etiketės (Užrašai)" @@ -6599,7 +6611,7 @@ msgid "Size:" msgstr "Dydis:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Rasta G-code trajektorijų konfliktų %d sluoksnyje, Z = %.2lfmm. Prašome labiau atskirti konfliktuojančius objektus (%s <-> %s)." @@ -10936,11 +10948,14 @@ msgstr "Rodyti nepalaikomus profilius" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Rodyti nesuderinamus / nepalaikomus profilius spausdintuvų ir gijų išskleidžiamuosiuose sąrašuose. Šių profilių pasirinkti negalima." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Eksportuoti statistiką kartu su G-code" +# AI Translated +# Needs human review: 'feature' here is a print feature type (outer wall, infill...), not the Design-tab feature; check the wording msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Jei įjungta, eksportuojant G-code failą šalia jo kaip .statistics.json įrašoma ir jo statistika JSON formatu, o eksportuotas susluoksniuotas 3MF failas ją turi savyje: spausdinimo laiką, gijos ir linijos tipo sumas bei tuos pačius duomenis pagal sluoksnį ir pagal objektą." msgid "Experimental Features" msgstr "Eksperimentinis" @@ -11797,6 +11812,10 @@ msgstr "Nepavyko įkelti failo į spausdintuvo atmintį. Bandykite dar kartą." msgid "Send Failed" msgstr "Siuntimas nepavyko" +# AI Translated +msgid "No available printers" +msgstr "Nėra galimų spausdintuvų" + msgid "The name length exceeds the limit." msgstr "Pavadinimas viršijo leistiną dydį." @@ -13643,8 +13662,8 @@ msgid "Left mouse" msgstr "Kairysis pelės mygtukas" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Veikia bet kurioje lango vietoje, net rašant teksto lauke." +msgid "Available anywhere in the window." +msgstr "Veikia bet kurioje lango vietoje." # AI Translated msgid "Run favorite 1 to 10" @@ -13756,10 +13775,6 @@ msgstr "%s jau priskirtas: %s. Priskirti jį veiksmui „%s“?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Numatytasis %s jau priskirtas: %s. Priskirti jį veiksmui „%s“?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Visuotiniai spartieji klavišai veikia ir rašant tekstą." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Klavišas, kuris įveda simbolį, negali būti visuotinis spartusis klavišas." @@ -14212,9 +14227,10 @@ msgstr "objekto „%2%“ modifikatorius „%1%“ (iš viso %3%) neturėjo įta msgid "Seam placement may differ from expected." msgstr "Siūlės vieta gali skirtis nuo numatytos." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Nepavyko įrašyti G-code statistikos į %1%." msgid "Internal Bridge" msgstr "Vidinis tiltas" @@ -17605,6 +17621,14 @@ msgstr "Išskirti objektus" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Įjunkite šią parinktį, kad į G-code būtų pridėta komanda EXCLUDE OBJECT." +# AI Translated +msgid "Outline tolerance" +msgstr "Kontūro tolerancija" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Didžiausias į EXCLUDE_OBJECT_DEFINE įrašomo objekto kontūro nuokrypis nuo pradinio kontūro. Didesnės reikšmės sukuria mažiau taškų, o tai padeda programinei aparatinei įrangai, kuri strigsta apdorodama G-code su daug objektų. 0 išsaugo visus taškus." + # AI Translated msgid "Verbose G-code" msgstr "Išsamus G-code (Verbose)" @@ -20826,11 +20850,14 @@ msgstr "Išvesties katalogas" msgid "This is the output directory for exported files." msgstr "Tai yra eksportuotų failų išvesties aplankas." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Eksportuoti statistiką" +# AI Translated +# Needs human review: 'feature' here is a print feature type (outer wall, infill...), not the Design-tab feature; check the wording msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Kiekvienos susluoksniuotos plokštės statistiką įrašo JSON formatu: kaip plate_N.statistics.json šalia jos G-code išvesties kataloge ir į 3MF, sukurtą su --export-3mf: spausdinimo laikas, gijos ir linijos tipo sumos bei tie patys duomenys pagal sluoksnį ir pagal objektą." msgid "Debug level" msgstr "Derinimo lygis" @@ -23239,7 +23266,7 @@ msgstr "pradedamas %s testas..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "%s testas: nustatytas IP = %s" # AI Translated @@ -30639,1231 +30666,1646 @@ msgstr[0] "Dabartiniame gijų sąraše nėra %s. Po išskaidymo automatiškai bu msgstr[1] "Dabartiniame gijų sąraše nėra %s. Po išskaidymo automatiškai bus sukurtos mišriai gijai reikalingos projekto gijos." msgstr[2] "Dabartiniame gijų sąraše nėra %s. Po išskaidymo automatiškai bus sukurtos mišriai gijai reikalingos projekto gijos." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Spalvų parinkiklis" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Pagrindinės spalvos" +# AI Translated +# Needs human review: Glossary cell for Palette empty for lt; 'paletė' used #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "„Orca“ paletė" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL klasikinė" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Gradientai" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Vienspalvė" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Gradientas" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Gradiento pradžia" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Gradiento pabaiga" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Gradiento spalva" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Pridėti spalvą" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Pašalinti spalvą" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Sodrumas" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Pradinė spalva" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Išsaugoti dabartinę spalvą" +# AI Translated +# Needs human review: Glossary cell for Palette empty for lt; 'paletė' used msgid "Palettes" -msgstr "" +msgstr "Paletės" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Ieškoti spalvų" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtruoti spalvas" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Nėra atitinkančių spalvų" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Šešioliktainė spalva" # AI Translated msgid "Opacity" msgstr "Nepermatomumas" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Nepermatomumas (%)" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Išsaugoti spalvą" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Įveskite pilną šešioliktainį spalvos kodą" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Dabartinis kelių spalvų pasirinkimas išsaugomas, kol pasirinksite kitą spalvą." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Palaikoma iki %d spalvų." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmazinas" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Oranžiškai raudona" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Pomidoras" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Oranžinė" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Tamsiai oranžinė" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Auksinė" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Medžio ruda" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Biskvitas" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Rūkuota rožinė" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Šviesiai geltona" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Citrininis šifonas" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Bėžinė" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Šviesiai rykštenio geltona" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Blyški rykštenio geltona" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Chaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Tamsiai chaki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Švelniai persikinė" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mokasinas" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papajų kremas" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Balintas migdolas" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antikinė balta" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navaho balta" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Kviečių" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Rykštenio geltona" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Šokoladinė" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Plytų raudona" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Balno ruda" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Ruda" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Rausvai ruda" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Lašišinė" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Šviesiai lašišinė" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Tamsiai lašišinė" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Smėlio ruda" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Koralinė" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Šviesiai koralinė" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Indiškai raudona" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Tamsiai raudona" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Kaštoninė" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Žalsvai geltona" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Gelsvai žalia" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Šartrezas" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Vejos žalia" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Laimo žalia" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Pavasario žalia" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Vidutinė pavasario žalia" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Laimo" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Miško žalia" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Tamsiai žalia" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Prislopinta alyvuogių" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Alyvuogių" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Tamsiai alyvuogių žalia" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Blyškiai žalia" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Šviesiai žalia" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Vidutinė jūros žalia" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Jūros žalia" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Tamsiai jūros žalia" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Kadeto mėlyna" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Vidutinė akvamarino" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turkio" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Vidutinė turkio" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Tamsiai turkio" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Blyškiai turkio" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Akva" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Šviesiai ciano" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Mėtinis kremas" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Medaus melionas" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Akvamarinas" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Šviesiai jūros žalia" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Tamsiai ciano" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Žalsvai žydra" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Tamsiai skalūno pilka" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Šviesiai skalūno pilka" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Skalūno pilka" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Sodri dangaus mėlyna" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodžerių mėlyna" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Dangaus mėlyna" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Šviesiai dangaus mėlyna" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Šviesiai mėlyna" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Pudros mėlyna" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Šviesiai plieno mėlyna" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Plieno mėlyna" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Rugiagėlių mėlyna" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Karališka mėlyna" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Vidutinė mėlyna" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Vidurnakčio mėlyna" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Tamsiai mėlyna" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Jūrų laivyno mėlyna" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Skalūno mėlyna" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Tamsiai skalūno mėlyna" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Vidutinė skalūno mėlyna" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Mėlynai violetinė" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Tamsiai violetinė" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Tamsi orchidėja" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Vidutinė orchidėja" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidėja" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violetinė" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Vidutinė purpurinė" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Purpurinė" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebekos purpurinė" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Vidutinė violetinė raudona" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Blyškiai violetinė raudona" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Sodri rožinė" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Ryškiai rožinė" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Šviesiai rožinė" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rožinė" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Slyvų" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Usnių" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuksija" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Tamsiai magenta" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lino" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Seni nėriniai" +# AI Translated +# Needs human review: CSS color 'seashell'; Shell glossary warning is a false match (not the print shell) msgid "Sea shell" -msgstr "" +msgstr "Kriauklė" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Dramblio kaulo" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Gėlių balta" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Levandų rausva" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Šmėklos balta" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Alisos mėlyna" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Levandų" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Dūmų balta" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Juoda" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Koralų ugnis" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Jūros anemonė" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Gili bedugnė" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Omaro raudona" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Smėlingas molis" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Jūros išplauta mediena" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Šaltalankis" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Saulėlydžio rifas" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tigrinis koralas" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Rožinis koralas" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Kriauklės žara" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Smėlis" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Auksinis rudadumblis" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Saulės nutviesta kopa" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Gintaro nautilas" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Jūros citrina" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Blyški jūrų žvaigždė" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Pavasario potvynis" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Laimo dumbliai" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Jūros žolė" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neoninis planktonas" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Rudadumblių miškas" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Smaragdo banga" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Banginio šešėlis" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Jūros vėžlys" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagūna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Tropinė srovė" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Vidurnakčio įduba" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Tamsus rudadumblis" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Krištolinė banga" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Turkio įlanka" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Dangus virš rifo" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Seklumos dangus" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektrinė mėlyna" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfinas" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Vandenyno gelmės" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Banginis" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indigo bedugnė" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Jūros ežys" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Levandų koralas" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Violetinis potvynis" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Giliavandenė orchidėja" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neoninė medūza" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuksijos koralas" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Rožinė medūza" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Putos" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Kriauklės balta" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Akmenukų pilka" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Audros debesis" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Rašalo juoda" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Žalsvai bėžinė" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Smėlio geltona" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Signalinė geltona" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Auksinė geltona" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Medaus geltona" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Kukurūzų geltona" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Narcizų geltona" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Rusvai bėžinė" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Citrinų geltona" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Austrės balta" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Šviesi dramblio kaulo" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Cinko geltona" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Pilkšvai bėžinė" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Alyvuogių geltona" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Rapsų geltona" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Eismo geltona" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Ochros geltona" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Eismo oranžiškai geltona" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Kario" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Melionų geltona" +# AI Translated +# Needs human review: RAL 1032 'broom' (genista/Cytisus); check the Lithuanian plant name msgid "Broom yellow" -msgstr "" +msgstr "Šluotos geltona" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Jurginų geltona" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pastelinė geltona" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Perlinė bėžinė" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Perlinė auksinė" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Saulės geltona" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Gelsvai oranžinė" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Sodri oranžinė" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Cinobro" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Perlinė oranžinė" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Gryna oranžinė" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Švytinti oranžinė" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Švytinti ryškiai oranžinė" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Ryški raudonai oranžinė" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Eismo oranžinė" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Signalinė oranžinė" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Lašišos oranžinė" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Perlinė rožinė" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Vario oranžinė" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Signalinė ruda" +# AI Translated +# Needs human review: RAL 2018 name; 'Fir' rendered as kėnis; check against the Lithuanian RAL chart msgid "Fir orange" -msgstr "" +msgstr "Kėnio oranžinė" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Signalinė raudona" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Švytinti raudona" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karmino raudona" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Perlinė karmino raudona" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Gryna raudona" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Švytinti sodriai raudona" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Serbentų raudona" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Perlinė rubino raudona" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Ugnies raudona" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rubino raudona" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Purpurinė raudona" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Vyno raudona" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Juodai raudona" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oksido raudona" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Rusvai raudona" +# AI Translated +# Needs human review: RAL 3012 name; check against the Lithuanian RAL chart msgid "Pine red" -msgstr "" +msgstr "Pušies raudona" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Pomidorinė raudona" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Antikinė rožinė" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Koralų raudona" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rožė" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Braškių raudona" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Eismo raudona" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Lašišos rožinė" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Švytinti rožinė" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Švytinti ryškiai raudona" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Aviečių raudona" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Rytų raudona" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Perlinis rubinas" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Raudonai purpurinė" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Raudonai violetinė" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Viržių violetinė" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordo violetinė" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Raudonmedis" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Pilkšvai purpurinė" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Signalinė violetinė" +# AI Translated +# Needs human review: Used for both RAL 4009 and 6009 (source reuses one msgid); check against the Lithuanian RAL chart msgid "Fir green" -msgstr "" +msgstr "Kėnio žalia" +# AI Translated +# Needs human review: RAL 4010 name (a violet-grey); unclear source term, check against the Lithuanian RAL chart msgid "Sabine grey" -msgstr "" +msgstr "Sabinų pilka" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Perlinė violetinė" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Perlinė gervuogių" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Žalsvai mėlyna" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarino mėlyna" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Safyro mėlyna" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Juodai mėlyna" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Signalinė mėlyna" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Žėrinti mėlyna" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Pilkšvai mėlyna" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Žydra" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Gencijonų mėlyna" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobalto mėlyna" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Karvelių mėlyna" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Eismo mėlyna" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Turkio mėlyna" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Kaprio mėlyna" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Vandenyno mėlyna" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Vandens mėlyna" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Nakties mėlyna" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Tolimoji mėlyna" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pastelinė mėlyna" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Perlinė gencijonų mėlyna" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Perlinė vidurnakčio mėlyna" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patinos žalia" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Smaragdo žalia" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Lapų žalia" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Alyvuogių žalia" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Melsvai žalia" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Samanų žalia" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Pilkšvai alyvuogių" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Pušies žalia" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Pušies ruda" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Žolės žalia" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Rezedos žalia" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Rusvai žalia" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Nendrių žalia" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Juodai žalia" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Turkio žalia" +# AI Translated msgid "May green" -msgstr "" +msgstr "Gegužės žalia" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Chromo oksido žalia" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Eismo žalia" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Paparčių žalia" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opalo žalia" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Mėtų žalia" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Bronzos žalia" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Perlinė žalia" +# AI Translated msgid "Sax turquoise" -msgstr "" +msgstr "Saksų turkio" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Perlinė turkio" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Perlinis nefritas" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Gryna žalia" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Švytinti žalia" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Voverės pilka" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Sidabrinė pilka" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Alyvuogių pilka" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Samanų pilka" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Signalinė pilka" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Pelės pilka" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Bėžinė pilka" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Chaki pilka" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Žalsvai pilka" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Brezento pilka" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Geležies pilka" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Bazalto pilka" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Rusvai pilka" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Skalūno pilka" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antracito pilka" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Šviesiai pilka" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umbros pilka" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Betono pilka" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafito pilka" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Granito pilka" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Akmens pilka" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Akmenukų pilka" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Cemento pilka" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Gelsvai pilka" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platinos pilka" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Dulkėta pilka" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Agato pilka" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Kvarco pilka" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Lango pilka" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Eismo pilka A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Eismo pilka B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Šilko pilka" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telepilka 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telepilka 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telepilka 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Perlinė pelės pilka" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Žalsvai ruda" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Ochros ruda" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Molio ruda" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Vario ruda" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Šokolado ruda" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Alyvuogių ruda" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Riešutų ruda" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Raudonai ruda" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sepijos ruda" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Kaštonų ruda" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Raudonmedžio ruda" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Pilkšvai ruda" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Perlinis varis" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Bėžinė ruda" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Perlinė mokos ruda" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Žemės ruda" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Perlinė ruda" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Kreminė" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Pilkšvai balta" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Signalinė balta" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Signalinė juoda" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Gagato juoda" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Balta aliuminio" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Pilka aliuminio" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Gryna balta" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Grafito juoda" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Eismo balta" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Eismo juoda" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papiruso balta" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Perlinė šviesiai pilka" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metalas: Sidabras" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metalas: Žalvaris" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metalas: Auksas" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metalas: Varis" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metalas: Bronza" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Gamta: Perlas" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Gamta: Vaivorykštė" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Gamta: Giedras dangus" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Gamta: Saulėlydis" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Mediena: Tamsi" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Mediena: Vidutinė" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Mediena: Šviesi" # AI Translated msgid "Alternate nozzles:" @@ -32341,13 +32783,25 @@ msgstr "Pašalinti iš „Mano tekstūros“" msgid "Built-in" msgstr "Integruotos" +# AI Translated +msgid "My textures" +msgstr "Mano tekstūros" + # AI Translated msgid "No textures found." msgstr "Tekstūrų nerasta." # AI Translated -msgid "My textures" -msgstr "Mano tekstūros" +msgid "Texture libraries" +msgstr "Tekstūrų bibliotekos" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Naršyti daugiau tekstūrų bibliotekų" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Atidaro „OrcaCloud“ pradžios puslapyje, kad galėtumėte naršyti papildinius." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32750,11 +33204,15 @@ msgstr "Tekstūra dedama pagal paties modelio UV išdėstymą, kuris jau nustato msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Kokio pločio yra viena tekstūros kopija ant modelio. Mažesnė reikšmė dažniau kartoja raštą ir smulkina jo detales; išjungus „Plytelės“, tai vienintelės kopijos dydis." +# AI Translated +# Needs human review: Caption under a tile-size picture in the Texture displacement gizmo; check gender/fit msgid "Larger" -msgstr "" +msgstr "Didesnis" +# AI Translated +# Needs human review: Caption under a tile-size picture in the Texture displacement gizmo; check gender/fit msgid "Smaller" -msgstr "" +msgstr "Mažesnis" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -32830,11 +33288,15 @@ msgstr "Mišrios spalvos" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Didžiausias mišrių gijų skaičius, kurį gali pridėti įkepimas. Jos parenkamos iš tekstūros spalvų, ir sukuriamos tik tos, kurias įkepimas iš tikrųjų naudoja." +# AI Translated +# Needs human review: Caption under a mixed-colors picture in the Texture displacement gizmo; check it fits msgid "Few" -msgstr "" +msgstr "Mažai" +# AI Translated +# Needs human review: Caption under a mixed-colors picture in the Texture displacement gizmo; check it fits msgid "Many" -msgstr "" +msgstr "Daug" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33195,11 +33657,15 @@ msgstr "Pertinklinimas" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Trikampių dydis, kuriuo perkuriamas visas modelis, milimetrais. Reljefas geriausiai formuojamas ant tolygaus tinklelio; būtent ši parinktis iš netolygaus importuoto modelio padaro tolygų." +# AI Translated +# Needs human review: Caption under the remesh before/after picture; check it fits msgid "Before" -msgstr "" +msgstr "Prieš" +# AI Translated +# Needs human review: Caption under the remesh before/after picture; check it fits msgid "After" -msgstr "" +msgstr "Po" # AI Translated msgid "Keep sharp edges" @@ -35087,6 +35553,10 @@ msgstr "Scenarijus" msgid "Slicing Pipeline" msgstr "Sluoksniavimo grandinė" +# AI Translated +msgid "Resource Texture" +msgstr "Išteklių tekstūra" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Papildinio konfigūracijos sąsaja tuščia. Rodomas numatytasis redaktorius." @@ -35234,6 +35704,30 @@ msgstr "Papildinio kataloge yra ir .py, ir .whl įėjimo failai" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Papildinio kataloge nėra .py ar .whl įėjimo failo" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Išteklių tekstūros katalogas nenustatytas" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Nepavyko nustatyti išteklių tekstūros katalogo" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Išteklių tekstūros kelias nėra katalogas" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Nepavyko nustatyti papildinio aplanko" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Išteklių tekstūros katalogas yra už papildinio aplanko ribų" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Nepavyko nuskaityti išteklių tekstūros katalogo" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -35694,7 +36188,7 @@ msgstr "Nepavyko įkelti konfigūracijos failo „%1%“: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Tai ne %1% sugeneruotas G-code failas." # AI Translated @@ -35814,7 +36308,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Nepavyko sukurti laikinos G-code failo %1% kopijos prieš paleidžiant papildomo apdorojimo scenarijų: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Papildomo apdorojimo programa neranda eksportuoto G-code failo" # AI Translated @@ -36184,6 +36678,28 @@ msgstr "" "Venkite deformacijų (warping)\n" "Ar žinojote, kad spausdinant medžiagas, kurios yra linkusios trauktis ir riestis (pvz., ABS), tinkamas kaitinamojo pagrindo temperatūros padidinimas gali sumažinti deformacijų (warping) tikimybę?" +# AI Translated +# Needs human review: Source likely a typo for RAL 1007 Daffodil yellow; translated as daffodil +#~ msgid "Dalmatian yellow" +#~ msgstr "Narcizų geltona" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Kapsantino violetinė" + +# AI Translated +# Needs human review: RAL 7002 name (olive grey); unclear source term, check against the Lithuanian RAL chart +#~ msgid "Olivestone" +#~ msgstr "Alyvuogių akmuo" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Veikia bet kurioje lango vietoje, net rašant teksto lauke." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Visuotiniai spartieji klavišai veikia ir rašant tekstą." + #~ msgid "Please choose the filament color" #~ msgstr "Pasirinkite gijos spalvą" @@ -36664,10 +37180,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "nėra sukonfigūruoto įrankio" -# AI Translated -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Pabaigos G-code, vykdomas baigus visą spausdinimą." - #~ msgid "Maximum X speed" #~ msgstr "Didžiausias X greitis" @@ -36684,26 +37196,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Python papildinys (-iai), iškviečiamas kiekviename pjaustymo konvejerio žingsnyje, kad nuskaitytų ir keistų tarpinius pjaustymo duomenis, įskaitant galutinį G-code po apdorojimo žingsnį. Tyrimų/eksperimentinis." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Kai įjungta, pjaustyklė generuoja G-code, kuriame pagrindinės zonos turinys centruotas pagrindo koordinačių pradžioje (0,0). Kopijas ir veidrodinius atvaizdus kiekvienos fizinės zonos padėtyje išdėsto spausdintuvo programinė aparatinė įranga. Įjunkite tik tuose spausdintuvuose, kurių programinė aparatinė įranga kopijos (Copy) / veidrodžio (Mirror) režimu pati taiko zonų poslinkius (pvz., RepRapFirmware IDEX dubliavimo režimas). Režimu „Pagrindinis“ neturi jokio poveikio." - # AI Translated # Needs human review: 'pem-inversion' is an undefined internal term kept verbatim; check what it refers to and whether it should be explained or translated. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Plokštės lygmens perrašymas, susiejantis fizines galvutes su gijų lizdais (numeruojama nuo 1). Tuščia reiškia, kad naudojami numatytieji pem-inversion nustatymai." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Ašis, apie kurią poligoninis tinklas pasukamas prieš sluoksniavimą. Tai juostinio spausdintuvo pokrypis: izometrinis (be iškraipymų) pasukimas, kuris taip pat lemia pagrindo atvaizdavimą ir atramų sunkio jėgos pokrypį ir kurį atvirkštinė G-code transformacija panaikina prieš mašinos koordinačių sistemos šlytį / mastelį ir ašių perskirstymą. X – įprastas portalo pokrypis (juosta juda išilgai Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Eksperto parinktis: nustatyti mašinos koordinačių sistemos (G-code šlyties / mastelio) pokrypio kampą nepriklausomai nuo pasukimo prieš sluoksniavimą kampo. Kai išjungta, mašinos koordinačių sistemos transformacija išvedama iš juostos pokrypio kampo, todėl vienas kampas valdo abu etapus. Įjunkite tik tada, kai reikia kompensuoti įrenginį, kurio fizinis portalo pokrypis skiriasi nuo sluoksniavimo pasukimo." - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Didžiausias leidžiamas nuokrypis, mažinant „Didžiausios sienelės raiškos“ nustatymo skiriamąją gebą. Jei jį padidinsite, spaudinys bus mažiau tikslus, tačiau G-kodas (G-Code) bus mažesnės apimties. „Didžiausias sienelės nuokrypis“ riboja „Didžiausią sienelės raišką“, todėl jei šie du nustatymai konfliktuoja, viršenybė teikiama „Didžiausiam sienelės nuokrypiui“." - #~ msgid " not in range " #~ msgstr " nepatenka į intervalą " diff --git a/localization/i18n/nl/OrcaSlicer_nl.po b/localization/i18n/nl/OrcaSlicer_nl.po index 518e4a1cde..1bce6a3f3f 100644 --- a/localization/i18n/nl/OrcaSlicer_nl.po +++ b/localization/i18n/nl/OrcaSlicer_nl.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -810,18 +810,22 @@ msgstr "Selectie" msgid "Plate" msgstr "Printbed" +# AI Translated +# Needs human review: Glossary has no Dutch term yet; Verdelen matches the existing Uitlijnen/Verdelen. msgid "Distribute" -msgstr "" +msgstr "Verdelen" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Coördinatensysteem dat wordt gebruikt voor transformatiebewerkingen." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Referentie voor uitlijning" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Selecteer minstens 3 onderdelen of objecten" # AI Translated msgid "Align left" @@ -874,8 +878,9 @@ msgstr "Boven-onder verdelen" msgid "Drop" msgstr "Neerzetten" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Verplaats de selectie langs Z zodat het laagste punt het printbed raakt." # AI Translated msgid "Absolute" @@ -1870,7 +1875,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "De lijn van vorm (%1%) bevat niet-ondersteund: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Ongeldige status; meld de stappen om dit te reproduceren op GitHub" # AI Translated @@ -1878,11 +1883,11 @@ msgid "No embossed file" msgstr "Geen reliëfbestand" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "SVG-bestand ontbreekt in de reliëfvorm" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Gegevens van het SVG-bestand ontbreken" # AI Translated @@ -2257,17 +2262,21 @@ msgstr "Samenstelgizmo starten" msgid "Leaving Assembly gizmo" msgstr "Samenstelgizmo verlaten" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Onderdelen van een gesneden object kunnen niet worden verplaatst" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Uitlijnen op het printbed is alleen mogelijk in X en Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Schakel Automatisch laten vallen uit voor de geselecteerde objecten om ze in Z te verplaatsen" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Alle geselecteerde objecten moeten op hetzelfde printbed staan" msgid "Shift+" msgstr "Shift+" @@ -5371,7 +5380,7 @@ msgstr "Sla uw project alstublieft op en herstart het programma." msgid "Unknown C++ exception." msgstr "Onbekende C++-uitzondering." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "De G-code van het vorige bestand wordt verwerkt..." msgid "Slicing complete" @@ -7030,8 +7039,10 @@ msgstr "Assen" msgid "Gridlines" msgstr "Rasterlijnen" +# AI Translated +# Needs human review: Glossary has no Dutch term for Focus mode yet; Focusmodus chosen. msgid "Focus mode" -msgstr "" +msgstr "Focusmodus" # AI Translated msgid "Labels" @@ -7095,7 +7106,7 @@ msgid "Size:" msgstr "Maat:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Er zijn conflicten tussen G-code-paden gevonden op laag %d, Z = %.2lfmm. Plaats de conflicterende objecten verder uit elkaar (%s <-> %s)." @@ -11752,11 +11763,13 @@ msgstr "Niet-ondersteunde voorinstellingen tonen" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Toon incompatibele/niet-ondersteunde voorinstellingen in de keuzelijsten voor printer en filament. Deze voorinstellingen kunnen niet worden geselecteerd." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Statistieken exporteren met de G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Indien ingeschakeld schrijft het exporteren van een G-codebestand ook de bijbehorende statistieken als JSON ernaast, als .statistics.json, en een geëxporteerd gesliced 3MF-bestand bevat ze intern: printtijd, totalen voor filament en lijntypen, en dezelfde gegevens per laag en per object." # AI Translated msgid "Experimental Features" @@ -12650,6 +12663,10 @@ msgstr "Uploaden van het bestand naar de opslag van de printer is mislukt. Probe msgid "Send Failed" msgstr "Verzenden mislukt" +# AI Translated +msgid "No available printers" +msgstr "Geen beschikbare printers" + # AI Translated msgid "The name length exceeds the limit." msgstr "De naam is langer dan toegestaan." @@ -14644,8 +14661,8 @@ msgid "Left mouse" msgstr "Linkermuisknop" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Overal in het venster beschikbaar, zelfs tijdens het typen in een tekstveld." +msgid "Available anywhere in the window." +msgstr "Overal in het venster beschikbaar." # AI Translated msgid "Run favorite 1 to 10" @@ -14758,10 +14775,6 @@ msgstr "%s is toegewezen aan %s. Opnieuw toewijzen aan %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "De standaardsneltoets %s is toegewezen aan %s. Opnieuw toewijzen aan %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Globale sneltoetsen werken ook tijdens het typen." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Een toets die een teken typt, kan geen globale sneltoets zijn." @@ -15241,9 +15254,10 @@ msgstr "aanpasser \"%1%\" van \"%2%\" (%3% in totaal) had geen effect op de naad msgid "Seam placement may differ from expected." msgstr "De plaatsing van de naad kan afwijken van wat verwacht wordt." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "De G-codestatistieken konden niet naar %1% worden geschreven." # AI Translated msgid "Internal Bridge" @@ -18985,6 +18999,14 @@ msgstr "Objecten uitsluiten" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Schakel deze optie in om de opdracht EXCLUDE OBJECT aan de G-code toe te voegen." +# AI Translated +msgid "Outline tolerance" +msgstr "Omtrektolerantie" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Maximale afwijking van de objectomtrek die naar EXCLUDE_OBJECT_DEFINE wordt geschreven ten opzichte van de oorspronkelijke omtrek. Hogere waarden geven minder punten, wat helpt bij firmware die vastloopt bij het verwerken van G-code met veel objecten. 0 behoudt elk punt." + msgid "Verbose G-code" msgstr "Opmerkingen in G-code" @@ -22565,11 +22587,13 @@ msgstr "Uitvoermap" msgid "This is the output directory for exported files." msgstr "Dit is de map waarin de geëxporteerde bestanden worden opgeslagen" +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Statistieken exporteren" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Schrijft de statistieken van elk printbed na het slicen als JSON, als plate_N.statistics.json naast de G-code in de uitvoermap en in de 3MF van --export-3mf: printtijd, totalen voor filament en lijntypen, en dezelfde gegevens per laag en per object." msgid "Debug level" msgstr "Debuggen level" @@ -25201,7 +25225,7 @@ msgstr "test %s gestart..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "test %s ip omgezet = %s" # AI Translated @@ -32838,1231 +32862,1651 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "De huidige filamentlijst bevat geen %s. Een projectfilament dat het gemengde filament nodig heeft, wordt na de ontleding automatisch aangemaakt." msgstr[1] "De huidige filamentlijst bevat geen %s. Projectfilamenten die het gemengde filament nodig heeft, worden na de ontleding automatisch aangemaakt." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Kleurkiezer" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Basiskleuren" +# AI Translated +# Needs human review: Glossary has no Dutch term for Palette yet; Palet chosen. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca-palet" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Classic" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Verlopen" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Effen" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Verloop" +# AI Translated +# Needs human review: Color picker label for the start of a gradient; check it reads right next to the field. msgid "Gradient start" -msgstr "" +msgstr "Begin van verloop" +# AI Translated +# Needs human review: Color picker label for the end of a gradient; check it reads right next to the field. msgid "Gradient end" -msgstr "" +msgstr "Einde van verloop" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Verloopkleur" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Kleur toevoegen" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Kleur verwijderen" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Verzadiging" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Oorspronkelijke kleur" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Huidige kleur opslaan" +# AI Translated +# Needs human review: Glossary has no Dutch term for Palette yet; Palet/Paletten chosen. msgid "Palettes" -msgstr "" +msgstr "Paletten" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Kleuren zoeken" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Kleuren filteren" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Geen overeenkomende kleuren" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Hexkleur" # AI Translated msgid "Opacity" msgstr "Dekking" +# AI Translated +# Needs human review: Label of the opacity percent input in the color picker; check it reads right next to the field. msgid "Opacity percent" -msgstr "" +msgstr "Dekking in procent" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Kleur opslaan" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Voer een volledige hexadecimale kleur in" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "De huidige meerkleurenselectie blijft behouden tot een andere kleur wordt gekozen." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Maximaal %d kleuren worden ondersteund." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmozijnrood" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Oranjerood" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Tomaat" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Oranje" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Donkeroranje" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Goud" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Houtbruin" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Bisque" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Nevelroze" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Lichtgeel" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Citroenchiffon" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beige" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Lichtguldenroedegeel" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Bleke guldenroede" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Kaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Donkerkaki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Perzikroom" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mocassin" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papajaroom" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Gepelde amandel" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antiekwit" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navajowit" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Tarwe" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Guldenroede" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Chocolade" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Baksteenrood" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Sienna" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Zadelbruin" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Bruin" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Rozebruin" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Zalm" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Lichte zalm" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Donkere zalm" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Zandbruin" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Koraal" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Licht koraal" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Indisch rood" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Donkerrood" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Kastanjerood" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Groengeel" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Geelgroen" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Gazongroen" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Limoengroen" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Lentegroen" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Midden-lentegroen" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Limoen" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Bosgroen" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Donkergroen" +# AI Translated +# Needs human review: CSS olive drab has no common Dutch name; Matolijf chosen. msgid "Olive drab" -msgstr "" +msgstr "Matolijf" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Olijf" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Donkerolijfgroen" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Bleekgroen" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Lichtgroen" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Midden-zeegroen" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Zeegroen" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Donkerzeegroen" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Cadetblauw" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Midden-aquamarijn" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turkoois" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Midden-turkoois" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Donkerturkoois" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Bleekturkoois" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Lichtcyaan" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Muntroom" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Honingdauw" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Aquamarijn" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Lichtzeegroen" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Donkercyaan" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Petrol" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Donkerleigrijs" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Lichtleigrijs" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Leigrijs" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Diephemelsblauw" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodgerblauw" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Hemelsblauw" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Lichthemelsblauw" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Lichtblauw" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Poederblauw" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Lichtstaalblauw" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Staalblauw" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Korenbloemblauw" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Koningsblauw" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Middenblauw" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Middernachtblauw" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Donkerblauw" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Marineblauw" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Leiblauw" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Donkerleiblauw" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Midden-leiblauw" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Blauwviolet" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Donkerviolet" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Donkere orchidee" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Midden-orchidee" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidee" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violet" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Midden-purper" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Purper" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebecca-purper" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Midden-violetrood" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Bleek violetrood" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Dieproze" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Knalroze" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Lichtroze" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Roze" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Pruim" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Distel" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuchsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Donkermagenta" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Linnen" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Oud kant" +# AI Translated +# Needs human review: Color name (CSS seashell), not the print Shell; glossary Shell warning is a false match. msgid "Sea shell" -msgstr "" +msgstr "Schelp" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Ivoor" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Bloemenwit" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavendelroze" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Spookwit" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Alice-blauw" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavendel" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Rookwit" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Zwart" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Koraalvuur" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Zeeanemoon" +# AI Translated +# Needs human review: Ocean-themed color name; check the Dutch rendering. msgid "Deep abyss" -msgstr "" +msgstr "Diepe afgrond" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Kreeftrood" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Zandklei" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Drijfhout" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Duindoorn" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Rif bij zonsondergang" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tijgerkoraal" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Rozekoraal" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Schelpgloed" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Zand" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Gouden kelp" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Zonovergoten duin" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Barnsteen-nautilus" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Zeecitroen" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Bleke zeester" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Springtij" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Limoenalg" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Zeegras" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neonplankton" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Kelpbos" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Smaragdgolf" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Walvisschaduw" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Zeeschildpad" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagune" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Tropische stroming" +# AI Translated +# Needs human review: Ocean-themed color name; check the Dutch rendering. msgid "Midnight trench" -msgstr "" +msgstr "Middernachtgeul" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Donkere kelp" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Kristalbranding" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Turkooisbaai" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Lucht boven het rif" +# AI Translated +# Needs human review: Ocean-themed color name; check the Dutch rendering. msgid "Shallow sky" -msgstr "" +msgstr "Ondiepe hemel" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektrisch blauw" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Dolfijn" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Oceaandiepten" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Walvis" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indigoafgrond" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Zee-egel" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Lavendelkoraal" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Violet getij" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Diepzeeorchidee" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neonkwal" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuchsiakoraal" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Roze kwal" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Schuim" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Schelpwit" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Kiezelgrijs" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Onweerswolk" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Inktzwart" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Groenbeige" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Zandgeel" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Signaalgeel" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Goudgeel" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Honinggeel" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Maisgeel" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Narcisgeel" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Bruinbeige" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Citroengeel" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Parelwit" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Licht ivoor" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Zinkgeel" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Grijsbeige" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Olijfgeel" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Koolzaadgeel" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Verkeersgeel" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Okergeel" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Verkeersoranjegeel" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Meloengeel" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Bremgeel" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Dahliageel" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pastelgeel" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Parelbeige" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Parelgoud" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Zonnegeel" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Geeloranje" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Dieporanje" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Vermiljoen" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Pareloranje" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Zuiver oranje" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Lichtgevend oranje" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Lichtgevend helderoranje" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Helder roodoranje" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Verkeersoranje" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Signaaloranje" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Zalmoranje" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Parelroze" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Koperoranje" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Signaalbruin" +# AI Translated +# Needs human review: Unusual name (fir = spar); check the Dutch colour name. msgid "Fir orange" -msgstr "" +msgstr "Sparrenoranje" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Signaalrood" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Lichtgevend rood" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karmijnrood" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Parelkarmijnrood" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Zuiver rood" +# AI Translated +# Needs human review: Nonstandard RAL name; literal rendering. msgid "Luminous deep red" -msgstr "" +msgstr "Lichtgevend dieprood" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Aalbesrood" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Parelrobijnrood" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Vuurrood" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Robijnrood" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Purperrood" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Wijnrood" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Zwartrood" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oxiderood" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Bruinrood" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Dennenrood" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Tomaatrood" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Oudroze" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Koraalrood" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rosé" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Aardbeirood" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Verkeersrood" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Zalmroze" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Lichtgevend roze" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Lichtgevend helderrood" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Frambozenrood" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Oriëntrood" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Parelrobijn" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Roodpurper" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Roodviolet" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Heideviolet" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordeauxviolet" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Mahonie" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Grijspurper" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Signaalviolet" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Sparrengroen" +# AI Translated msgid "Sabine grey" -msgstr "" +msgstr "Sabijnengrijs" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Parelviolet" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Parelbraam" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Groenblauw" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarijnblauw" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Saffierblauw" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Zwartblauw" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Signaalblauw" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Briljantblauw" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Grijsblauw" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azuurblauw" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Gentiaanblauw" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobaltblauw" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Duifblauw" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Verkeersblauw" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Turkooisblauw" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Capriblauw" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Oceaanblauw" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Waterblauw" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Nachtblauw" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Verblauw" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pastelblauw" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Parelgentiaanblauw" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Parel-middernachtblauw" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patinagroen" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Smaragdgroen" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Loofgroen" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Olijfgroen" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Blauwgroen" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Mosgroen" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Grijsolijf" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Dennengroen" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Dennenbruin" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Grasgroen" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Resedagroen" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Bruingroen" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Rietgroen" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Zwartgroen" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Turkooisgroen" +# AI Translated msgid "May green" -msgstr "" +msgstr "Meigroen" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Chroomoxidegroen" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Verkeersgroen" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Varengroen" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opaalgroen" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Muntgroen" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Bronsgroen" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Parelgroen" +# AI Translated +# Needs human review: Unclear RAL-style name (Sax = Saxe blue?); check the Dutch colour name. msgid "Sax turquoise" -msgstr "" +msgstr "Sax-turkoois" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Parelturkoois" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Pareljade" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Zuiver groen" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Lichtgevend groen" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Eekhoorngrijs" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Zilvergrijs" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Olijfgrijs" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Mosgrijs" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Signaalgrijs" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Muisgrijs" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Beigegrijs" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Kakigrijs" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Groengrijs" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Dekzeilgrijs" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "IJzergrijs" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Basaltgrijs" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Bruingrijs" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Leigrijs" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antracietgrijs" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Lichtgrijs" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Ombergrijs" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Betongrijs" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafietgrijs" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Granietgrijs" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Steengrijs" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Kiezelgrijs" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Cementgrijs" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Geelgrijs" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platinagrijs" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Stofgrijs" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Agaatgrijs" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Kwartsgrijs" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Raamgrijs" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Verkeersgrijs A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Verkeersgrijs B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Zijdegrijs" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegrijs 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegrijs 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegrijs 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Parelmuisgrijs" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Groenbruin" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Okerbruin" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Kleibruin" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Koperbruin" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Chocoladebruin" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Olijfbruin" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Notenbruin" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Roodbruin" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sepiabruin" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Kastanjebruin" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Mahoniebruin" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Grijsbruin" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Parelkoper" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Beigebruin" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Parelmokkabruin" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Aardbruin" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Parelbruin" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Crème" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Grijswit" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Signaalwit" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Signaalzwart" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Gitzwart" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Wit aluminium" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Grijs aluminium" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Zuiver wit" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Grafietzwart" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Verkeerswit" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Verkeerszwart" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papyruswit" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Parellichtgrijs" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metaal: Zilver" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metaal: Messing" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metaal: Goud" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metaal: Koper" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metaal: Brons" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Natuur: Parel" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Natuur: Regenboog" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natuur: Heldere hemel" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Natuur: Zonsondergang" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Hout: Donker" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Hout: Gemiddeld" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Hout: Licht" # AI Translated msgid "Alternate nozzles:" @@ -34538,13 +34982,25 @@ msgstr "Verwijderen uit Mijn texturen" msgid "Built-in" msgstr "Ingebouwd" +# AI Translated +msgid "My textures" +msgstr "Mijn texturen" + # AI Translated msgid "No textures found." msgstr "Geen texturen gevonden." # AI Translated -msgid "My textures" -msgstr "Mijn texturen" +msgid "Texture libraries" +msgstr "Textuurbibliotheken" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Ontdek meer textuurbibliotheken" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Opent OrcaCloud op de startpagina om naar plug-ins te zoeken." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -34947,11 +35403,13 @@ msgstr "Gekoppeld via de eigen UV-indeling van het model, die al de plaatsing be msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Hoe breed één kopie van de textuur op het model is. Kleiner herhaalt het patroon vaker en maakt het detail fijner; met Tegelen uit is dit de grootte van de enkele kopie." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Groter" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Kleiner" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -35027,11 +35485,14 @@ msgstr "Gemengde kleuren" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Het maximale aantal gemengde filamenten dat bij het bakken mag worden toegevoegd. Ze worden gekozen uit de kleuren van de textuur, en alleen de filamenten die bij het bakken daadwerkelijk worden gebruikt, worden aangemaakt." +# AI Translated +# Needs human review: Caption under an illustration in the texture displacement mixed-colors option; check it reads right as a pair with Many. msgid "Few" -msgstr "" +msgstr "Weinig" +# AI Translated msgid "Many" -msgstr "" +msgstr "Veel" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -35387,11 +35848,13 @@ msgstr "Remeshen" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Driehoeksgrootte waarmee het hele model opnieuw wordt opgebouwd, in millimeters. Verplaatsing werkt het best op een gelijkmatige mesh; hiermee maakt u er een van een ongelijkmatige import." +# AI Translated msgid "Before" -msgstr "" +msgstr "Voor" +# AI Translated msgid "After" -msgstr "" +msgstr "Na" # AI Translated msgid "Keep sharp edges" @@ -37270,6 +37733,10 @@ msgstr "Script" msgid "Slicing Pipeline" msgstr "Slicepijplijn" +# AI Translated +msgid "Resource Texture" +msgstr "Resourcetextuur" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "De configuratie-UI van de plug-in was leeg. De standaardeditor wordt getoond." @@ -37417,6 +37884,30 @@ msgstr "Plug-inmap bevat zowel .py- als .whl-startbestanden" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Plug-inmap bevat geen .py- of .whl-startbestand" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "De map voor de resourcetextuur is niet ingesteld" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "De map voor de resourcetextuur kon niet worden bepaald" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Het pad van de resourcetextuur is geen map" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "De plug-inmap kon niet worden bepaald" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "De map voor de resourcetextuur ligt buiten de plug-inmap" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "De map voor de resourcetextuur kon niet worden gelezen" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -37875,7 +38366,7 @@ msgstr "Laden van configuratiebestand \"%1%\" mislukt: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Geen G-code-bestand dat door %1% is gegenereerd." # AI Translated @@ -37995,7 +38486,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Kan geen tijdelijke kopie van G-code-bestand %1% maken voordat een nabewerkingsscript wordt uitgevoerd: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Nabewerking kan het geëxporteerde G-code-bestand niet vinden" # AI Translated @@ -38364,6 +38855,29 @@ msgstr "" "Kromtrekken voorkomen\n" "Wist je dat bij het printen van materialen die gevoelig zijn voor kromtrekken, zoals ABS, een juiste verhoging van de temperatuur van het warmtebed de kans op kromtrekken kan verkleinen?" +# AI Translated +# Needs human review: Likely RAL 1007 daffodil yellow (Narcisgeel); source name is nonstandard. +#~ msgid "Dalmatian yellow" +#~ msgstr "Narcisgeel" + +# AI Translated +# Needs human review: Source likely a typo for RAL 5019 Capri blue (sits between Turquoise blue and Ocean blue); translated as Capriblauw. +#~ msgid "Capsanthin violet" +#~ msgstr "Capriblauw" + +# AI Translated +# Needs human review: Source likely a typo for RAL 7002 Olive grey; translated as Olijfgrijs. +#~ msgid "Olivestone" +#~ msgstr "Olijfgrijs" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Overal in het venster beschikbaar, zelfs tijdens het typen in een tekstveld." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Globale sneltoetsen werken ook tijdens het typen." + # AI Translated #~ msgid "Please choose the filament color" #~ msgstr "Kies de filamentkleur" @@ -38878,9 +39392,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "geen geconfigureerd gereedschap" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Voeg een eind G-code toe bij het afwerken van de hele print." - #~ msgid "Maximum X speed" #~ msgstr "Maximale X snelheid" @@ -38897,27 +39408,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Python-plug-in(s) die bij elke stap van de slicepijplijn worden aangeroepen om tussentijdse slicegegevens te lezen en te wijzigen, inclusief een afsluitende nabewerkingsstap voor de G-code. Onderzoek/experimenteel." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Indien ingeschakeld genereert de slicer G-code waarin de inhoud van de primaire zone gecentreerd is op de oorsprong van het printbed (0,0). De printerfirmware is verantwoordelijk voor het plaatsen van kopieën/spiegelingen op elke fysieke zonepositie. Schakel dit alleen in op printers waarvan de firmware zelf zoneverschuivingen toepast in de kopie-/spiegelmodus (bijv. de IDEX-duplicatiemodus van RepRapFirmware). Heeft geen effect in de modus Primair." - # AI Translated # Needs human review: 'pem-inversion' is unexplained jargon in the source (probably the inverse of the physical extruder map); check the wording once the English is clarified. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Overschrijving per printbed die fysieke koppen aan filamentslots koppelt (vanaf 1 geteld). Leeg betekent dat de standaardwaarden uit de pem-inversie worden gebruikt." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "As waarom de mesh vóór het slicen wordt gedraaid. Dit is de kanteling van de bandprinter: een isometrische rotatie (zonder vervorming) die ook de weergave van het printbed en de zwaartekrachtkanteling van de ondersteuning bepaalt, en die de G-code-terugtransformatie omkeert vóór de afschuiving/schaling naar het machinecoördinatenstelsel en de herindeling van de assen. X is de gebruikelijke kanteling van het portaal (de band beweegt langs Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Overschrijving voor experts: stel de kantelhoek van het machinecoördinatenstelsel (G-code-afschuiving/-schaling) in los van de rotatiehoek vóór het slicen. Indien uitgeschakeld wordt de transformatie naar het machinecoördinatenstelsel afgeleid van de kantelhoek van de band, zodat één hoek beide stappen bepaalt. Schakel dit alleen in om te compenseren voor een machine waarvan de fysieke portaalkanteling afwijkt van de slicerotatie." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "De maximale afwijking die is toegestaan bij het verlagen van de resolutie voor de instelling 'Maximale wandresolutie'. Als u deze verhoogt, wordt de print minder nauwkeurig, maar de G-code kleiner. 'Maximale wandafwijking' beperkt 'Maximale wandresolutie'; als de twee met elkaar in conflict zijn, gaat 'Maximale wandafwijking' voor." - # AI Translated #~ msgid " not in range " #~ msgstr " niet in bereik " diff --git a/localization/i18n/pl/OrcaSlicer_pl.po b/localization/i18n/pl/OrcaSlicer_pl.po index a8292fdfd8..4da84941df 100644 --- a/localization/i18n/pl/OrcaSlicer_pl.po +++ b/localization/i18n/pl/OrcaSlicer_pl.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: OrcaSlicer 2.3.0-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: \n" "Last-Translator: Krzysztof Morga <>\n" "Language-Team: \n" @@ -790,18 +790,21 @@ msgstr "Wybór" msgid "Plate" msgstr "Płyta" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "Rozłóż" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Układ współrzędnych używany przy operacjach transformacji." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Odniesienie wyrównania" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Wybierz co najmniej 3 części lub obiekty" # AI Translated msgid "Align left" @@ -854,8 +857,9 @@ msgstr "Rozłóż góra-dół" msgid "Drop" msgstr "Upuść" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Przesuwa zaznaczenie wzdłuż osi Z tak, aby jego najniższy punkt dotykał stołu." # AI Translated msgid "Absolute" @@ -1763,7 +1767,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Obrys kształtu (%1%) zawiera nieobsługiwane: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Nieprawidłowy stan, zgłoś na GitHubie kroki pozwalające odtworzyć problem" # AI Translated @@ -1771,11 +1775,11 @@ msgid "No embossed file" msgstr "Brak pliku wytłoczenia" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Brak pliku SVG w wytłoczonym kształcie" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Brak danych pliku SVG" msgid "Face the camera" @@ -2099,17 +2103,21 @@ msgstr "Wejście do gizmo składania" msgid "Leaving Assembly gizmo" msgstr "Wyjście z gizmo składania" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Części przeciętego obiektu nie mogą być przesuwane" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Wyrównanie do stołu jest dostępne tylko w osiach X i Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Wyłącz automatyczne opuszczanie dla wybranych obiektów, aby przesuwać je w osi Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Wszystkie wybrane obiekty muszą znajdować się na tej samej płycie" msgid "Shift+" msgstr "Shift+" @@ -5069,7 +5077,7 @@ msgstr "Zapisz projekt i uruchom program ponownie." msgid "Unknown C++ exception." msgstr "Nieznany wyjątek C++." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Przetwarzanie G-code z poprzedniego pliku..." msgid "Slicing complete" @@ -6644,8 +6652,9 @@ msgstr "Osie" msgid "Gridlines" msgstr "Linie siatki" +# AI Translated msgid "Focus mode" -msgstr "" +msgstr "Tryb skupienia" # AI Translated msgid "Labels" @@ -6707,7 +6716,7 @@ msgstr "Objętość:" msgid "Size:" msgstr "Rozmiar:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Wykryto konflikty ścieżek G-code na warstwie %d, Z = %.2lfmm. Proszę oddalić od siebie obiekty będące w konflikcie (%s <-> %s)." @@ -11186,11 +11195,14 @@ msgstr "Pokaż nieobsługiwane profile" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Pokazuj niekompatybilne/nieobsługiwane profile na listach rozwijanych drukarek i filamentów. Tych profili nie można wybrać." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Eksportuj statystyki razem z G-code" +# AI Translated +# Needs human review: 'feature totals' = totals per extrusion feature type; check the wording. msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Jeśli włączone, eksport pliku G-code zapisuje obok niego także jego statystyki w formacie JSON, jako .statistics.json, a wyeksportowany plik 3MF z wynikiem cięcia zawiera je w środku: czas druku, sumy dla filamentu i rodzajów linii oraz te same dane dla każdej warstwy i każdego obiektu." # AI Translated msgid "Experimental Features" @@ -12063,6 +12075,10 @@ msgstr "Nie udało się przesłać pliku do pamięci drukarki. Spróbuj ponownie msgid "Send Failed" msgstr "Wysyłanie nieudane" +# AI Translated +msgid "No available printers" +msgstr "Brak dostępnych drukarek" + msgid "The name length exceeds the limit." msgstr "Długość nazwy przekracza limit." @@ -13948,8 +13964,8 @@ msgid "Left mouse" msgstr "Lewy przycisk myszy" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Dostępne w dowolnym miejscu okna, nawet podczas wpisywania tekstu w polu tekstowym." +msgid "Available anywhere in the window." +msgstr "Dostępne w dowolnym miejscu okna." # AI Translated msgid "Run favorite 1 to 10" @@ -14061,10 +14077,6 @@ msgstr "Skrót %s jest przypisany do %s. Przypisać go do %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Domyślny skrót %s jest przypisany do %s. Przypisać go do %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Skróty globalne działają także podczas pisania." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Klawisz wpisujący znak nie może być skrótem globalnym." @@ -14521,9 +14533,10 @@ msgstr "modyfikator „%1%” obiektu „%2%” (łącznie %3%) nie wpłynął n msgid "Seam placement may differ from expected." msgstr "Położenie szwu może różnić się od oczekiwanego." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Nie udało się zapisać statystyk G-code do %1%." msgid "Internal Bridge" msgstr "Wewnętrzny most" @@ -17998,6 +18011,14 @@ msgstr "Wyłącz obiekty" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Włącz tę opcję, aby dodać polecenie EXCLUDE OBJECT do G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Tolerancja konturu" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Maksymalne odchylenie konturu obiektu zapisanego w EXCLUDE_OBJECT_DEFINE od konturu oryginalnego. Większe wartości dają mniej punktów, co pomaga w przypadku firmware, który zawiesza się podczas analizy G-code z wieloma obiektami. 0 zachowuje każdy punkt." + msgid "Verbose G-code" msgstr "Rozszerzony G-code" @@ -21304,11 +21325,14 @@ msgstr "Katalog wyjściowy" msgid "This is the output directory for exported files." msgstr "Katalog wyjściowy dla eksportowanych plików." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Eksportuj statystyki" +# AI Translated +# Needs human review: 'feature totals' = totals per extrusion feature type; check the wording. msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Zapisuje statystyki każdej pociętej płyty w formacie JSON, jako plate_N.statistics.json obok jej G-code w katalogu wyjściowym oraz w pliku 3MF z --export-3mf: czas druku, sumy dla filamentu i rodzajów linii oraz te same dane dla każdej warstwy i każdego obiektu." msgid "Debug level" msgstr "Poziom debugowania" @@ -23783,7 +23807,7 @@ msgstr "test %s: start..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "test %s: rozwiązany adres IP = %s" # AI Translated @@ -31330,1231 +31354,1648 @@ msgstr[0] "Bieżąca lista filamentów nie zawiera: %s. Filament projektu wymaga msgstr[1] "Bieżąca lista filamentów nie zawiera: %s. Filamenty projektu wymagane przez filament mieszany zostaną utworzone automatycznie po rozkładzie." msgstr[2] "Bieżąca lista filamentów nie zawiera: %s. Filamenty projektu wymagane przez filament mieszany zostaną utworzone automatycznie po rozkładzie." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Selektor kolorów" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Kolory podstawowe" +# AI Translated #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Paleta Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Classic" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Gradienty" +# AI Translated +# Needs human review: Color picker tab: single solid color as opposed to a gradient; check it reads right next to 'Gradients'. +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Jednolity" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Gradient" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Początek gradientu" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Koniec gradientu" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Kolor gradientu" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Dodaj kolor" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Usuń kolor" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Nasycenie" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Oryginalny kolor" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Zapisz bieżący kolor" +# AI Translated msgid "Palettes" -msgstr "" +msgstr "Palety" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Szukaj kolorów" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtruj kolory" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Brak pasujących kolorów" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Kolor HEX" # AI Translated msgid "Opacity" msgstr "Krycie" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Krycie w procentach" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Zapisz kolor" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Wprowadź pełny kolor szesnastkowy" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Bieżący wybór wielu kolorów zostaje zachowany, dopóki nie wybierzesz innego koloru." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Obsługiwanych jest maksymalnie %d kolorów." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmazynowy" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Pomarańczowoczerwony" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Pomidorowy" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Pomarańczowy" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Ciemnopomarańczowy" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Złoty" +# AI Translated +# Needs human review: CSS color name; 'Drewniany' is a free rendering. msgid "Burly wood" -msgstr "" +msgstr "Drewniany" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Kremoworóżowy" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Mglistoróżowy" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Jasnożółty" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Cytrynowy szyfon" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beżowy" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Jasny nawłociowożółty" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Blady nawłociowy" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Khaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Ciemne khaki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Brzoskwiniowy krem" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mokasynowy" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Krem papai" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Blady migdałowy" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antyczna biel" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Biel Navajo" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Pszeniczny" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Nawłociowy" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Czekoladowy" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Ceglasty" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Sjena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Siodłowy brąz" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Brązowy" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Różowobrązowy" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Łososiowy" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Jasnołososiowy" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Ciemnołososiowy" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Piaskowobrązowy" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Koralowy" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Jasnokoralowy" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Indyjskoczerwony" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Ciemnoczerwony" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Kasztanowy" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Zielonożółty" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Żółtozielony" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Trawnikowozielony" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Limonkowozielony" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Wiosennozielony" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Średni wiosennozielony" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Limonkowy" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Leśnozielony" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Ciemnozielony" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Wojskowooliwkowy" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliwkowy" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Ciemny oliwkowozielony" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Bladozielony" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Jasnozielony" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Średni morskozielony" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Morskozielony" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Ciemny morskozielony" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Kadetowoniebieski" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Średni akwamarynowy" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turkusowy" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Średni turkusowy" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Ciemnoturkusowy" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Bladoturkusowy" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Jasny cyjan" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Miętowy krem" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Rosa miodowa" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Akwamarynowy" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Jasny morskozielony" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Ciemny cyjan" +# AI Translated +# Needs human review: CSS color kept in English; no distinct Polish name found; check. msgid "Teal" -msgstr "" +msgstr "Teal" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Ciemny łupkowoszary" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Jasny łupkowoszary" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Łupkowoszary" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Intensywny błękit nieba" +# AI Translated +# Needs human review: CSS color name; proper name kept. msgid "Dodger Blue" -msgstr "" +msgstr "Niebieski Dodger" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Błękit nieba" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Jasny błękit nieba" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Jasnoniebieski" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Pudrowoniebieski" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Jasny stalowoniebieski" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Stalowoniebieski" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Chabrowy" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Królewski niebieski" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Średni niebieski" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Północnoniebieski" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Ciemnoniebieski" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Granatowy" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Łupkowoniebieski" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Ciemny łupkowoniebieski" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Średni łupkowoniebieski" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Niebieskofioletowy" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indygo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Ciemnofioletowy" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Ciemna orchidea" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Średnia orchidea" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orchidea" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Fioletowy" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Średni purpurowy" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Purpurowy" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Purpurowy Rebecca" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Średni fioletowoczerwony" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Blady fioletowoczerwony" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Intensywny różowy" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Jaskraworóżowy" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Jasnoróżowy" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Różowy" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Śliwkowy" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Ostowy" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuksjowy" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Ciemna magenta" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Lniany" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Stara koronka" +# AI Translated +# Needs human review: CSS color Seashell; the glossary Shell term does not apply (false match). msgid "Sea shell" -msgstr "" +msgstr "Muszlowy" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Kość słoniowa" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Kwiatowa biel" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lawendowy róż" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Widmowa biel" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Błękit Alicji" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lawendowy" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Dymna biel" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Czarny" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Koralowy ogień" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Ukwiał" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Głęboka otchłań" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Homarowa czerwień" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Piaszczysta glina" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Wyrzucone drewno" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Rokitnik" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Rafa o zachodzie słońca" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tygrysi koral" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Różowy koral" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Blask muszli" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Piasek" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Złote wodorosty" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Wydma w słońcu" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Bursztynowy łodzik" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Morska cytryna" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Blada rozgwiazda" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Wiosenny przypływ" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Limonkowe algi" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Trawa morska" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neonowy plankton" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Las wodorostów" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Szmaragdowa fala" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Cień wieloryba" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Żółw morski" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Laguna" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Tropikalny prąd" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Północny rów" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Ciemne wodorosty" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Kryształowy przybój" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Turkusowa zatoka" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Niebo nad rafą" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Płytkie niebo" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektryczny błękit" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfin" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Głębiny oceanu" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Wieloryb" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indygowa otchłań" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Jeżowiec" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Lawendowy koral" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Fioletowy przypływ" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Głębinowa orchidea" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neonowa meduza" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuksjowy koral" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Różowa meduza" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Piana" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Muszlowa biel" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Otoczakowoszary" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Burzowa chmura" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Atramentowa czerń" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Zielonobeżowy" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Piaskowożółty" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Sygnałowy żółty" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Złotożółty" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Miodowożółty" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Kukurydzianożółty" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Narcyzowożółty" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Brązowobeżowy" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Cytrynowożółty" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Ostrygowa biel" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Jasna kość słoniowa" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Cynkowożółty" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Szarobeżowy" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Oliwkowożółty" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Rzepakowożółty" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Drogowy żółty" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Ochrowożółty" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Drogowy pomarańczowożółty" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Melonowożółty" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Żarnowcowożółty" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Daliowożółty" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pastelowożółty" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Perłowy beżowy" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Perłowy złoty" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Słonecznożółty" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Żółtopomarańczowy" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Intensywny pomarańczowy" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Cynober" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Perłowy pomarańczowy" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Czysty pomarańczowy" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Jaskrawy pomarańczowy" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Jaskrawy jasnopomarańczowy" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Jasny czerwonopomarańczowy" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Drogowy pomarańczowy" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Sygnałowy pomarańczowy" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Łososiowopomarańczowy" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Perłowy różowy" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Miedzianopomarańczowy" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Sygnałowy brązowy" +# AI Translated +# Needs human review: RAL color name, probably a typo of the source; rendering follows the English literally. msgid "Fir orange" -msgstr "" +msgstr "Jodłowopomarańczowy" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Sygnałowy czerwony" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Jaskrawy czerwony" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karminowoczerwony" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Perłowy karminowoczerwony" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Czysty czerwony" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Jaskrawy intensywnoczerwony" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Porzeczkowoczerwony" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Perłowy rubinowoczerwony" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Ognistoczerwony" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rubinowoczerwony" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Purpurowoczerwony" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Winnoczerwony" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Czarnoczerwony" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Tlenkowoczerwony" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Brązowoczerwony" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Sosnowoczerwony" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Pomidorowoczerwony" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Staroróżowy" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Koralowoczerwony" +# AI Translated +# Needs human review: RAL color name; rendered as 'różany' to stay distinct from 'Pink'. msgid "Rose" -msgstr "" +msgstr "Różany" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Truskawkowoczerwony" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Drogowy czerwony" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Łososioworóżowy" +# AI Translated +# Needs human review: RAL color name; 'Rose' rendered as 'różany'. msgid "Luminous rose" -msgstr "" +msgstr "Jaskrawy różany" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Jaskrawy jasnoczerwony" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Malinowoczerwony" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Orientalny czerwony" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Perłowy rubinowy" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Czerwonopurpurowy" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Czerwonofioletowy" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Wrzosowofioletowy" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordowofioletowy" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Mahoniowy" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Szaropurpurowy" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Sygnałowy fioletowy" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Jodłowozielony" +# AI Translated +# Needs human review: RAL color name; check. msgid "Sabine grey" -msgstr "" +msgstr "Sabiński szary" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Perłowy fioletowy" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Perłowy jeżynowy" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Zielononiebieski" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarynowy" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Szafirowy" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Czarnoniebieski" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Sygnałowy niebieski" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Brylantowoniebieski" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Szaroniebieski" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Lazurowy" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Goryczkowoniebieski" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobaltowy" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Gołębioniebieski" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Drogowy niebieski" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Turkusowoniebieski" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Niebieski Capri" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Oceanicznoniebieski" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Wodnoniebieski" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Nocnoniebieski" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Odległy niebieski" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pastelowoniebieski" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Perłowy goryczkowoniebieski" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Perłowy północnoniebieski" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patynowozielony" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Szmaragdowozielony" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Liściastozielony" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Oliwkowozielony" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Niebieskozielony" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Mchowozielony" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Szarooliwkowy" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Sosnowozielony" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Sosnowobrązowy" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Trawiastozielony" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Rezedowozielony" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Brązowozielony" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Trzcinowozielony" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Czarnozielony" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Turkusowozielony" +# AI Translated msgid "May green" -msgstr "" +msgstr "Majowozielony" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Zielony tlenek chromu" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Drogowy zielony" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Paprociowozielony" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opalowozielony" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Miętowozielony" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Spiżowozielony" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Perłowy zielony" +# AI Translated +# Needs human review: RAL color name; 'Sax' may be Saxon or sax blue; check. msgid "Sax turquoise" -msgstr "" +msgstr "Turkusowy Sax" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Perłowy turkusowy" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Perłowy nefrytowy" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Czysty zielony" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Jaskrawy zielony" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Wiewiórkowoszary" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Srebrnoszary" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Oliwkowoszary" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Mchowoszary" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Sygnałowy szary" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Mysioszary" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Beżowoszary" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Szary khaki" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Zielonoszary" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Brezentowoszary" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Żelazoszary" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Bazaltowoszary" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Brązowoszary" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Łupkowoszary" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antracytowoszary" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Jasnoszary" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umbrowoszary" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Betonowoszary" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafitowoszary" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Granitowoszary" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Kamiennoszary" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Otoczakowoszary" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Cementowoszary" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Żółtoszary" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platynowoszary" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Pyłowoszary" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Agatowoszary" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Kwarcowoszary" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Okiennoszary" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Drogowy szary A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Drogowy szary B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Jedwabnoszary" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telszary 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telszary 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telszary 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Perłowy mysioszary" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Zielonobrązowy" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Ochrowobrązowy" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Glinianobrązowy" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Miedzianobrązowy" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Czekoladowobrązowy" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Oliwkowobrązowy" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Orzechowobrązowy" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Czerwonobrązowy" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sepiowobrązowy" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Kasztanowobrązowy" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Mahoniowobrązowy" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Szarobrązowy" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Perłowy miedziany" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Beżowobrązowy" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Perłowy mokkowobrązowy" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Ziemistobrązowy" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Perłowy brązowy" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Kremowy" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Szarobiały" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Biel sygnałowa" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Czerń sygnałowa" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Głęboka czerń" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Białe aluminium" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Szare aluminium" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Czysta biel" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Czerń grafitowa" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Biel drogowa" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Czerń drogowa" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Biel papirusowa" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Perłowy jasnoszary" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metal: Srebro" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metal: Mosiądz" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metal: Złoto" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metal: Miedź" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metal: Brąz" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Natura: Perła" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Natura: Tęcza" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natura: Czyste niebo" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Natura: Zachód słońca" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Drewno: Ciemne" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Drewno: Średnie" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Drewno: Jasne" msgid "Alternate nozzles:" msgstr "Inne rozmiary dysz:" @@ -32965,13 +33406,25 @@ msgstr "Usuń z Moich tekstur" msgid "Built-in" msgstr "Wbudowane" +# AI Translated +msgid "My textures" +msgstr "Moje tekstury" + # AI Translated msgid "No textures found." msgstr "Nie znaleziono tekstur." # AI Translated -msgid "My textures" -msgstr "Moje tekstury" +msgid "Texture libraries" +msgstr "Biblioteki tekstur" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Przeglądaj więcej bibliotek tekstur" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Otwiera OrcaCloud na stronie głównej, aby przeglądać wtyczki." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33374,11 +33827,15 @@ msgstr "Mapowanie według własnego układu UV modelu, który już stanowi rozmi msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Szerokość jednej kopii tekstury na modelu. Mniejsza wartość częściej powtarza wzór, a jego szczegóły stają się drobniejsze; przy wyłączonym Kafelkowaniu jest to rozmiar pojedynczej kopii." +# AI Translated +# Needs human review: Label on the tile-size tip image; check gender agreement with 'tile' (kafelek). msgid "Larger" -msgstr "" +msgstr "Większy" +# AI Translated +# Needs human review: Label on the tile-size tip image; check gender agreement with 'tile' (kafelek). msgid "Smaller" -msgstr "" +msgstr "Mniejszy" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33454,11 +33911,15 @@ msgstr "Kolory mieszane" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Maksymalna liczba filamentów mieszanych, które może dodać wypiekanie. Są wybierane z kolorów tekstury, a tworzone są tylko te, których wypiekanie faktycznie używa." +# AI Translated +# Needs human review: Label on the mixed-colors tip image (few vs many colors); check it reads right. msgid "Few" -msgstr "" +msgstr "Mało" +# AI Translated +# Needs human review: Label on the mixed-colors tip image (few vs many colors); check it reads right. msgid "Many" -msgstr "" +msgstr "Dużo" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33819,11 +34280,13 @@ msgstr "Przebudowa siatki" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Rozmiar trójkątów, z jakim przebudowywany jest cały model, w milimetrach. Przemieszczenie działa najlepiej na równomiernej siatce; to ustawienie tworzy ją z nierównomiernego importu." +# AI Translated msgid "Before" -msgstr "" +msgstr "Przed" +# AI Translated msgid "After" -msgstr "" +msgstr "Po" # AI Translated msgid "Keep sharp edges" @@ -35694,6 +36157,10 @@ msgstr "Skrypt" msgid "Slicing Pipeline" msgstr "Potok cięcia" +# AI Translated +msgid "Resource Texture" +msgstr "Tekstura zasobu" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Interfejs konfiguracji wtyczki był pusty. Wyświetlany jest domyślny edytor." @@ -35841,6 +36308,30 @@ msgstr "Katalog wtyczki zawiera zarówno plik wejściowy .py, jak i .whl" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Katalog wtyczki nie zawiera pliku wejściowego .py ani .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Katalog tekstury zasobu nie jest ustawiony" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Nie udało się ustalić katalogu tekstury zasobu" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Ścieżka tekstury zasobu nie jest katalogiem" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Nie udało się ustalić folderu wtyczki" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Katalog tekstury zasobu znajduje się poza folderem wtyczki" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Nie udało się odczytać katalogu tekstury zasobu" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36301,7 +36792,7 @@ msgstr "Nie udało się wczytać pliku konfiguracyjnego „%1%”: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "To nie jest plik G-code wygenerowany przez %1%." # AI Translated @@ -36421,7 +36912,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Nie udało się utworzyć tymczasowej kopii pliku G-code %1% przed uruchomieniem skryptu post-processingu: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Post-procesor nie może znaleźć wyeksportowanego pliku G-code" # AI Translated @@ -36789,6 +37280,27 @@ msgstr "" "Unikaj odkształceń\n" "Czy wiesz, że podczas drukowania filamentami podatnymi na odkształcenia, takimi jak ABS, odpowiednie zwiększenie temperatury podgrzewanej płyty może zmniejszyć prawdopodobieństwo odkształceń?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Dalmatyński żółty" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Kapsantynowofioletowy" + +# AI Translated +# Needs human review: RAL color name written as one word in the source; check. +#~ msgid "Olivestone" +#~ msgstr "Oliwkowy kamień" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Dostępne w dowolnym miejscu okna, nawet podczas wpisywania tekstu w polu tekstowym." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Skróty globalne działają także podczas pisania." + #~ msgid "Please choose the filament color" #~ msgstr "Proszę wybrać kolor filamentu" @@ -37270,9 +37782,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "brak skonfigurowanego narzędzia" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Końcowy G-code po zakończeniu całego druku" - #~ msgid "Maximum X speed" #~ msgstr "Maksymalna prędkość X" @@ -37289,27 +37798,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Wtyczki Pythona wywoływane na każdym etapie potoku cięcia w celu odczytu i modyfikacji pośrednich danych cięcia, w tym końcowego etapu postprocessingu G-code. Badawcze/eksperymentalne." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Gdy ta opcja jest włączona, slicer generuje G-code z zawartością strefy głównej wyśrodkowaną względem początku układu stołu (0,0). Oprogramowanie sprzętowe drukarki odpowiada za umieszczenie kopii i odbić lustrzanych w położeniu każdej fizycznej strefy. Włączaj tylko w drukarkach, których oprogramowanie sprzętowe samo stosuje przesunięcia stref w trybie Kopia/Lustro (np. tryb duplikacji IDEX w RepRapFirmware). Nie ma wpływu w trybie głównym (Primary)." - # AI Translated # Needs human review: 'pem-inversion' (inverse of the physical extruder map) is developer jargon kept as 'odwrócenia pem'; check it is understandable. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Nadpisanie dla płyty przypisujące fizyczne głowice do gniazd filamentu (liczonych od 1). Puste oznacza użycie wartości domyślnych z odwrócenia pem." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Oś, wokół której siatka jest obracana przed cięciem. To pochylenie drukarki taśmowej: obrót izometryczny (bez zniekształceń), który steruje również renderowaniem stołu i pochyleniem grawitacji dla podpór i który odwrotna transformacja G-code cofa przed ścinaniem/skalowaniem w układzie współrzędnych maszyny i przemapowaniem osi. X to typowe pochylenie portalu (taśma przesuwa się wzdłuż Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Nadpisanie dla ekspertów: ustawia kąt pochylenia układu współrzędnych maszyny (ścinanie/skalowanie G-code) niezależnie od kąta obrotu przed cięciem. Gdy opcja jest wyłączona, transformacja układu współrzędnych maszyny jest wyznaczana z kąta pochylenia taśmy, więc jeden kąt steruje oboma etapami. Włączaj tylko w celu kompensacji maszyny, której fizyczne pochylenie portalu różni się od obrotu przy cięciu." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Maksymalna dopuszczalna odchyłka przy zmniejszaniu rozdzielczości dla ustawienia „Maksymalna rozdzielczość ściany”. Jej zwiększenie sprawi, że wydruk będzie mniej dokładny, ale G-code będzie mniejszy. „Maksymalna odchyłka ściany” ogranicza „Maksymalną rozdzielczość ściany”, więc w razie konfliktu pierwszeństwo ma „Maksymalna odchyłka ściany”." - #~ msgid " not in range " #~ msgstr " nie w zakresie " diff --git a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po index 06fd49ab2f..1fb4d894ec 100644 --- a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po +++ b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" -"PO-Revision-Date: 2026-10-11 16:22-0300\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" +"PO-Revision-Date: 2026-10-17 10:38-0300\n" "Last-Translator: Alexandre Folle de Menezes\n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -17,7 +17,7 @@ msgstr "" "X-Crowdin-Language: pt-BR\n" "X-Crowdin-Project: orcaslicer-pt-br\n" "X-Crowdin-Project-ID: 664934\n" -"X-Generator: Poedit 3.9\n" +"X-Generator: Poedit 3.10\n" msgid "Main Extruder" msgstr "Extrusora Principal" @@ -725,17 +725,21 @@ msgstr "Seleção" msgid "Plate" msgstr "Placa" +# AI Translated +# Needs human review: Glossary has no pt_BR rendering for Distribute; check it matches the Align/Distribute menu msgid "Distribute" -msgstr "" +msgstr "Distribuir" msgid "Coordinate system used for transform actions." msgstr "Sistema de coordenadas usado para ações de transformação." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Referência para o alinhamento" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Selecione pelo menos 3 peças ou objetos" # AI Translated msgid "Align left" @@ -788,8 +792,9 @@ msgstr "Distribuir cima-baixo" msgid "Drop" msgstr "Descartar" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Move a seleção ao longo de Z para que seu ponto mais baixo toque a mesa." msgid "Absolute" msgstr "Absoluto" @@ -1635,16 +1640,16 @@ msgstr "Opacidade (%1%)" #, boost-format msgid "Color gradient (%1%)" -msgstr "Gradiente de cor (%1%)" +msgstr "Degradê de cor (%1%)" msgid "Undefined fill type" msgstr "Tipo de preenchimento indefinido" msgid "Linear gradient" -msgstr "Gradiente linear" +msgstr "Degradê linear" msgid "Radial gradient" -msgstr "Gradiente radial" +msgstr "Degradê radial" msgid "Open filled path" msgstr "Caminho preenchido aberto" @@ -1675,16 +1680,16 @@ msgstr "O traço da forma (%1%) é muito fino (largura mínima é %2% mm)." msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "O traço da forma (%1%) contém não suportado: %2%." -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Estado inválido, informe os passos para reproduzir no GitHub" msgid "No embossed file" msgstr "Nenhum arquivo em relevo" -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Arquivo SVG ausente na forma em relevo" -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Dados do arquivo SVG ausentes" msgid "Face the camera" @@ -2001,17 +2006,21 @@ msgstr "Entrando no gizmo de Montagem" msgid "Leaving Assembly gizmo" msgstr "Saindo do gizmo de Montagem" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "As peças de um objeto cortado não podem ser movidas" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "O alinhamento à placa está disponível apenas em X e Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Desative a Soltura Automática dos objetos selecionados para movê-los em Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Todos os objetos selecionados devem estar na mesma placa" msgid "Shift+" msgstr "Shift+" @@ -4799,7 +4808,7 @@ msgstr "Por favor, salve seu projeto e reinicie a aplicação." msgid "Unknown C++ exception." msgstr "Exceção C++ desconhecida." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Processando o G-code do arquivo anterior…" msgid "Slicing complete" @@ -6304,8 +6313,10 @@ msgstr "Eixos" msgid "Gridlines" msgstr "Linhas da Grade" +# AI Translated +# Needs human review: Glossary has no pt_BR rendering for Focus mode; context-menu item of the 3D canvas (plate switcher) msgid "Focus mode" -msgstr "" +msgstr "Modo de foco" msgid "Labels" msgstr "Etiquetas" @@ -6366,7 +6377,7 @@ msgstr "Volume:" msgid "Size:" msgstr "Tamanho:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Foram encontrados conflitos de caminhos de G-code na camada %d, Z = %.2lfmm. Por favor, separe mais os objetos em conflito (%s <-> %s)." @@ -10554,11 +10565,13 @@ msgstr "Mostrar predefinições não suportadas" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Exibir predefinições incompatíveis e não suportadas nas listas de impressora e filamento. Essas predefinições não podem ser selecionadas." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Exportar estatísticas com o G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Se ativado, exportar um arquivo G-code também grava suas estatísticas em JSON ao lado dele, como .statistics.json, e um arquivo 3MF fatiado exportado as contém internamente: tempo de impressão, totais de filamento e por tipo de linha, e os mesmos dados por camada e por objeto." msgid "Experimental Features" msgstr "Recursos Experimentais" @@ -11354,6 +11367,10 @@ msgstr "Falha ao enviar o arquivo para o armazenamento da impressora. Tente nova msgid "Send Failed" msgstr "Falha no envio" +# AI Translated +msgid "No available printers" +msgstr "Nenhuma impressora disponível" + msgid "The name length exceeds the limit." msgstr "O comprimento do nome excede o limite." @@ -13132,8 +13149,9 @@ msgstr "Tecla" msgid "Left mouse" msgstr "Mouse esquerdo" -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Disponível em qualquer lugar da janela, mesmo ao digitar em um campo de texto." +# AI Translated +msgid "Available anywhere in the window." +msgstr "Disponível em qualquer lugar da janela." msgid "Run favorite 1 to 10" msgstr "Executar favorito 1 a 10" @@ -13229,9 +13247,6 @@ msgstr "%s está atribuído a %s. Reatribuí-lo a %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "O %s padrão está atribuído a %s. Reatribuí-lo a %s?" -msgid "Global shortcuts also apply while typing." -msgstr "Os atalhos globais também funcionam durante a digitação." - msgid "A key that types a character cannot be a global shortcut." msgstr "Uma tecla que digita um caractere não pode ser um atalho global." @@ -13651,9 +13666,10 @@ msgstr "o modificador \"%1%\" de \"%2%\" (%3% no total) não teve efeito na cost msgid "Seam placement may differ from expected." msgstr "A posição da costura pode diferir do esperado." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Falha ao gravar as estatísticas do G-code em %1%." msgid "Internal Bridge" msgstr "Ponte interna" @@ -13944,7 +13960,7 @@ msgid "\"Leading edge only\" brim applies to belt printers. On this printer it i msgstr "A borda \"Somente bordo de ataque\" se aplica a impressoras de esteira. Nesta impressora, ela é impressa como uma borda externa comum." msgid "A gradient mixed filament is used, but 'Mixed color sublayer' is disabled. The gradient will not be printed." -msgstr "Um filamento misto com gradiente está em uso, mas 'Subcamada de cor mista' está desativado. O gradiente não será impresso." +msgstr "Um filamento misto com degradê está em uso, mas 'Subcamada de cor mista' está desativado. O degradê não será impresso." msgid "Smooth mode of timelapse is not supported when \"by object\" sequence is enabled." msgstr "O modo suave do timelapse não é suportado quando a sequência \"por objeto\" está ativada." @@ -15313,7 +15329,6 @@ msgstr "Este é o comprimento máximo de pontes que não precisam de suporte. De msgid "End G-code" msgstr "G-code de finalização" -# AI Translated msgid "Add end G-code when finishing the entire print." msgstr "Adicionar G-code de finalização ao terminar a impressão completa." @@ -16093,28 +16108,28 @@ msgid "Comma-separated ratio values summing to 1.0, e.g. \"0.7,0.3\"" msgstr "Valores de proporção separados por vírgulas cuja soma seja 1.0; ex.: \"0.7,0.3\"" msgid "Mixed filament gradient" -msgstr "Gradiente do filamento misto" +msgstr "Degradê do filamento misto" msgid "Enable Z-direction gradient mode for mixed filament sub-layers. When enabled, the sub-layer ratios vary linearly across layers." -msgstr "Ativa o modo de gradiente na direção Z para as subcamadas do filamento misto. Quando ativo, as proporções das subcamadas variam linearmente ao longo das camadas." +msgstr "Ativa o modo de degradê na direção Z para as subcamadas do filamento misto. Quando ativo, as proporções das subcamadas variam linearmente ao longo das camadas." msgid "Mixed filament gradient range" -msgstr "Faixa do gradiente do filamento misto" +msgstr "Faixa do degradê do filamento misto" msgid "Start and end ratios for the first component in gradient mode. Comma-separated pair, e.g. \"0.10,0.90\" means 10% to 90%." -msgstr "Proporções inicial e final do primeiro componente no modo de gradiente. Par separado por vírgula; ex.: \"0.10,0.90\" significa de 10% a 90%." +msgstr "Proporções inicial e final do primeiro componente no modo de degradê. Par separado por vírgula; ex.: \"0.10,0.90\" significa de 10% a 90%." msgid "Mixed filament gradient curve" -msgstr "Curva do gradiente do filamento misto" +msgstr "Curva do degradê do filamento misto" msgid "Optional Photoshop-style custom curve mapping Z progress to the first component ratio. Encoded as pipe-separated control points, either \"x,y\" (legacy) or \"x,y,m_in,m_out\" when a tangent override is needed (empty token or \"nan\" means use PCHIP default). x in [0,1]; y is clamped to the configured ratio range, e.g. \"0,0.15|0.5,0.50|1,0.85\". When empty, the linear gradient_range is used instead." msgstr "Curva personalizada opcional no estilo do Photoshop, mapeando o progresso em Z para a proporção do primeiro componente. Codificada como pontos de controle separados por barras verticais, no formato \"x,y\" (legado) ou \"x,y,m_in,m_out\" quando é necessário substituir a tangente (um valor vazio ou \"nan\" usa o padrão PCHIP). X em [0,1]; Y é limitado à faixa de proporção configurada; ex.: \"0,0.15|0.5,0.50|1,0.85\". Quando vazio, o gradient_range linear é usado no lugar." msgid "Mixed filament per-part gradient" -msgstr "Gradiente por peça do filamento misto" +msgstr "Degradê por peça do filamento misto" msgid "When gradient mode is enabled, apply the gradient to each part of an assembly independently rather than treating the whole assembly as one Z range." -msgstr "Quando o modo de gradiente está ativado, aplica o gradiente a cada peça de uma montagem de forma independente em vez de tratar toda a montagem como uma única faixa Z." +msgstr "Quando o modo de degradê está ativado, aplica o degradê a cada peça de uma montagem de forma independente em vez de tratar toda a montagem como uma única faixa Z." msgid "Filament printable" msgstr "Filamento imprimível" @@ -16270,7 +16285,7 @@ msgstr "Densidade do preenchimento adaptativo no centro do objeto." # AI Translated msgid "Adaptive gradient" -msgstr "Gradiente adaptativo" +msgstr "Degradê adaptativo" # AI Translated msgid "" @@ -16941,6 +16956,14 @@ msgstr "Excluir objetos" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Ative esta opção para adicionar o comando EXCLUIR OBJETO no G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Tolerância do contorno" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Desvio máximo do contorno do objeto gravado em EXCLUDE_OBJECT_DEFINE em relação ao contorno original. Valores maiores geram menos pontos, o que ajuda firmwares que travam ao processar G-code com muitos objetos. 0 mantém todos os pontos." + msgid "Verbose G-code" msgstr "G-code detalhado" @@ -20060,11 +20083,13 @@ msgstr "Diretório de saída" msgid "This is the output directory for exported files." msgstr "Este é o diretório de saída para arquivos exportados." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Exportar estatísticas" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Grava as estatísticas de cada placa fatiada em JSON, como plate_N.statistics.json ao lado do seu G-code no diretório de saída e dentro do 3MF de --export-3mf: tempo de impressão, totais de filamento e por tipo de linha, e os mesmos dados por camada e por objeto." msgid "Debug level" msgstr "Nível de depuração" @@ -22435,7 +22460,7 @@ msgid "test %s start..." msgstr "iniciando teste de %s..." #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "teste de %s: IP resolvido = %s" #, c-format, boost-format @@ -29594,31 +29619,24 @@ msgid_plural "The material list supports at most %1% colors. After %2% decomposi msgstr[0] "A lista de materiais suporta no máximo %1% cor. Após a decomposição de %2%, a quantidade de materiais excederia %1%. Exclua os filamentos não utilizados na tela principal antes de decompor." msgstr[1] "A lista de materiais suporta no máximo %1% cores. Após a decomposição de %2%, a quantidade de materiais excederia %1%. Exclua os filamentos não utilizados na tela principal antes de decompor." -# AI Translated msgid "Cyan" msgstr "Ciano" -# AI Translated msgid "Magenta" msgstr "Magenta" -# AI Translated msgid "Yellow" msgstr "Amarelo" -# AI Translated msgid "White" msgstr "Branco" -# AI Translated msgid "Red" msgstr "Vermelho" -# AI Translated msgid "Green" msgstr "Verde" -# AI Translated msgid "Blue" msgstr "Azul" @@ -29642,1230 +29660,1521 @@ msgstr[0] "A lista de filamentos atual não contém %s. Um filamento do projeto msgstr[1] "A lista de filamentos atual não contém %s. Os filamentos do projeto exigidos pelo filamento misto serão criados automaticamente após a decomposição." msgid "Color Picker" -msgstr "" +msgstr "Seletor de Cores" msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Cores Básicas" #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Paleta Orca" #. TRN: Keep the standard/brand name "RAL" unchanged. -msgid "Gradients" -msgstr "" +msgid "RAL Classic" +msgstr "RAL Clássico" +msgid "Gradients" +msgstr "Degradês" + +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Sólido" msgid "Gradient" -msgstr "" +msgstr "Degradê" msgid "Gradient start" -msgstr "" +msgstr "Início do degradê" msgid "Gradient end" -msgstr "" +msgstr "Final do degradê" msgid "Gradient color" -msgstr "" +msgstr "Cor em degradê" msgid "Add color" -msgstr "" +msgstr "Adicionar cor" msgid "Remove color" -msgstr "" +msgstr "Remover cor" msgid "Saturation" -msgstr "" +msgstr "Saturação" msgid "Original color" -msgstr "" +msgstr "Cor original" #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Salvar cor atual" msgid "Palettes" -msgstr "" +msgstr "Paletas" msgid "Search colors" -msgstr "" +msgstr "Buscar cores" msgid "Filter colors" -msgstr "" +msgstr "Filtrar cores" msgid "No matching colors" -msgstr "" +msgstr "Nenhuma cor correspondente" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Cor hexadecimal" # AI Translated msgid "Opacity" msgstr "Opacidade" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Porcentagem de opacidade" msgid "Save color" -msgstr "" +msgstr "Salvar cor" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Insira uma cor hexadecimal completa" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "A seleção de várias cores atual é mantida até você escolher uma cor diferente." #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Até %d cores suportadas." msgid "Crimson" -msgstr "" +msgstr "Carmesim" msgid "Orange red" -msgstr "" +msgstr "Vermelho laranja" msgid "Tomato" -msgstr "" +msgstr "Tomate" msgid "Orange" -msgstr "" +msgstr "Laranja" msgid "Dark orange" -msgstr "" +msgstr "Laranja escuro" msgid "Gold" -msgstr "" +msgstr "Ouro" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Burly wood" -msgstr "" +msgstr "Madeira robusta" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Bisque" -msgstr "" +msgstr "Bisque" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Rosa nebuloso" msgid "Light yellow" -msgstr "" +msgstr "Amarelo claro" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Lemon chiffon" -msgstr "" +msgstr "Chiffon limão" msgid "Beige" -msgstr "" +msgstr "Bege" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Amarelo vara-de-ouro claro" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Vara-de-ouro pálido" msgid "Khaki" -msgstr "" +msgstr "Cáqui" msgid "Dark khaki" -msgstr "" +msgstr "Cáqui escuro" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Peach puff" -msgstr "" +msgstr "Pêssego suave" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mocassim" msgid "Papaya whip" -msgstr "" +msgstr "Creme de papaia" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Amêndoa branqueada" msgid "Antique white" -msgstr "" +msgstr "Branco antigo" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Branco navajo" msgid "Wheat" -msgstr "" +msgstr "Trigo" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Vara-de-ouro" msgid "Chocolate" -msgstr "" +msgstr "Chocolate" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Tijolo refratário" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Marrom sela" msgid "Brown" -msgstr "" +msgstr "Marrom" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Marrom rosado" msgid "Salmon" -msgstr "" +msgstr "Salmão" msgid "Light salmon" -msgstr "" +msgstr "Salmão claro" msgid "Dark salmon" -msgstr "" +msgstr "Salmão escuro" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Marrom arenoso" msgid "Coral" -msgstr "" +msgstr "Coral" msgid "Light coral" -msgstr "" +msgstr "Coral claro" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Vermelho indiano" msgid "Dark red" -msgstr "" +msgstr "Vermelho escuro" msgid "Maroon" -msgstr "" +msgstr "Bordô" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Amarelo verde" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Verde amarelo" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Verde gramado" msgid "Lime green" -msgstr "" +msgstr "Verde limão" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Verde primavera" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Verde primavera médio" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Lima" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Verde floresta" msgid "Dark green" -msgstr "" +msgstr "Verde escuro" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Verde oliva fosco" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliva" msgid "Dark olive green" -msgstr "" +msgstr "Verde oliva escuro" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Verde pálido" msgid "Light green" -msgstr "" +msgstr "Verde claro" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Verde mar médio" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Verde mar" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Verde mar escuro" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Azul cadete" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Água-marinha médio" msgid "Turquoise" -msgstr "" +msgstr "Turquesa" msgid "Medium turquoise" -msgstr "" +msgstr "Turquesa médio" msgid "Dark turquoise" -msgstr "" +msgstr "Turquesa escuro" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Turquesa pálido" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Água" msgid "Light cyan" -msgstr "" +msgstr "Ciano claro" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Creme menta" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Honey dew" -msgstr "" +msgstr "Orvalho de mel" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Água-marinha" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Verde mar claro" msgid "Dark cyan" -msgstr "" +msgstr "Ciano escuro" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Verde azulado" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Cinza ardósia escuro" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Cinza ardósia claro" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Cinza ardósia" msgid "Deep sky blue" -msgstr "" +msgstr "Azul celeste profundo" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Dodger Blue" -msgstr "" +msgstr "Azul Dodger" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Azul céu" msgid "Light sky blue" -msgstr "" +msgstr "Azul celeste claro" msgid "Light blue" -msgstr "" +msgstr "Azul claro" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Azul pó" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Azul aço claro" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Azul aço" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Azul centáurea" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Azul royal" msgid "Medium blue" -msgstr "" +msgstr "Azul médio" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Azul meia-noite" msgid "Dark blue" -msgstr "" +msgstr "Azul escuro" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Azul naval" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Azul ardósia" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Azul ardósia escuro" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Azul ardósia médio" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Violeta azul" msgid "Indigo" -msgstr "" +msgstr "Índigo" msgid "Dark violet" -msgstr "" +msgstr "Violeta escuro" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Orquídea escuro" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Orquídea médio" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orquídea" msgid "Violet" -msgstr "" +msgstr "Violeta" msgid "Medium purple" -msgstr "" +msgstr "Púrpura médio" msgid "Purple" -msgstr "" +msgstr "Púrpura" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Púrpura Rebecca" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Vermelho violeta médio" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Vermelho violeta pálido" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Rosa profundo" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Rosa vivo" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Rosa claro" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rosa" msgid "Plum" -msgstr "" +msgstr "Ameixa" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Cardo" msgid "Fuchsia" -msgstr "" +msgstr "Fúcsia" msgid "Dark magenta" -msgstr "" +msgstr "Magenta escuro" msgid "Linen" -msgstr "" +msgstr "Linho" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Renda antiga" +# AI Translated +# Needs human review: CSS color seashell: Concha, not the print Shell (Casca) from the glossary msgid "Sea shell" -msgstr "" +msgstr "Concha do mar" msgid "Ivory" -msgstr "" +msgstr "Marfim" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Branco floral" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavanda rosado" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Branco fantasma" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Azul Alice" msgid "Lavender" -msgstr "" +msgstr "Lavanda" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Branco fumaça" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" msgid "Black" -msgstr "" +msgstr "Preto" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Coral fogo" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Anêmona-do-mar" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Abismo profundo" msgid "Lobster red" -msgstr "" +msgstr "Vermelho lagosta" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Argila arenosa" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Madeira flutuante" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Espinheiro-marítimo" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Recife ao pôr do sol" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Coral tigre" msgid "Pink coral" -msgstr "" +msgstr "Coral rosa" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Brilho de concha" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Areia" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Alga dourada" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Duna iluminada" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Náutilo âmbar" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Limão-do-mar" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Estrela-do-mar pálida" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Maré de primavera" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Alga lima" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Grama-marinha" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Plâncton neon" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Floresta de algas" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Onda esmeralda" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Sombra de baleia" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Tartaruga-marinha" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagoa" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Corrente tropical" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Fossa da meia-noite" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Alga escura" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Arrebentação cristalina" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Baía turquesa" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Céu sobre o recife" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Shallow sky" -msgstr "" +msgstr "Céu de águas rasas" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Azul elétrico" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Golfinho" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Profundezas do oceano" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Baleia" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Abismo índigo" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Ouriço-do-mar" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Coral lavanda" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Maré violeta" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Orquídea do mar profundo" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Água-viva neon" msgid "Fuchsia coral" -msgstr "" +msgstr "Coral fúcsia" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Água-viva rosa" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Espuma" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Branco concha" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Cinza seixo" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Nuvem de tempestade" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Preto tinta" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Bege verde" msgid "Sand yellow" -msgstr "" +msgstr "Amarelo areia" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Amarelo sinal" msgid "Golden yellow" -msgstr "" +msgstr "Amarelo dourado" msgid "Honey yellow" -msgstr "" +msgstr "Amarelo mel" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Amarelo milho" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Amarelo narciso" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Bege marrom" msgid "Lemon yellow" -msgstr "" +msgstr "Amarelo limão" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Branco ostra" msgid "Light ivory" -msgstr "" +msgstr "Marfim claro" msgid "Zinc yellow" -msgstr "" +msgstr "Amarelo zinco" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Bege cinza" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Amarelo oliva" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Amarelo colza" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Amarelo trânsito" msgid "Ochre yellow" -msgstr "" +msgstr "Amarelo ocre" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Amarelo laranja trânsito" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" msgid "Melon yellow" -msgstr "" +msgstr "Amarelo melão" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Amarelo giesta" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Amarelo dália" msgid "Pastel yellow" -msgstr "" +msgstr "Amarelo pastel" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Bege perolado" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Ouro perolado" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Amarelo sol" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Laranja amarelo" msgid "Deep orange" -msgstr "" +msgstr "Laranja profundo" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Vermelhão" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Laranja perolado" msgid "Pure orange" -msgstr "" +msgstr "Laranja puro" msgid "Luminous orange" -msgstr "" +msgstr "Laranja luminoso" msgid "Luminous bright orange" -msgstr "" +msgstr "Laranja brilhante luminoso" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Laranja vermelho brilhante" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Laranja trânsito" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Laranja sinal" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Laranja salmão" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Rosa perolado" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Laranja cobre" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Marrom sinal" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Fir orange" -msgstr "" +msgstr "Laranja abeto" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Vermelho sinal" msgid "Luminous red" -msgstr "" +msgstr "Vermelho luminoso" msgid "Carmine red" -msgstr "" +msgstr "Vermelho carmim" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Vermelho carmim perolado" msgid "Pure red" -msgstr "" +msgstr "Vermelho puro" msgid "Luminous deep red" -msgstr "" +msgstr "Vermelho profundo luminoso" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Vermelho groselha" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Vermelho rubi perolado" msgid "Fire red" -msgstr "" +msgstr "Vermelho fogo" msgid "Ruby red" -msgstr "" +msgstr "Vermelho rubi" msgid "Purple red" -msgstr "" +msgstr "Vermelho púrpura" msgid "Wine red" -msgstr "" +msgstr "Vermelho vinho" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Vermelho preto" msgid "Oxide red" -msgstr "" +msgstr "Vermelho ferrugem" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Vermelho marrom" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Pine red" -msgstr "" +msgstr "Vermelho pinheiro" msgid "Tomato red" -msgstr "" +msgstr "Vermelho tomate" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Rosa antigo" msgid "Coral red" -msgstr "" +msgstr "Vermelho coral" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Rosa" msgid "Strawberry red" -msgstr "" +msgstr "Vermelho morango" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Vermelho trânsito" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Rosa salmão" msgid "Luminous rose" -msgstr "" +msgstr "Rosa luminoso" msgid "Luminous bright red" -msgstr "" +msgstr "Vermelho brilhante luminoso" msgid "Raspberry red" -msgstr "" +msgstr "Vermelho framboesa" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Vermelho oriental" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Rubi perolado" msgid "Red purple" -msgstr "" +msgstr "Púrpura vermelho" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Violeta vermelho" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Violeta urze" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Violeta bordô" msgid "Mahogany" -msgstr "" +msgstr "Mogno" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Púrpura cinza" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Violeta sinal" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Verde abeto" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Sabine grey" -msgstr "" +msgstr "Cinza sabino" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Violeta perolado" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Pearl blackberry" -msgstr "" +msgstr "Amora perolado" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Azul verde" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Azul ultramar" msgid "Sapphire blue" -msgstr "" +msgstr "Azul safira" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Azul preto" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Azul sinal" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Azul brilhante" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Azul cinza" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Azure blue" -msgstr "" +msgstr "Azul celeste" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Azul genciana" msgid "Cobalt blue" -msgstr "" +msgstr "Azul cobalto" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Azul pombo" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Azul trânsito" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Azul turquesa" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Azul Capri" msgid "Ocean blue" -msgstr "" +msgstr "Azul marinho" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Azul água" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Azul noite" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Azul distante" msgid "Pastel blue" -msgstr "" +msgstr "Azul pastel" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Azul genciana perolado" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Azul meia-noite perolado" msgid "Patina green" -msgstr "" +msgstr "Verde pátina" msgid "Emerald green" -msgstr "" +msgstr "Verde esmeralda" msgid "Leaf green" -msgstr "" +msgstr "Verde folha" msgid "Olive green" -msgstr "" +msgstr "Verde oliva" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Verde azul" msgid "Moss green" -msgstr "" +msgstr "Verde musgo" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Oliva cinza" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Verde pinheiro" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Marrom pinheiro" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Verde grama" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Verde reseda" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Verde marrom" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Verde junco" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Verde preto" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Verde turquesa" +# AI Translated msgid "May green" -msgstr "" +msgstr "Verde maio" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Verde óxido de cromo" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Verde trânsito" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Verde samambaia" msgid "Opal green" -msgstr "" +msgstr "Verde opala" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Verde menta" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Verde bronze" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Verde perolado" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Sax turquoise" -msgstr "" +msgstr "Turquesa sax" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Turquesa perolado" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Jade perolado" msgid "Pure green" -msgstr "" +msgstr "Verde puro" msgid "Luminous green" -msgstr "" +msgstr "Verde luminoso" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Cinza esquilo" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Cinza prata" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Cinza oliva" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Cinza musgo" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Cinza sinal" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Cinza rato" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Cinza bege" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Cinza cáqui" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Cinza verde" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Cinza lona" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Cinza ferro" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Cinza basalto" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Cinza marrom" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Cinza ardósia" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Cinza antracite" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Cinza claro" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Umber grey" -msgstr "" +msgstr "Cinza umbra" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Cinza concreto" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Cinza grafite" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Cinza granito" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Cinza pedra" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Cinza seixo" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Cinza cimento" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Cinza amarelo" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Cinza platina" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Cinza poeira" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Cinza ágata" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Cinza quartzo" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Cinza janela" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Cinza trânsito A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Cinza trânsito B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Cinza seda" +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names msgid "Telegrey 1" -msgstr "" +msgstr "Telecinza 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telecinza 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telecinza 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Cinza rato perolado" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Marrom verde" msgid "Ochre brown" -msgstr "" +msgstr "Marrom ocre" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Marrom argila" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Marrom cobre" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Marrom chocolate" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Marrom oliva" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Marrom noz" msgid "Red brown" -msgstr "" +msgstr "Marrom vermelho" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Marrom sépia" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Marrom castanha" msgid "Mahogany brown" -msgstr "" +msgstr "Marrom mogno" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Marrom cinza" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Cobre perolado" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Marrom bege" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Marrom moca perolado" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Marrom terra" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Marrom perolado" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Creme" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Branco cinza" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Branco sinal" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Preto sinal" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Preto azeviche" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Alumínio branco" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Alumínio cinza" msgid "Pure white" -msgstr "" +msgstr "Branco puro" msgid "Graphite black" -msgstr "" +msgstr "Preto grafite" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Branco trânsito" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Preto trânsito" msgid "Papyrus white" -msgstr "" +msgstr "Branco papiro" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Cinza claro perolado" msgid "Metal: Silver" -msgstr "" +msgstr "Metal: Prata" msgid "Metal: Brass" -msgstr "" +msgstr "Metal: Latão" msgid "Metal: Gold" -msgstr "" +msgstr "Metal: Ouro" msgid "Metal: Copper" -msgstr "" +msgstr "Metal: Cobre" msgid "Metal: Bronze" -msgstr "" +msgstr "Metal: Bronze" msgid "Nature: Pearl" -msgstr "" +msgstr "Natureza: Pérola" msgid "Nature: Rainbow" -msgstr "" +msgstr "Natureza: Arco-Íris" msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natureza: Céu Limpo" msgid "Nature: Sunset" -msgstr "" +msgstr "Natureza: Pôr do Sol" msgid "Wood: Dark" -msgstr "" +msgstr "Madeira: Escura" msgid "Wood: Medium" -msgstr "" +msgstr "Madeira: Média" msgid "Wood: Light" -msgstr "" +msgstr "Madeira: Clara" # AI Translated msgid "Alternate nozzles:" @@ -31327,11 +31636,23 @@ msgstr "Remover de Minhas texturas" msgid "Built-in" msgstr "Integradas" +msgid "My textures" +msgstr "Minhas texturas" + msgid "No textures found." msgstr "Nenhuma textura encontrada." -msgid "My textures" -msgstr "Minhas texturas" +# AI Translated +msgid "Texture libraries" +msgstr "Bibliotecas de texturas" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Explorar mais bibliotecas de texturas" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Abre o OrcaCloud na página inicial para procurar plugins." msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." msgstr "Importe sua própria imagem como mapa de altura. Ela é convertida para o formato a partir do qual o fatiador assa e salva na sua pasta pessoal de texturas, mantida separada das texturas fornecidas com o OrcaSlicer." @@ -31699,11 +32020,15 @@ msgstr "Mapeada pelo layout UV do próprio modelo, que já é o posicionamento - msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Largura de uma cópia da textura no modelo. Valores menores repetem o padrão mais vezes e deixam seus detalhes mais finos; com Ladrilho desativado, este é o tamanho da cópia única." +# AI Translated +# Needs human review: Caption under an image comparing tile sizes in the texture gizmo; check plural/gender fits what is shown msgid "Larger" -msgstr "" +msgstr "Maiores" +# AI Translated +# Needs human review: Caption under an image comparing tile sizes in the texture gizmo; check plural/gender fits what is shown msgid "Smaller" -msgstr "" +msgstr "Menores" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -31769,7 +32094,7 @@ msgstr "Misturar filamentos" # AI Translated msgid "Interleaves two filaments to fake the colors in between, so a handful of filaments can cover a photo or a gradient. An image of flat colors prints the same either way. Off uses one filament per area." -msgstr "Intercala dois filamentos para simular as cores intermediárias, de modo que poucos filamentos consigam cobrir uma foto ou um gradiente. Uma imagem de cores chapadas é impressa da mesma forma em ambos os casos. Desativado, usa um filamento por área." +msgstr "Intercala dois filamentos para simular as cores intermediárias, de modo que poucos filamentos consigam cobrir uma foto ou um degradê. Uma imagem de cores chapadas é impressa da mesma forma em ambos os casos. Desativado, usa um filamento por área." # AI Translated msgid "Mixed colors" @@ -31779,11 +32104,15 @@ msgstr "Cores mistas" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "O número máximo de filamentos mistos que um assamento pode adicionar. Eles são escolhidos a partir das cores da textura, e somente os que o assamento realmente usa são criados." +# AI Translated +# Needs human review: Caption of the mixed-colors illustration; check gender fits (cores) msgid "Few" -msgstr "" +msgstr "Poucas" +# AI Translated +# Needs human review: Caption of the mixed-colors illustration; check gender fits (cores) msgid "Many" -msgstr "" +msgstr "Muitas" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -32124,11 +32453,13 @@ msgstr "Remalhamento" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Tamanho dos triângulos com que o modelo inteiro é reconstruído, em milímetros. O deslocamento funciona melhor em uma malha uniforme; isto cria uma a partir de uma importação irregular." +# AI Translated msgid "Before" -msgstr "" +msgstr "Antes" +# AI Translated msgid "After" -msgstr "" +msgstr "Depois" msgid "Keep sharp edges" msgstr "Manter arestas vivas" @@ -32402,13 +32733,12 @@ msgstr "+ Adicionar Material" msgid "- Delete Material" msgstr "- Excluir Material" -# AI Translated msgid "Gradient Effect" -msgstr "Efeito de Gradiente" +msgstr "Efeito de Degradê" # AI Translated msgid "Enable per-part gradient effect" -msgstr "Ativar efeito de gradiente por peça" +msgstr "Ativar efeito de degradê por peça" # AI Translated msgid "Mixing Recommendations" @@ -33954,6 +34284,10 @@ msgstr "Script" msgid "Slicing Pipeline" msgstr "Pipeline de fatiamento" +# AI Translated +msgid "Resource Texture" +msgstr "Textura de recurso" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "A interface de configuração do plugin estava vazia. Exibindo o editor padrão." @@ -34101,6 +34435,30 @@ msgstr "O diretório do plugin contém arquivos de entrada .py e .whl" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "O diretório do plugin não contém um arquivo de entrada .py ou .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "O diretório de textura de recurso não está definido" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Não foi possível resolver o diretório de textura de recurso" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "O caminho da textura de recurso não é um diretório" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Não foi possível resolver a pasta do plugin" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "O diretório de textura de recurso está fora da pasta do plugin" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Não foi possível ler o diretório de textura de recurso" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -34544,7 +34902,7 @@ msgstr "espaço %1%: o componente %2% referencia um espaço de filamento misto" # AI Translated #, boost-format msgid "slot %1%: gradient requires exactly 2 components" -msgstr "espaço %1%: o gradiente exige exatamente 2 componentes" +msgstr "espaço %1%: o degradê exige exatamente 2 componentes" # AI Translated #, boost-format @@ -34559,7 +34917,7 @@ msgstr "Falha ao carregar o arquivo de configuração \"%1%\": %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Não é um arquivo G-code gerado pelo %1%." # AI Translated @@ -34676,7 +35034,7 @@ msgstr "" msgid "Failed making a temporary copy of G-code file %1% before running a post-processing script: %2%" msgstr "Falha ao criar uma cópia temporária do arquivo G-code %1% antes de executar um script de pós-processamento: %2%" -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "O pós-processador não consegue encontrar o arquivo G-code exportado" #, boost-format @@ -35034,6 +35392,29 @@ msgstr "" "Evitar empenamento\n" "Você sabia que ao imprimir materiais propensos ao empenamento como ABS, aumentar adequadamente a temperatura da mesa aquecida pode reduzir a probabilidade de empenamento?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Amarelo dálmata" + +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names +#~ msgid "Capsanthin violet" +#~ msgstr "Violeta capsantina" + +# AI Translated +# Needs human review: Color name of uncertain Portuguese rendering; check the shade it names +#~ msgid "Olivestone" +#~ msgstr "Pedra oliva" + +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Disponível em qualquer lugar da janela, mesmo ao digitar em um campo de texto." + +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Os atalhos globais também funcionam durante a digitação." + +#~ msgid "Solid" +#~ msgstr "Sólido" + #~ msgid "Please choose the filament color" #~ msgstr "Escolha a cor do filamento" @@ -35495,13 +35876,6 @@ msgstr "" #~ msgid " is partially outside the printable area, and it cannot be printed.\n" #~ msgstr " está parcialmente fora da área imprimível, e não pode ser impresso.\n" -# AI Translated -#~ msgid "no configured tool" -#~ msgstr "nenhuma ferramenta configurada" - -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Adicionar G-code de finalização ao terminar a impressão completa." - #~ msgid "Maximum X speed" #~ msgstr "Velocidade máxima em X" @@ -35517,25 +35891,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Plugin(s) Python invocado(s) em cada etapa do pipeline de fatiamento para ler e modificar dados intermediários de fatiamento, incluindo uma etapa final de pós-processamento do G-code. Pesquisa/experimental." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Quando ativado, o fatiador emite o G-code com o conteúdo da zona principal centralizado na origem da mesa (0,0). O firmware da impressora é responsável por posicionar as cópias/espelhos na posição física de cada zona. Ative somente em impressoras cujo firmware aplica seus próprios deslocamentos de zona no modo cópia/espelho (ex.: modo de duplicação IDEX do RepRapFirmware). Não tem efeito no modo Principal." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Substituição por placa que mapeia as cabeças físicas para os espaços de filamento (começando em 1). Vazio significa usar os padrões da inversão do pem." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Eixo em torno do qual a malha é girada antes do fatiamento. Esta é a inclinação da impressora de esteira: uma rotação isométrica (sem distorção) que também define a renderização da mesa e a inclinação da gravidade dos suportes, e que a transformação inversa do G-code desfaz antes do cisalhamento/escala e do remapeamento do referencial da máquina. X é a inclinação típica do pórtico (a esteira se move ao longo de Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Substituição para especialistas: define o ângulo de inclinação do referencial da máquina (cisalhamento/escala do G-code) independentemente do ângulo de rotação antes do fatiamento. Quando desativado, a transformação do referencial da máquina é derivada do ângulo de inclinação da esteira, de modo que um único ângulo controla as duas etapas. Ative somente para compensar uma máquina cuja inclinação física do pórtico difere da rotação de fatiamento." - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "O desvio máximo permitido ao reduzir a resolução para a configuração 'Resolução máxima de parede'. Se você aumentar esse valor, a impressão ficará menos precisa, mas o G-code será menor. 'Desvio máximo de parede' limita a 'Resolução máxima de parede', portanto, se houver conflito entre os dois, 'Desvio máximo de parede' terá prioridade." - #~ msgid " not in range " #~ msgstr " fora do intervalo " diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po index 8215dec8f6..639d9948fc 100644 --- a/localization/i18n/ru/OrcaSlicer_ru.po +++ b/localization/i18n/ru/OrcaSlicer_ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OrcaSlicer V2.5.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-02-25 13:38+0300\n" "Last-Translator: Felix14_v2\n" "Language-Team: Felix14_v2 (ДС/ТГ: @felix14_v2, почта: aleks111001@list.ru), Andylg \n" @@ -750,17 +750,22 @@ msgstr "Элемент" msgid "Plate" msgstr "Стол" +# AI Translated +# Needs human review: No glossary rendering yet (Russian cell empty); Распределить matches the existing Align/Distribute label. msgid "Distribute" -msgstr "" +msgstr "Распределить" msgid "Coordinate system used for transform actions." msgstr "Опорная система координат для изменения положения." +# AI Translated +# Needs human review: Label in the Align/Distribute tool: what the objects are aligned to; check the wording in the UI. msgid "Reference for alignment" -msgstr "" +msgstr "Опора для выравнивания" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Выберите не менее 3 частей или объектов" # AI Translated msgid "Align left" @@ -814,8 +819,9 @@ msgstr "Распределить по высоте" msgid "Drop" msgstr "Опустить на стол" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Сместить выбранное по оси Z так, чтобы его нижняя точка касалась стола." msgid "Absolute" msgstr "Поворот" @@ -1733,7 +1739,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Обводка фигуры (%1%) не поддерживается: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Недопустимое состояние. Сообщите о шагах воспроизведения на GitHub" # AI Translated @@ -1741,11 +1747,11 @@ msgid "No embossed file" msgstr "Нет файла рельефа" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "В рельефной фигуре отсутствует файл SVG" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Отсутствуют данные файла SVG" msgid "Face the camera" @@ -2070,17 +2076,23 @@ msgstr "Запуск режима сборки" msgid "Leaving Assembly gizmo" msgstr "Выход из режима сборки" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Части разрезанного объекта нельзя перемещать" +# AI Translated +# Needs human review: Plate renders as Стол per the glossary; check it reads naturally for a project plate. msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Выравнивание по столу доступно только по осям X и Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Отключите притягивание к столу для выбранных объектов, чтобы перемещать их по оси Z" +# AI Translated +# Needs human review: Plate renders as Стол per the glossary; check it reads naturally for a project plate. msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Все выбранные объекты должны находиться на одном столе" msgid "Shift+" msgstr "Shift+" @@ -4961,7 +4973,7 @@ msgstr "Пожалуйста, сохраните проект и перезап msgid "Unknown C++ exception." msgstr "Неизвестное исключение C++." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Обработка G-code из предыдущего файла…" msgid "Slicing complete" @@ -6538,8 +6550,10 @@ msgstr "Оси координат" msgid "Gridlines" msgstr "Разметка" +# AI Translated +# Needs human review: No glossary rendering yet (Russian cell empty); check the term for hiding the interface to concentrate on the 3D canvas. msgid "Focus mode" -msgstr "" +msgstr "Режим фокуса" msgid "Labels" msgstr "Имена моделей" @@ -6600,7 +6614,7 @@ msgstr "Объём:" msgid "Size:" msgstr "Размер:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "В G-code на %d слое (z = %.2lf мм) обнаружен конфликт путей. Пожалуйста, разместите конфликтующие модели дальше друг от друга (%s <-> %s)." @@ -10941,11 +10955,13 @@ msgstr "" "\n" "Примечание: профили остаются недоступными для выбора." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Экспортировать статистику вместе с G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Если включено, при экспорте файла G-code рядом с ним записывается его статистика в формате JSON (.statistics.json), а экспортируемый нарезанный файл 3MF содержит её внутри: время печати, итоги по материалу и типам линий, а также те же данные по слоям и по объектам." msgid "Experimental Features" msgstr "Экспериментальные настройки" @@ -11791,6 +11807,10 @@ msgstr "Не удалось загрузить файл в хранилище п msgid "Send Failed" msgstr "Ошибка отправки" +# AI Translated +msgid "No available printers" +msgstr "Нет доступных принтеров" + msgid "The name length exceeds the limit." msgstr "Слишком длинное имя." @@ -13629,8 +13649,8 @@ msgid "Left mouse" msgstr "ЛКМ" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Доступно в любом месте окна, даже при вводе текста в поле." +msgid "Available anywhere in the window." +msgstr "Доступно в любом месте окна." # AI Translated msgid "Run favorite 1 to 10" @@ -13740,10 +13760,6 @@ msgstr "%s уже назначено для: %s. Переназначить на msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Сочетание по умолчанию %s уже назначено для: %s. Переназначить на «%s»?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Глобальные сочетания клавиш работают и при вводе текста." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Клавиша, вводящая символ, не может быть глобальным сочетанием." @@ -14184,9 +14200,10 @@ msgstr "модификатор «%1%» модели «%2%» (всего: %3%) н msgid "Seam placement may differ from expected." msgstr "Размещение шва может отличаться от ожидаемого." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Не удалось записать статистику G-code в %1%." msgid "Internal Bridge" msgstr "Внутренний мост" @@ -17713,6 +17730,14 @@ msgstr "Исключение объектов" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Включите эту опцию, чтобы добавить команду EXCLUDE OBJECT (исключение объектов) в G-code для печати на принтере с прошивкой Klipper." +# AI Translated +msgid "Outline tolerance" +msgstr "Допуск обводки" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Максимальное отклонение обводки объекта, записываемой в EXCLUDE_OBJECT_DEFINE, от исходной обводки. Чем больше значение, тем меньше точек, что помогает прошивкам, которые зависают при разборе G-code с большим числом объектов. При 0 сохраняются все точки." + msgid "Verbose G-code" msgstr "Подробный G-code" @@ -21204,11 +21229,13 @@ msgstr "Папку сохранения" msgid "This is the output directory for exported files." msgstr "Выходной каталог для экспортированных файлов." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Экспорт статистики" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Записывать статистику каждого нарезанного стола в формате JSON: plate_N.statistics.json рядом с его G-code в выходной папке и внутри 3MF при --export-3mf. Содержит время печати, итоги по материалу и типам линий, а также те же данные по слоям и по объектам." msgid "Debug level" msgstr "Уровень отладки журнала" @@ -23636,7 +23663,7 @@ msgstr "тест %s: запуск..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "тест %s: IP-адрес определён = %s" # AI Translated @@ -31029,1231 +31056,1649 @@ msgstr[0] "В текущем списке материалов нет: %s. Ма msgstr[1] "В текущем списке материалов нет: %s. Материалы проекта, необходимые для смешанного материала, будут созданы автоматически после разложения." msgstr[2] "В текущем списке материалов нет: %s. Материалы проекта, необходимые для смешанного материала, будут созданы автоматически после разложения." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Выбор цвета" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Основные цвета" +# AI Translated +# Needs human review: No glossary rendering yet for Palette (Russian cell empty); Палитра proposed. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Палитра Orca" +# AI Translated +# Needs human review: Brand RAL kept; check whether Classic should be translated or kept in English. #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Классика" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Градиенты" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Однотонный" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Градиент" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Начало градиента" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Конец градиента" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Цвет градиента" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Добавить цвет" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Удалить цвет" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Насыщенность" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Исходный цвет" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Сохранить текущий цвет" +# AI Translated +# Needs human review: No glossary rendering yet for Palette (Russian cell empty); Палитра proposed. msgid "Palettes" -msgstr "" +msgstr "Палитры" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Поиск цветов" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Фильтр цветов" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Нет подходящих цветов" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "HEX-цвет" # AI Translated msgid "Opacity" msgstr "Непрозрачность" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Непрозрачность в процентах" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Сохранить цвет" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Введите полный шестнадцатеричный код цвета" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Текущий выбор нескольких цветов сохраняется, пока вы не выберете другой цвет." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Поддерживается до %d цветов." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Кармазин" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Оранжево-красный" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Томатный" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Оранжевый" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Тёмно-оранжевый" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Золотой" +# AI Translated +# Needs human review: CSS burlywood; check the natural Russian color name. msgid "Burly wood" -msgstr "" +msgstr "Древесный" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Бисквитный" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Туманная роза" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Светло-жёлтый" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Лимонный шифон" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Бежевый" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Светло-золотисто-жёлтый" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Бледно-золотистый" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Хаки" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Тёмный хаки" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Персиковый мусс" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Мокасиновый" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Взбитая папайя" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Бланшированный миндаль" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Античный белый" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Белый навахо" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Пшеничный" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Золотистый" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Шоколадный" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Перу" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Кирпичный" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Сиена" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Седельно-коричневый" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Коричневый" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Розово-коричневый" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Лососевый" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Светло-лососевый" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Тёмно-лососевый" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Песочно-коричневый" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Коралловый" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Светло-коралловый" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Индийский красный" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Тёмно-красный" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Бордовый" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Зелёно-жёлтый" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Жёлто-зелёный" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Шартрез" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Зелёный газон" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Зелёный лайм" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Весенний зелёный" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Средний весенний зелёный" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Лайм" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Лесной зелёный" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Тёмно-зелёный" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Тускло-оливковый" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Оливковый" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Тёмно-оливковый" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Бледно-зелёный" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Светло-зелёный" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Средний морской зелёный" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Морской зелёный" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Тёмный морской зелёный" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Кадетский синий" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Средний аквамарин" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Бирюзовый" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Средне-бирюзовый" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Тёмно-бирюзовый" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Бледно-бирюзовый" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Аква" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Светло-циановый" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Мятный крем" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Медовая роса" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Аквамарин" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Светлый морской зелёный" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Тёмно-циановый" +# AI Translated +# Needs human review: CSS teal; check the natural Russian color name. msgid "Teal" -msgstr "" +msgstr "Зелёная бирюза" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Тёмный сланцево-серый" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Светлый сланцево-серый" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Сланцево-серый" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Насыщенный небесно-голубой" +# AI Translated +# Needs human review: CSS dodgerblue; check the natural Russian color name. msgid "Dodger Blue" -msgstr "" +msgstr "Синий доджер" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Небесно-голубой" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Светлый небесно-голубой" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Светло-голубой" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Пудрово-голубой" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Светлый стально-синий" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Стально-синий" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Васильковый" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Королевский синий" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Средний синий" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Полуночно-синий" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Тёмно-синий" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Морской синий" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Сланцево-синий" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Тёмный сланцево-синий" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Средний сланцево-синий" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Сине-фиолетовый" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Индиго" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Тёмно-фиолетовый" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Тёмная орхидея" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Средняя орхидея" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Орхидея" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Фиолетовый" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Средний пурпурный" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Пурпурный" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Пурпурный Ребекки" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Средний фиолетово-красный" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Бледный фиолетово-красный" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Насыщенный розовый" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Ярко-розовый" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Светло-розовый" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Розовый" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Сливовый" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Чертополох" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Фуксия" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Тёмная маджента" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Льняной" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Старое кружево" +# AI Translated +# Needs human review: Color name; the Shell glossary term does not apply. msgid "Sea shell" -msgstr "" +msgstr "Морская раковина" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Слоновая кость" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Цветочно-белый" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Лавандовый румянец" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Призрачно-белый" +# AI Translated +# Needs human review: CSS aliceblue; check the natural Russian color name. msgid "Alice blue" -msgstr "" +msgstr "Голубой Элис" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Лавандовый" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Белый дым" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Гейнсборо" +# AI Translated msgid "Black" -msgstr "" +msgstr "Чёрный" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Коралловый огонь" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Морская анемона" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Глубокая бездна" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Красный омар" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Песчаная глина" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Плавник" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Облепиха" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Закатный риф" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Тигровый коралл" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Розовый коралл" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Сияние ракушки" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Песок" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Золотая ламинария" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Дюна на солнце" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Янтарный наутилус" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Морской лимон" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Бледная морская звезда" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Весенний прилив" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Лаймовые водоросли" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Морская трава" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Неоновый планктон" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Лес ламинарии" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Изумрудная волна" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Тень кита" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Морская черепаха" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Лагуна" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Тропическое течение" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Полуночная впадина" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Тёмная ламинария" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Хрустальный прибой" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Бирюзовая бухта" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Небо над рифом" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Небо мелководья" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Электрик" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Дельфин" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Океанские глубины" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Кит" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Индиговая бездна" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Морской ёж" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Лавандовый коралл" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Фиолетовый прилив" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Глубоководная орхидея" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Неоновое желе" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Фуксиевый коралл" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Розовая медуза" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Пена" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Белая ракушка" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Галечно-серый" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Грозовая туча" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Чернильно-чёрный" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Зелёно-бежевый" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Песочно-жёлтый" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Сигнальный жёлтый" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Золотисто-жёлтый" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Медово-жёлтый" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Кукурузно-жёлтый" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Нарциссово-жёлтый" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Коричнево-бежевый" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Лимонно-жёлтый" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Устрично-белый" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Светлая слоновая кость" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Цинково-жёлтый" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Серо-бежевый" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Оливково-жёлтый" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Рапсово-жёлтый" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Транспортный жёлтый" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Охристо-жёлтый" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Транспортный оранжево-жёлтый" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Карри" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Дынно-жёлтый" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Ракитниково-жёлтый" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Георгиново-жёлтый" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Пастельно-жёлтый" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Перламутровый бежевый" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Перламутровый золотой" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Солнечно-жёлтый" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Жёлто-оранжевый" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Насыщенный оранжевый" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Киноварь" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Перламутровый оранжевый" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Чистый оранжевый" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Светящийся оранжевый" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Светящийся ярко-оранжевый" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Ярко-красно-оранжевый" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Транспортный оранжевый" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Сигнальный оранжевый" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Лососево-оранжевый" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Перламутровый розовый" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Медно-оранжевый" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Сигнальный коричневый" +# AI Translated +# Needs human review: Source name unclear; translated literally. msgid "Fir orange" -msgstr "" +msgstr "Пихтово-оранжевый" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Сигнальный красный" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Светящийся красный" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Карминово-красный" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Перламутровый карминово-красный" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Чистый красный" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Светящийся насыщенный красный" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Смородиново-красный" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Перламутровый рубиново-красный" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Огненно-красный" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Рубиново-красный" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Пурпурно-красный" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Винно-красный" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Чёрно-красный" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Оксидно-красный" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Коричнево-красный" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Сосново-красный" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Томатно-красный" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Античный розовый" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Кораллово-красный" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Роза" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Клубнично-красный" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Транспортный красный" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Лососево-розовый" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Светящаяся роза" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Светящийся ярко-красный" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Малиново-красный" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Восточный красный" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Перламутровый рубиновый" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Красно-пурпурный" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Красно-фиолетовый" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Вересково-фиолетовый" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Бордово-фиолетовый" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Красное дерево" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Серо-пурпурный" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Сигнальный фиолетовый" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Пихтово-зелёный" +# AI Translated +# Needs human review: Source name unclear; translated literally. msgid "Sabine grey" -msgstr "" +msgstr "Сабинский серый" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Перламутровый фиолетовый" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Перламутровый ежевичный" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Зелёно-синий" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ультрамариново-синий" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Сапфирово-синий" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Чёрно-синий" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Сигнальный синий" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Бриллиантово-синий" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Серо-синий" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Лазурно-синий" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Горечавково-синий" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Кобальтово-синий" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Голубино-синий" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Транспортный синий" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Бирюзово-синий" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Синий Капри" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Океанский синий" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Водно-синий" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Ночно-синий" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Дальний синий" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Пастельно-синий" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Перламутровый горечавково-синий" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Перламутровый полуночно-синий" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Патиново-зелёный" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Изумрудно-зелёный" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Лиственно-зелёный" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Оливково-зелёный" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Сине-зелёный" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Мшисто-зелёный" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Серо-оливковый" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Сосново-зелёный" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Сосново-коричневый" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Травяно-зелёный" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Резедово-зелёный" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Коричнево-зелёный" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Тростниково-зелёный" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Чёрно-зелёный" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Бирюзово-зелёный" +# AI Translated msgid "May green" -msgstr "" +msgstr "Майский зелёный" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Хромоксидный зелёный" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Транспортный зелёный" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Папоротниково-зелёный" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Опалово-зелёный" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Мятно-зелёный" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Бронзово-зелёный" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Перламутровый зелёный" +# AI Translated +# Needs human review: Source name unclear (Saxe blue?); translated literally. msgid "Sax turquoise" -msgstr "" +msgstr "Саксонско-бирюзовый" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Перламутровый бирюзовый" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Перламутровый нефритовый" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Чистый зелёный" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Светящийся зелёный" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Беличий серый" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Серебристо-серый" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Оливково-серый" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Мшисто-серый" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Сигнальный серый" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Мышино-серый" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Бежево-серый" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Хаки-серый" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Зелёно-серый" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Брезентово-серый" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Железно-серый" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Базальтово-серый" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Коричнево-серый" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Сланцево-серый" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Антрацитово-серый" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Светло-серый" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Умброво-серый" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Бетонно-серый" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Графитово-серый" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Гранитно-серый" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Каменно-серый" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Галечно-серый" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Цементно-серый" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Жёлто-серый" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Платиново-серый" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Пыльно-серый" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Агатово-серый" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Кварцево-серый" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Оконно-серый" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Транспортный серый A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Транспортный серый B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Шёлково-серый" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Телесерый 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Телесерый 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Телесерый 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Перламутровый мышино-серый" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Зелёно-коричневый" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Охристо-коричневый" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Глинисто-коричневый" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Медно-коричневый" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Шоколадно-коричневый" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Оливково-коричневый" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Орехово-коричневый" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Красно-коричневый" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Сепиево-коричневый" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Каштаново-коричневый" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Махагоново-коричневый" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Серо-коричневый" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Перламутровый медный" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Бежево-коричневый" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Перламутровый мокко-коричневый" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Землисто-коричневый" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Перламутровый коричневый" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Кремовый" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Серо-белый" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Сигнальный белый" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Сигнальный чёрный" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Гагатово-чёрный" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Белый алюминий" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Серый алюминий" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Чистый белый" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Графитово-чёрный" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Транспортный белый" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Транспортный чёрный" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Папирусно-белый" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Перламутровый светло-серый" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Металл: серебро" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Металл: латунь" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Металл: золото" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Металл: медь" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Металл: бронза" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Природа: жемчуг" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Природа: радуга" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Природа: ясное небо" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Природа: закат" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Дерево: тёмное" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Дерево: среднее" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Дерево: светлое" # AI Translated msgid "Alternate nozzles:" @@ -32730,13 +33175,25 @@ msgstr "Удалить из «Моих текстур»" msgid "Built-in" msgstr "Встроенные" +# AI Translated +msgid "My textures" +msgstr "Мои текстуры" + # AI Translated msgid "No textures found." msgstr "Текстуры не найдены." # AI Translated -msgid "My textures" -msgstr "Мои текстуры" +msgid "Texture libraries" +msgstr "Библиотеки текстур" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Найти другие библиотеки текстур" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Открывает OrcaCloud на главной странице для просмотра плагинов." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33139,11 +33596,15 @@ msgstr "Наложение выполняется по собственной UV msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Ширина одной копии текстуры на модели. Чем меньше значение, тем чаще повторяется узор и тем мельче его детали; при выключенной «Плитке» это размер единственной копии." +# AI Translated +# Needs human review: Caption of a tile-size picture in the texture-displacement tool; check it reads right. msgid "Larger" -msgstr "" +msgstr "Крупнее" +# AI Translated +# Needs human review: Caption of a tile-size picture in the texture-displacement tool; check it reads right. msgid "Smaller" -msgstr "" +msgstr "Мельче" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33219,11 +33680,15 @@ msgstr "Смешанные цвета" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Максимальное число смешанных материалов, которое может добавить запекание. Они подбираются по цветам текстуры, и создаются только те, которые запекание действительно использует." +# AI Translated +# Needs human review: Caption under a mixed-colors image in the texture-displacement tool; check it reads right. msgid "Few" -msgstr "" +msgstr "Мало" +# AI Translated +# Needs human review: Caption under a mixed-colors image in the texture-displacement tool; check it reads right. msgid "Many" -msgstr "" +msgstr "Много" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33584,11 +34049,13 @@ msgstr "Перестроение сетки" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Размер треугольников, с которым перестраивается вся модель, в миллиметрах. Смещение лучше всего работает на равномерной сетке; этот параметр делает её из неравномерной импортированной." +# AI Translated msgid "Before" -msgstr "" +msgstr "До" +# AI Translated msgid "After" -msgstr "" +msgstr "После" # AI Translated msgid "Keep sharp edges" @@ -35475,6 +35942,10 @@ msgstr "Скрипт" msgid "Slicing Pipeline" msgstr "Конвейер нарезки" +# AI Translated +msgid "Resource Texture" +msgstr "Текстура ресурса" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Интерфейс настройки плагина пуст. Показан редактор по умолчанию." @@ -35622,6 +36093,30 @@ msgstr "В папке плагина есть одновременно вход msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "В папке плагина нет входного файла .py или .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Папка текстур ресурса не задана" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Не удалось определить папку текстур ресурса" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Путь к текстурам ресурса не является папкой" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Не удалось определить папку плагина" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Папка текстур ресурса находится вне папки плагина" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Не удалось прочитать папку текстур ресурса" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36080,7 +36575,7 @@ msgstr "Не удалось загрузить файл конфигурации # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Это не файл G-code, созданный в %1%." # AI Translated @@ -36200,7 +36695,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Не удалось создать временную копию файла G-code %1% перед запуском скрипта постобработки: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Постобработчику не удалось найти экспортированный файл G-code" # AI Translated @@ -36344,7 +36839,9 @@ msgstr "" msgid "" "Reverse on even\n" "Did you know that Reverse on even feature can significantly improve the surface quality of your overhangs? However, it can cause wall inconsistencies so use carefully!" -msgstr "Реверс на чётных слояхСовет: настройка Реверс на чётных слоях может существенно улучшить качество нависающих поверхностей. Как и нарушить их однородность, так что используйте с осторожностью." +msgstr "" +"Реверс на чётных слоях\n" +"Совет: настройка Реверс на чётных слоях может существенно улучшить качество нависающих поверхностей. Как и нарушить их однородность, так что используйте с осторожностью." #: resources/data/hints.ini: [hint:Cut Tool] msgid "" @@ -36566,6 +37063,28 @@ msgstr "" "Предотвращение коробления материала\n" "Знаете ли вы, что при печати материалами, склонными к короблению, таких как ABS, повышение температуры подогреваемого стола может снизить эту вероятность?" +# AI Translated +# Needs human review: Not a known RAL name; translated literally. +#~ msgid "Dalmatian yellow" +#~ msgstr "Далматский жёлтый" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Капсантиново-фиолетовый" + +# AI Translated +# Needs human review: Source name unclear; translated literally. +#~ msgid "Olivestone" +#~ msgstr "Оливково-каменный" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Доступно в любом месте окна, даже при вводе текста в поле." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Глобальные сочетания клавиш работают и при вводе текста." + #~ msgid "Please choose the filament color" #~ msgstr "Изменение цвета" @@ -37074,10 +37593,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "ненастроенный инструмент" -# AI Translated -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "G-code, который выполняется в самом конце печати." - #~ msgid "Maximum X speed" #~ msgstr "Максимальная скорость перемещения по X" @@ -37093,28 +37608,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Python-плагины, вызываемые на каждом этапе нарезки для чтения и изменения промежуточных её данных (включая финальную постобработку G-code). Тестовая/экспериментальная функция." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Если включено, слайсер выводит G-code, в котором содержимое основной зоны центрировано относительно начала координат стола (0,0). За размещение копий и зеркальных отражений в физическом положении каждой зоны отвечает прошивка принтера. Включайте только на принтерах, прошивка которых сама применяет смещения зон в режиме копии/зеркала (например, режим дублирования IDEX в RepRapFirmware). Не действует в режиме «Основной»." - # AI Translated # Needs human review: 'pem-inversion defaults' is developer jargon (inverse of physical_extruder_map); check the wording. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Переопределение для стола: соответствие физических голов слотам материала (нумерация с 1). Пустое значение означает значения по умолчанию, полученные обращением карты физических экструдеров (pem)." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Ось, вокруг которой поворачивается сетка перед нарезкой. Это наклон ленточного принтера: изометрический (без искажений) поворот, который также определяет отображение стола и наклон направления силы тяжести для поддержек и который обратное преобразование G-code отменяет перед сдвигом/масштабированием в машинную систему координат и переназначением осей. Обычно портал наклонён вокруг X (лента движется вдоль Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Настройка для экспертов: задаёт угол наклона машинной системы координат (сдвиг/масштаб G-code) независимо от угла поворота перед нарезкой. Если отключено, преобразование в машинную систему координат выводится из угла наклона ленты, так что один угол управляет обоими этапами. Включайте только для компенсации принтера, у которого физический наклон портала отличается от поворота при нарезке." - -# AI Translated -# Перенёс упоминание главенства этой настройки в настройку выше. -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Максимальное отклонение сегментов от модели. Чем меньше, тем выше точность и размер файла G-code." - #~ msgid " not in range " #~ msgstr " вне диапазона " diff --git a/localization/i18n/sv/OrcaSlicer_sv.po b/localization/i18n/sv/OrcaSlicer_sv.po index 50819ceaa4..bd4f298798 100644 --- a/localization/i18n/sv/OrcaSlicer_sv.po +++ b/localization/i18n/sv/OrcaSlicer_sv.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -823,18 +823,22 @@ msgstr "Markering" msgid "Plate" msgstr "Platta" +# AI Translated +# Needs human review: Glossary has no Swedish rendering for Distribute; matches the existing 'Justera/Fördela'. msgid "Distribute" -msgstr "" +msgstr "Fördela" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Koordinatsystem som används för transformeringar." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Referens för justering" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Välj minst 3 delar eller objekt" # AI Translated msgid "Align left" @@ -887,8 +891,9 @@ msgstr "Fördela i höjdled" msgid "Drop" msgstr "Släpp" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Flytta markeringen längs Z så att dess lägsta punkt når byggplattan." # AI Translated msgid "Absolute" @@ -1931,7 +1936,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Formens linje (%1%) innehåller något som inte stöds: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Ogiltigt tillstånd, rapportera stegen för att återskapa det på GitHub" # AI Translated @@ -1939,11 +1944,11 @@ msgid "No embossed file" msgstr "Ingen präglad fil" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "SVG-fil saknas i den präglade formen" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Data för SVG-filen saknas" # AI Translated @@ -2335,17 +2340,21 @@ msgstr "Öppnar monterings-gizmot" msgid "Leaving Assembly gizmo" msgstr "Lämnar monterings-gizmot" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Delar av ett klippt objekt kan inte flyttas" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Justering mot plattan är bara tillgänglig i X och Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Avaktivera automatiskt nedsläpp för de valda objekten för att flytta dem i Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Alla valda objekt måste ligga på samma platta" msgid "Shift+" msgstr "Shift+" @@ -5438,7 +5447,7 @@ msgstr "Spara projekt och starta om programmet." msgid "Unknown C++ exception." msgstr "Okänt C++-undantag." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Processera G-Code från Föregående fil…" msgid "Slicing complete" @@ -7126,8 +7135,10 @@ msgstr "Axlar" msgid "Gridlines" msgstr "Rutnät" +# AI Translated +# Needs human review: Glossary has no Swedish rendering for Focus mode yet; check Fokusläge fits the view-mode name. msgid "Focus mode" -msgstr "" +msgstr "Fokusläge" msgid "Labels" msgstr "Etiketter" @@ -7190,7 +7201,7 @@ msgid "Size:" msgstr "Storlek:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Konflikter mellan G-code-banor hittades på lager %d, Z = %.2lfmm. Placera de objekt som krockar längre ifrån varandra (%s <-> %s)." @@ -11889,11 +11900,13 @@ msgstr "Visa förinställningar som inte stöds" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Visa inkompatibla förinställningar och förinställningar som inte stöds i rullgardinslistorna för skrivare och filament. Dessa förinställningar kan inte väljas." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Exportera statistik med G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Om det är aktiverat skrivs statistiken även som JSON bredvid G-code-filen vid export, som .statistics.json, och en exporterad beredd 3MF-fil innehåller den: utskriftstid, totaler för filament och linjetyper, samt samma sak per lager och per objekt." # AI Translated msgid "Experimental Features" @@ -12793,6 +12806,10 @@ msgstr "Det gick inte att ladda upp filen till skrivarens lagring. Försök igen msgid "Send Failed" msgstr "Sändningen misslyckades" +# AI Translated +msgid "No available printers" +msgstr "Inga tillgängliga skrivare" + msgid "The name length exceeds the limit." msgstr "Namnlängden överskrider gränsen." @@ -14844,8 +14861,8 @@ msgid "Left mouse" msgstr "Vänster musknapp" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Tillgängligt överallt i fönstret, även när du skriver i ett textfält." +msgid "Available anywhere in the window." +msgstr "Tillgängligt var som helst i fönstret." # AI Translated msgid "Run favorite 1 to 10" @@ -14957,10 +14974,6 @@ msgstr "%s är tilldelat till %s. Vill du tilldela det till %s i stället?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Standardkortkommandot %s är tilldelat till %s. Vill du tilldela det till %s i stället?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Globala kortkommandon gäller även när du skriver." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "En tangent som skriver ett tecken kan inte vara ett globalt kortkommando." @@ -15442,9 +15455,10 @@ msgstr "modifieraren \"%1%\" för \"%2%\" (%3% totalt) hade ingen effekt på sö msgid "Seam placement may differ from expected." msgstr "Sömmens placering kan skilja sig från det förväntade." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Det gick inte att skriva G-code-statistiken till %1%." # AI Translated msgid "Internal Bridge" @@ -19202,6 +19216,14 @@ msgstr "Exkludera objekt" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Aktivera det här alternativet för att lägga till kommandot EXCLUDE OBJECT i G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Konturtolerans" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Största avvikelse för objektkonturen som skrivs till EXCLUDE_OBJECT_DEFINE från den ursprungliga konturen. Större värden ger färre punkter, vilket hjälper fast programvara som hänger sig vid tolkning av G-code med många objekt. 0 behåller alla punkter." + # AI Translated msgid "Verbose G-code" msgstr "Utförlig G-code" @@ -22784,11 +22806,13 @@ msgstr "Mata ut katalog" msgid "This is the output directory for exported files." msgstr "Mata ut katalogen för exporterade filer." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Exportera statistik" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Skriv statistiken för varje beredd platta som JSON, som plate_N.statistics.json bredvid dess G-code i utdatamappen och inuti 3MF-filen från --export-3mf: utskriftstid, totaler för filament och linjetyper, samt samma sak per lager och per objekt." msgid "Debug level" msgstr "Felsökningsnivå" @@ -25409,7 +25433,7 @@ msgstr "test av %s startar..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "test av %s: IP uppslagen = %s" # AI Translated @@ -33073,1231 +33097,1647 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "Den aktuella filamentlistan innehåller inte %s. Ett projektfilament som det blandade filamentet kräver skapas automatiskt efter uppdelningen." msgstr[1] "Den aktuella filamentlistan innehåller inte %s. Projektfilament som det blandade filamentet kräver skapas automatiskt efter uppdelningen." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Färgväljare" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Grundfärger" +# AI Translated +# Needs human review: Glossary has no Swedish rendering for Palette; check 'palett' (also Paletter). #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca-palett" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Klassisk" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Gradienter" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Enfärgad" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Gradient" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Gradientstart" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Gradientslut" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Gradientfärg" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Lägg till färg" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Ta bort färg" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Färgmättnad" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Ursprunglig färg" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Spara aktuell färg" +# AI Translated +# Needs human review: Glossary has no Swedish rendering for Palette; check 'Paletter'. msgid "Palettes" -msgstr "" +msgstr "Paletter" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Sök färger" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Filtrera färger" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Inga matchande färger" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Hexfärg" # AI Translated msgid "Opacity" msgstr "Opacitet" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Opacitet i procent" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Spara färg" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Ange en komplett hexadecimal färg" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Det aktuella flerfärgsvalet behålls tills du väljer en annan färg." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Upp till %d färger stöds." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Karmosinröd" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Orangeröd" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Tomatröd" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Orange" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Mörkorange" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Guld" +# AI Translated +# Needs human review: CSS color; check Träbrun conveys burlywood (light tan wood). msgid "Burly wood" -msgstr "" +msgstr "Träbrun" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Aprikosbeige" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Dimrosa" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Ljusgul" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Citronchiffong" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Beige" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Ljus gullrisgul" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Blek gullrisgul" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Khaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Mörk khaki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Persikokräm" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mockasin" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papayakräm" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Blancherad mandel" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antikvit" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navajovit" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Vete" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Gullrisgul" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Choklad" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Tegelröd" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Sienna" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Sadelbrun" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Brun" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Rosabrun" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Lax" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Ljus lax" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Mörk lax" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Sandbrun" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Korall" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Ljus korall" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Indianröd" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Mörkröd" +# AI Translated +# Needs human review: Kept as Maroon (loan word); Rödbrun/Brunröd are taken by RAL names. msgid "Maroon" -msgstr "" +msgstr "Maroon" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Gröngul" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Gulgrön" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Gräsmattegrön" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Limegrön" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Vårgrön" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Mellan vårgrön" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Lime" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Skogsgrön" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Mörkgrön" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Armégrön" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Oliv" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Mörk olivgrön" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Blekgrön" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Ljusgrön" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Mellan havsgrön" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Havsgrön" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Mörk havsgrön" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Kadettblå" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Mellan akvamarin" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turkos" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Mellanturkos" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Mörkturkos" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Blekturkos" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Ljuscyan" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Mintkräm" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Honungsmelon" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Akvamarin" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Ljus havsgrön" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Mörkcyan" +# AI Translated +# Needs human review: Rendered Petrol; check it reads as teal. msgid "Teal" -msgstr "" +msgstr "Petrol" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Mörk skiffergrå" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Ljus skiffergrå" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Skiffergrå" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Djup himmelsblå" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodgerblå" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Himmelsblå" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Ljus himmelsblå" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Ljusblå" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Pulverblå" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Ljus stålblå" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Stålblå" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Blåklintsblå" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Kungsblå" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Mellanblå" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Midnattsblå" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Mörkblå" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Marinblå" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Skifferblå" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Mörk skifferblå" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Mellan skifferblå" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Blåviolett" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Indigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Mörkviolett" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Mörk orkidé" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Mellan orkidé" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orkidé" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Violett" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Mellanlila" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Lila" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebecca-lila" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Mellan violettröd" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Blek violettröd" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Djuprosa" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Knallrosa" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Ljusrosa" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Rosa" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Plommon" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Tistel" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuchsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Mörk magenta" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Linne" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Gammal spets" +# AI Translated msgid "Sea shell" -msgstr "" +msgstr "Snäckskal" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Elfenben" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Blomvit" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavendelrosa" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Spökvit" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Alice-blå" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavendel" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Rökvit" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Svart" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Korallglöd" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Havsanemon" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Djup avgrund" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Hummerröd" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Sandlera" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Drivved" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Havtorn" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Solnedgångsrev" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Tigerkorall" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Rosa korall" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Snäckskalsglöd" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Sand" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Gyllene tång" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Solbelyst dyn" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Bärnstensnautilus" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Havscitron" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Blek sjöstjärna" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Springflod" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Limealg" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Ålgräs" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neonplankton" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Tångskog" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Smaragdvåg" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Valskugga" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Havssköldpadda" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagun" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Tropisk ström" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Midnattsgrav" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Mörk tång" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Kristallbränning" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Turkos vik" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Himmel över revet" +# AI Translated +# Needs human review: Ocean-themed color name; check 'Grund himmel' reads as a color. msgid "Shallow sky" -msgstr "" +msgstr "Grund himmel" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektrisk blå" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Delfin" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Havsdjup" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Val" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Indigoavgrund" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Sjöborre" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Lavendelkorall" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Violett tidvatten" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Djuphavsorkidé" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neonmanet" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuchsiakorall" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Rosa manet" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Skum" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Snäckskalsvit" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Kiselgrå" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Stormmoln" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Bläckssvart" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Grönbeige" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Sandgul" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Signalgul" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Gyllengul" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Honungsgul" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Majsgul" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Påskliljegul" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Brunbeige" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Citrongul" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Ostronvit" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Ljust elfenben" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Zinkgul" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Gråbeige" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Olivgul" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Rapsgul" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Trafikgul" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Ockragul" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Trafikorangegul" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Curry" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Melongul" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Ginstgul" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Dahliagul" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pastellgul" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Pärlbeige" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Pärlguld" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Solgul" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Gulorange" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Djuporange" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Cinnober" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Pärlorange" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Ren orange" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Lysorange" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Ljus lysorange" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Ljus rödorange" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Trafikorange" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Signalorange" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Laxorange" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Pärlrosa" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Kopparorange" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Signalbrun" +# AI Translated +# Needs human review: Odd RAL name; translated literally as Granorange. msgid "Fir orange" -msgstr "" +msgstr "Granorange" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Signalröd" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Lysröd" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karminröd" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Pärlkarminröd" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Ren röd" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Djup lysröd" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Vinbärsröd" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Pärlrubinröd" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Eldröd" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Rubinröd" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Lilaröd" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Vinröd" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Svartröd" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oxidröd" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Brunröd" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Tallröd" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Tomatröd" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Antikrosa" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Korallröd" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Ros" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Jordgubbsröd" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Trafikröd" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Laxrosa" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Lysrosa" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Ljus lysröd" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Hallonröd" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Orientröd" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Pärlrubin" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Rödlila" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Rödviolett" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Ljungviolett" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordeauxviolett" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Mahogny" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Grålila" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Signalviolett" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Grangrön" +# AI Translated +# Needs human review: RAL name; check the Swedish form. msgid "Sabine grey" -msgstr "" +msgstr "Sabinegrå" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Pärlviolett" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Pärlbjörnbär" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Grönblå" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarinblå" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Safirblå" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Svartblå" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Signalblå" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Briljantblå" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Gråblå" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azurblå" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Gentianablå" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Koboltblå" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Duvblå" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Trafikblå" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Turkosblå" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Capriblå" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Havsblå" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Vattenblå" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Nattblå" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Avlägsen blå" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pastellblå" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Pärlgentianablå" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Pärlmidnattsblå" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patinagrön" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Smaragdgrön" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Lövgrön" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Olivgrön" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Blågrön" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Mossgrön" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Gråoliv" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Tallgrön" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Tallbrun" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Gräsgrön" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Resedagrön" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Brungrön" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Vassgrön" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Svartgrön" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Turkosgrön" +# AI Translated msgid "May green" -msgstr "" +msgstr "Majgrön" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Kromoxidgrön" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Trafikgrön" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Ormbunksgrön" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opalgrön" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Mintgrön" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Bronsgrön" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Pärlgrön" +# AI Translated +# Needs human review: RAL name; check the Swedish form. msgid "Sax turquoise" -msgstr "" +msgstr "Saxturkos" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Pärlturkos" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Pärljade" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Ren grön" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Lysgrön" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Ekorrgrå" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Silvergrå" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Olivgrå" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Mossgrå" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Signalgrå" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Musgrå" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Beigegrå" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Khakigrå" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Gröngrå" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Presenninggrå" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Järngrå" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Basaltgrå" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Brungrå" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Skiffergrå" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antracitgrå" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Ljusgrå" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umbragrå" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Betonggrå" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafitgrå" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Granitgrå" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Stengrå" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Kiselgrå" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Cementgrå" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Gulgrå" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platinagrå" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Dammgrå" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Agatgrå" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Kvartsgrå" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Fönstergrå" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Trafikgrå A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Trafikgrå B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Sidengrå" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegrå 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegrå 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegrå 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Pärlmusgrå" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Grönbrun" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Ockrabrun" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Lerbrun" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Kopparbrun" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Chokladbrun" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Olivbrun" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Nötbrun" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Rödbrun" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sepiabrun" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Kastanjebrun" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Mahognybrun" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Gråbrun" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Pärlkoppar" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Beigebrun" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Pärlmockabrun" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Jordbrun" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Pärlbrun" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Kräm" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Gråvit" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Signalvit" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Signalsvart" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Kolsvart" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Vitt aluminium" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Grått aluminium" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Ren vit" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Grafitsvart" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Trafikvit" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Trafiksvart" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papyrusvit" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Pärl-ljusgrå" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metall: Silver" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metall: Mässing" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metall: Guld" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metall: Koppar" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metall: Brons" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Natur: Pärla" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Natur: Regnbåge" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Natur: Klar himmel" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Natur: Solnedgång" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Trä: Mörkt" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Trä: Medel" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Trä: Ljust" # AI Translated msgid "Alternate nozzles:" @@ -34773,13 +35213,25 @@ msgstr "Ta bort från Mina texturer" msgid "Built-in" msgstr "Inbyggda" +# AI Translated +msgid "My textures" +msgstr "Mina texturer" + # AI Translated msgid "No textures found." msgstr "Inga texturer hittades." # AI Translated -msgid "My textures" -msgstr "Mina texturer" +msgid "Texture libraries" +msgstr "Texturbibliotek" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Utforska fler texturbibliotek" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Öppnar OrcaCloud på startsidan för att bläddra bland insticksmoduler." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -35182,11 +35634,13 @@ msgstr "Mappas av modellens egen UV-layout, som redan är placeringen - en kopia msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Hur bred en kopia av texturen är på modellen. Mindre värden upprepar mönstret oftare och gör detaljerna finare; med Sida vid sida avstängt är detta storleken på den enda kopian." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Större" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Mindre" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -35262,11 +35716,15 @@ msgstr "Blandade färger" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Det högsta antalet blandade filament som en inbakning får lägga till. De väljs ur texturens färger, och endast de som inbakningen faktiskt använder skapas." +# AI Translated +# Needs human review: Bare label in the app; check Få/Många fit their context. msgid "Few" -msgstr "" +msgstr "Få" +# AI Translated +# Needs human review: Bare label in the app; check Få/Många fit their context. msgid "Many" -msgstr "" +msgstr "Många" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -35622,11 +36080,15 @@ msgstr "Ombyggnad av mesh" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Triangelstorleken som hela modellen byggs om med, i millimeter. Förskjutning fungerar bäst på en jämn mesh; det är detta som skapar en sådan av en ojämn import." +# AI Translated +# Needs human review: Bare label in the app; check Före/Efter fit their context. msgid "Before" -msgstr "" +msgstr "Före" +# AI Translated +# Needs human review: Bare label in the app; check Före/Efter fit their context. msgid "After" -msgstr "" +msgstr "Efter" # AI Translated msgid "Keep sharp edges" @@ -37498,6 +37960,10 @@ msgstr "Skript" msgid "Slicing Pipeline" msgstr "Beredningspipeline" +# AI Translated +msgid "Resource Texture" +msgstr "Resurstextur" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Insticksmodulens konfigurationsgränssnitt var tomt. Standardredigeraren visas." @@ -37645,6 +38111,30 @@ msgstr "Insticksmodulens mapp innehåller både .py- och .whl-startfiler" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Insticksmodulens mapp innehåller ingen .py- eller .whl-startfil" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Mappen för resurstexturer är inte angiven" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Mappen för resurstexturer kunde inte lösas upp" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Sökvägen för resurstexturer är ingen mapp" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Insticksmodulens mapp kunde inte lösas upp" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Mappen för resurstexturer ligger utanför insticksmodulens mapp" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Mappen för resurstexturer kunde inte läsas" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -38105,7 +38595,7 @@ msgstr "Det gick inte att läsa in konfigurationsfilen \"%1%\": %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Inte en G-code-fil som genererats av %1%." # AI Translated @@ -38225,7 +38715,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Det gick inte att skapa en tillfällig kopia av G-code-filen %1% innan ett efterbearbetningsskript kördes: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Efterbearbetningen hittar inte den exporterade G-code-filen" # AI Translated @@ -38609,6 +39099,28 @@ msgstr "" "Undvik vridning\n" "Visste du att när du skriver ut material som är benägna att vrida, såsom ABS, kan en lämplig ökning av värmebäddens temperatur minska sannolikheten för vridning?" +# AI Translated +# Needs human review: Possibly meant Daffodil yellow (RAL 1007); translated literally. +#~ msgid "Dalmatian yellow" +#~ msgstr "Dalmatinergul" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Capsanthinviolett" + +# AI Translated +# Needs human review: Probably RAL Olive grey; translated as Olivgrå. +#~ msgid "Olivestone" +#~ msgstr "Olivgrå" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Tillgängligt överallt i fönstret, även när du skriver i ett textfält." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Globala kortkommandon gäller även när du skriver." + # AI Translated #~ msgid "Please choose the filament color" #~ msgstr "Välj filamentfärg" @@ -39125,10 +39637,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "inget konfigurerat verktyg" -# AI Translated -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Lägg till slut-G-code när hela utskriften avslutas." - #~ msgid "Maximum X speed" #~ msgstr "Max X hastighet" @@ -39145,26 +39653,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Python-insticksmoduler som anropas vid varje steg i beredningspipelinen för att läsa och ändra mellanliggande beredningsdata, inklusive ett avslutande efterbearbetningssteg för G-code. Forskning/experimentellt." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "När detta är aktiverat genererar beredningsprogrammet G-code med den primära zonens innehåll centrerat kring byggplattans origo (0,0). Skrivarens fasta programvara ansvarar för att placera kopior/speglingar på varje fysisk zonposition. Aktivera endast på skrivare vars fasta programvara tillämpar egna zonförskjutningar i läget Kopia/Spegel (t.ex. dupliceringsläget för IDEX i RepRapFirmware). Har ingen effekt i läget Primär." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Åsidosättning per platta som mappar fysiska huvuden till filamentplatser (1-baserade). Tomt innebär att standardvärdena för pem-inversion används." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Axeln som meshen roteras kring före beredning. Detta är bandskrivarens lutning: en isometrisk (förvrängningsfri) rotation som även styr renderingen av byggplattan och tyngdkraftslutningen för support, och som G-code-baktransformationen inverterar före skjuvningen/skalningen och ommappningen till maskinkoordinatsystemet. X är den typiska portallutningen (bandet rör sig längs Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Expertinställning: ange lutningsvinkeln för maskinkoordinatsystemet (G-code-skjuvning/skalning) oberoende av rotationsvinkeln före beredning. När detta är inaktiverat härleds transformationen till maskinkoordinatsystemet från bandets lutningsvinkel, så att en enda vinkel styr båda stegen. Aktivera endast för att kompensera för en maskin vars fysiska portallutning skiljer sig från beredningsrotationen." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Den största avvikelse som tillåts när upplösningen minskas för inställningen 'Maximal väggupplösning'. Om du ökar den blir utskriften mindre exakt, men G-code:n blir mindre. 'Maximal väggavvikelse' begränsar 'Maximal väggupplösning', så om de två står i konflikt har 'Maximal väggavvikelse' företräde." - #~ msgid " not in range " #~ msgstr " inte inom intervallet " diff --git a/localization/i18n/th/OrcaSlicer_th.po b/localization/i18n/th/OrcaSlicer_th.po index c0b34bc848..0f076d2209 100644 --- a/localization/i18n/th/OrcaSlicer_th.po +++ b/localization/i18n/th/OrcaSlicer_th.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-06-19 13:40+0700\n" "Last-Translator: Icezaza\n" "Language-Team: Thai\n" @@ -799,18 +799,21 @@ msgstr "การเลือก" msgid "Plate" msgstr "เพลต" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "กระจาย" # AI Translated msgid "Coordinate system used for transform actions." msgstr "ระบบพิกัดที่ใช้สำหรับการแปลงรูป" +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "ตัวอ้างอิงสำหรับการจัดแนว" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "เลือกชิ้นส่วนหรือวัตถุอย่างน้อย 3 รายการ" # AI Translated msgid "Align left" @@ -863,8 +866,9 @@ msgstr "กระจายในแนวบน-ล่าง" msgid "Drop" msgstr "วางลงฐานพิมพ์" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "เลื่อนส่วนที่เลือกไปตามแกน Z ให้จุดต่ำสุดแตะฐานพิมพ์" # AI Translated msgid "Absolute" @@ -1747,7 +1751,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "เส้นโครงร่างของรูปร่าง (%1%) ประกอบด้วยที่ไม่รองรับ: %2%" # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "สถานะไม่ถูกต้อง โปรดรายงานขั้นตอนการทำให้เกิดซ้ำบน GitHub" # AI Translated @@ -1755,11 +1759,11 @@ msgid "No embossed file" msgstr "ไม่มีไฟล์ลายนูน" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "ไม่มีไฟล์ SVG ในรูปทรงลายนูน" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "ไม่มีข้อมูลของไฟล์ SVG" msgid "Face the camera" @@ -2081,17 +2085,21 @@ msgstr "เข้าสู่กิซโมการประกอบ" msgid "Leaving Assembly gizmo" msgstr "ออกจากกิซโมการประกอบ" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "ไม่สามารถย้ายชิ้นส่วนของวัตถุที่ถูกตัดได้" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "การจัดแนวกับเพลตทำได้เฉพาะแกน X และ Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "ปิดการวางอัตโนมัติของวัตถุที่เลือกเพื่อย้ายในแกน Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "วัตถุที่เลือกทั้งหมดต้องอยู่บนเพลตเดียวกัน" msgid "Shift+" msgstr "Shift+" @@ -4963,7 +4971,7 @@ msgstr "โปรดบันทึกโปรเจกต์และเริ msgid "Unknown C++ exception." msgstr "ข้อยกเว้น C++ ที่ไม่ทราบสาเหตุ" -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "กำลังประมวลผล G-code จากไฟล์ก่อนหน้า..." msgid "Slicing complete" @@ -6501,8 +6509,9 @@ msgstr "แกน" msgid "Gridlines" msgstr "เส้นกริด" +# AI Translated msgid "Focus mode" -msgstr "" +msgstr "โหมดโฟกัส" msgid "Labels" msgstr "ป้ายชื่อ" @@ -6564,7 +6573,7 @@ msgid "Size:" msgstr "ขนาด:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "พบความขัดแย้งของเส้นทาง G-code ที่เลเยอร์ %d, Z = %.2lfmm โปรดแยกวัตถุที่ขัดแย้งกันให้ไกลออกไป (%s <-> %s)" @@ -10863,11 +10872,14 @@ msgstr "แสดงค่าที่ตั้งไว้ล่วงหน้ msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "แสดงค่าที่ตั้งไว้ล่วงหน้าที่ไม่เข้ากันหรือไม่รองรับในรายการเลือกเครื่องพิมพ์และเส้นพลาสติก ไม่สามารถเลือกค่าที่ตั้งไว้ล่วงหน้าเหล่านี้ได้" +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "ส่งออกสถิติพร้อมกับ G-code" +# AI Translated +# Needs human review: "feature" rendered as line type (ประเภทเส้น / Loại đường); check this matches the per-feature totals in the exported JSON msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "เมื่อเปิดใช้งาน การส่งออกไฟล์ G-code จะเขียนสถิติของไฟล์นั้นเป็น JSON ไว้ข้างกันด้วย ในชื่อ .statistics.json และไฟล์ 3MF ที่สไลซ์แล้วซึ่งส่งออกจะมีสถิตินี้อยู่ภายใน ได้แก่ เวลาพิมพ์ ยอดรวมของเส้นพลาสติกและประเภทเส้น และข้อมูลเดียวกันนี้แยกตามเลเยอร์และตามวัตถุ" # AI Translated msgid "Experimental Features" @@ -11731,6 +11743,10 @@ msgstr "ไม่สามารถอัปโหลดไฟล์ไปยั msgid "Send Failed" msgstr "ส่งล้มเหลว" +# AI Translated +msgid "No available printers" +msgstr "ไม่มีเครื่องพิมพ์ที่พร้อมใช้งาน" + msgid "The name length exceeds the limit." msgstr "ชื่อมีความยาวเกินขีดจำกัด" @@ -13582,8 +13598,8 @@ msgid "Left mouse" msgstr "เมาส์ซ้าย" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "ใช้ได้ทุกที่ในหน้าต่าง แม้ขณะพิมพ์ในช่องข้อความ" +msgid "Available anywhere in the window." +msgstr "ใช้ได้ทุกที่ในหน้าต่าง" # AI Translated msgid "Run favorite 1 to 10" @@ -13695,10 +13711,6 @@ msgstr "%s ถูกกำหนดให้กับ %s แล้ว กำห msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "%s ซึ่งเป็นค่าเริ่มต้นถูกกำหนดให้กับ %s แล้ว กำหนดใหม่ให้กับ %s หรือไม่" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "แป้นพิมพ์ลัดส่วนกลางจะทำงานแม้ขณะพิมพ์ข้อความ" - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "ปุ่มที่พิมพ์ตัวอักษรไม่สามารถเป็นแป้นพิมพ์ลัดส่วนกลางได้" @@ -14143,9 +14155,10 @@ msgstr "ตัวปรับแต่ง \"%1%\" ของ \"%2%\" (ทั้ msgid "Seam placement may differ from expected." msgstr "ตำแหน่งรอยตะเข็บอาจแตกต่างจากที่คาดไว้" +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "เขียนสถิติ G-code ไปยัง %1% ไม่สำเร็จ" msgid "Internal Bridge" msgstr "สะพานภายใน" @@ -17621,6 +17634,14 @@ msgstr "ไม่รวมวัตถุ" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "เปิดใช้งานตัวเลือกนี้เพื่อเพิ่มคำสั่ง EXCLUDE OBJECT ใน G-code" +# AI Translated +msgid "Outline tolerance" +msgstr "ค่าความเผื่อเส้นขอบ" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "ค่าเบี่ยงเบนสูงสุดของเส้นขอบวัตถุที่เขียนลงใน EXCLUDE_OBJECT_DEFINE จากเส้นขอบเดิม ค่าที่มากขึ้นจะให้จำนวนจุดน้อยลง ซึ่งช่วยเฟิร์มแวร์ที่ค้างขณะแยกวิเคราะห์ G-code ที่มีวัตถุจำนวนมาก ค่า 0 คือเก็บทุกจุดไว้" + msgid "Verbose G-code" msgstr "G-code แบบละเอียด" @@ -20894,11 +20915,14 @@ msgstr "ไดเร็กทอรีเอาต์พุต" msgid "This is the output directory for exported files." msgstr "ไดเร็กทอรีเอาต์พุตสำหรับไฟล์ที่ส่งออก" +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "ส่งออกสถิติ" +# AI Translated +# Needs human review: "feature" rendered as line type (ประเภทเส้น / Loại đường); check this matches the per-feature totals in the exported JSON msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "เขียนสถิติของแต่ละเพลตที่สไลซ์แล้วเป็น JSON ชื่อ plate_N.statistics.json ไว้ข้างไฟล์ G-code ในโฟลเดอร์ปลายทาง และภายใน 3MF ของ --export-3mf ได้แก่ เวลาพิมพ์ ยอดรวมของเส้นพลาสติกและประเภทเส้น และข้อมูลเดียวกันนี้แยกตามเลเยอร์และตามวัตถุ" msgid "Debug level" msgstr "ระดับการแก้ไขข้อบกพร่อง" @@ -23309,7 +23333,7 @@ msgstr "เริ่มทดสอบ %s..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "ทดสอบ %s แปลง IP ได้ = %s" # AI Translated @@ -30676,1231 +30700,1641 @@ msgid "The current filament list does not contain %s. A project filament require msgid_plural "The current filament list does not contain %s. Project filaments required by the mixed filament will be created automatically after decomposition." msgstr[0] "รายการเส้นพลาสติกปัจจุบันไม่มี %s เส้นพลาสติกโครงการที่เส้นพลาสติกผสมต้องใช้จะถูกสร้างขึ้นโดยอัตโนมัติหลังจากแยกสี" +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "ตัวเลือกสี" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "สีพื้นฐาน" +# AI Translated #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "จานสี Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL คลาสสิก" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "การไล่ระดับสี" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "สีเดียว" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "ไล่ระดับสี" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "จุดเริ่มต้นการไล่ระดับสี" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "จุดสิ้นสุดการไล่ระดับสี" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "สีของการไล่ระดับสี" +# AI Translated msgid "Add color" -msgstr "" +msgstr "เพิ่มสี" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "ลบสี" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "ความอิ่มตัว" +# AI Translated msgid "Original color" -msgstr "" +msgstr "สีเดิม" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "บันทึกสีปัจจุบัน" +# AI Translated msgid "Palettes" -msgstr "" +msgstr "จานสี" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "ค้นหาสี" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "กรองสี" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "ไม่มีสีที่ตรงกัน" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "สีเลขฐานสิบหก" # AI Translated msgid "Opacity" msgstr "ความทึบแสง" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "เปอร์เซ็นต์ความทึบแสง" +# AI Translated msgid "Save color" -msgstr "" +msgstr "บันทึกสี" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "ป้อนสีเลขฐานสิบหกให้ครบถ้วน" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "การเลือกหลายสีปัจจุบันจะคงไว้จนกว่าคุณจะเลือกสีอื่น" +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "รองรับสูงสุด %d สี" +# AI Translated msgid "Crimson" -msgstr "" +msgstr "แดงคริมสัน" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "แดงส้ม" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "แดงมะเขือเทศ" +# AI Translated msgid "Orange" -msgstr "" +msgstr "ส้ม" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "ส้มเข้ม" +# AI Translated msgid "Gold" -msgstr "" +msgstr "ทอง" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "น้ำตาลไม้อ่อน" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "ส้มครีม" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "ชมพูหมอก" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "เหลืองอ่อน" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "ครีมเลมอน" +# AI Translated msgid "Beige" -msgstr "" +msgstr "เบจ" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "เหลืองขมิ้นอ่อน" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "เหลืองขมิ้นซีด" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "กากี" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "กากีเข้ม" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "พีชอ่อน" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "เหลืองหนังกวาง" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "ครีมมะละกอ" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "อัลมอนด์ลอกเปลือก" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "ขาวโบราณ" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "ขาวนาวาโฮ" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "ข้าวสาลี" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "เหลืองขมิ้น" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "ช็อกโกแลต" +# AI Translated msgid "Peru" -msgstr "" +msgstr "น้ำตาลเปรู" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "อิฐทนไฟ" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "น้ำตาลเซียนนา" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "น้ำตาลอานม้า" +# AI Translated msgid "Brown" -msgstr "" +msgstr "น้ำตาล" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "น้ำตาลกุหลาบ" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "แซลมอน" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "แซลมอนอ่อน" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "แซลมอนเข้ม" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "น้ำตาลทราย" +# AI Translated msgid "Coral" -msgstr "" +msgstr "ปะการัง" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "ปะการังอ่อน" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "แดงอินเดียน" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "แดงเข้ม" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "แดงเลือดหมู" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "เหลืองเขียว" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "เขียวเหลือง" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "ชาร์เทรอส" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "เขียวสนามหญ้า" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "เขียวมะนาว" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "เขียวฤดูใบไม้ผลิ" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "เขียวฤดูใบไม้ผลิกลาง" +# AI Translated msgid "Lime" -msgstr "" +msgstr "ไลม์" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "เขียวป่า" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "เขียวเข้ม" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "เขียวมะกอกหม่น" +# AI Translated msgid "Olive" -msgstr "" +msgstr "มะกอก" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "เขียวมะกอกเข้ม" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "เขียวซีด" +# AI Translated msgid "Light green" -msgstr "" +msgstr "เขียวอ่อน" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "เขียวทะเลกลาง" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "เขียวทะเล" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "เขียวทะเลเข้ม" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "น้ำเงินแคเด็ต" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "อความารีนกลาง" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "เทอร์ควอยซ์" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "เทอร์ควอยซ์กลาง" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "เทอร์ควอยซ์เข้ม" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "เทอร์ควอยซ์ซีด" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "อควา" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "ไซแอนอ่อน" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "ครีมมินต์" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "ฮันนีดิว" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "อความารีน" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "เขียวทะเลอ่อน" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "ไซแอนเข้ม" +# AI Translated msgid "Teal" -msgstr "" +msgstr "เขียวหัวเป็ด" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "เทาหินชนวนเข้ม" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "เทาหินชนวนอ่อน" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "เทาหินชนวน" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "ฟ้าท้องฟ้าเข้ม" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "น้ำเงินดอดเจอร์" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "ฟ้าท้องฟ้า" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "ฟ้าท้องฟ้าอ่อน" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "ฟ้าอ่อน" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "ฟ้าแป้ง" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "น้ำเงินเหล็กอ่อน" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "น้ำเงินเหล็ก" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "น้ำเงินคอร์นฟลาวเวอร์" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "น้ำเงินรอยัล" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "น้ำเงินกลาง" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "น้ำเงินเที่ยงคืน" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "น้ำเงินเข้ม" +# AI Translated msgid "Navy" -msgstr "" +msgstr "น้ำเงินกรมท่า" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "น้ำเงินหินชนวน" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "น้ำเงินหินชนวนเข้ม" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "น้ำเงินหินชนวนกลาง" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "ม่วงน้ำเงิน" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "คราม" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "ไวโอเล็ตเข้ม" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "กล้วยไม้เข้ม" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "กล้วยไม้กลาง" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "กล้วยไม้" +# AI Translated msgid "Violet" -msgstr "" +msgstr "ไวโอเล็ต" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "ม่วงกลาง" +# AI Translated msgid "Purple" -msgstr "" +msgstr "ม่วง" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "ม่วงเรเบกกา" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "แดงไวโอเล็ตกลาง" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "แดงไวโอเล็ตซีด" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "ชมพูเข้ม" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "ชมพูสด" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "ชมพูอ่อน" +# AI Translated msgid "Pink" -msgstr "" +msgstr "ชมพู" +# AI Translated msgid "Plum" -msgstr "" +msgstr "ม่วงบ๊วย" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "ม่วงธิสเซิล" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "ฟูเชีย" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "แมเจนตาเข้ม" +# AI Translated msgid "Linen" -msgstr "" +msgstr "ผ้าลินิน" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "ลูกไม้เก่า" +# AI Translated msgid "Sea shell" -msgstr "" +msgstr "เปลือกหอย" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "งาช้าง" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "ขาวดอกไม้" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "ลาเวนเดอร์อมชมพู" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "ขาวโกสต์" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "ฟ้าอลิซ" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "ลาเวนเดอร์" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "ขาวควัน" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "เกนส์โบโร" +# AI Translated msgid "Black" -msgstr "" +msgstr "ดำ" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "ปะการังเพลิง" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "ดอกไม้ทะเล" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "ห้วงเหวลึก" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "แดงกุ้งมังกร" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "ดินเหนียวปนทราย" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "ไม้ลอยน้ำ" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "ซีบัคธอร์น" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "แนวปะการังยามอาทิตย์ตก" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "ปะการังเสือ" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "ปะการังชมพู" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "ประกายเปลือกหอย" +# AI Translated msgid "Sand" -msgstr "" +msgstr "ทราย" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "สาหร่ายเคลป์สีทอง" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "เนินทรายยามแดด" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "นอติลุสอำพัน" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "มะนาวทะเล" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "ดาวทะเลซีด" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "น้ำเกิด" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "สาหร่ายเขียวมะนาว" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "หญ้าทะเล" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "แพลงก์ตอนนีออน" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "ป่าสาหร่ายเคลป์" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "คลื่นมรกต" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "เงาวาฬ" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "เต่าทะเล" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "ลากูน" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "กระแสน้ำเขตร้อน" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "ร่องลึกยามเที่ยงคืน" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "สาหร่ายเคลป์เข้ม" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "คลื่นคริสตัล" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "อ่าวเทอร์ควอยซ์" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "ท้องฟ้าเหนือแนวปะการัง" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "ท้องฟ้าน้ำตื้น" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "น้ำเงินอิเล็กทริก" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "โลมา" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "ห้วงลึกมหาสมุทร" +# AI Translated msgid "Whale" -msgstr "" +msgstr "วาฬ" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "ห้วงลึกสีคราม" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "เม่นทะเล" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "ปะการังลาเวนเดอร์" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "กระแสน้ำไวโอเล็ต" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "กล้วยไม้ทะเลลึก" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "แมงกะพรุนนีออน" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "ปะการังฟูเชีย" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "แมงกะพรุนชมพู" +# AI Translated msgid "Foam" -msgstr "" +msgstr "ฟองคลื่น" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "ขาวเปลือกหอย" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "เทาก้อนกรวด" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "เมฆพายุ" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "ดำหมึก" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "เบจเขียว" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "เหลืองทราย" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "เหลืองสัญญาณ" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "เหลืองทอง" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "เหลืองน้ำผึ้ง" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "เหลืองข้าวโพด" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "เหลืองแดฟโฟดิล" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "เบจน้ำตาล" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "เหลืองเลมอน" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "ขาวหอยนางรม" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "งาช้างอ่อน" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "เหลืองสังกะสี" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "เบจเทา" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "เหลืองมะกอก" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "เหลืองดอกเรพ" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "เหลืองจราจร" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "เหลืองออคเคอร์" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "เหลืองส้มจราจร" +# AI Translated msgid "Curry" -msgstr "" +msgstr "แกงกะหรี่" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "เหลืองเมลอน" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "เหลืองดอกบรูม" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "เหลืองดาห์เลีย" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "เหลืองพาสเทล" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "เบจมุก" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "ทองมุก" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "เหลืองอาทิตย์" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "ส้มเหลือง" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "ส้มเข้มจัด" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "แดงชาด" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "ส้มมุก" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "ส้มบริสุทธิ์" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "ส้มเรืองแสง" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "ส้มสดเรืองแสง" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "ส้มแดงสด" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "ส้มจราจร" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "ส้มสัญญาณ" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "ส้มแซลมอน" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "ชมพูมุก" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "ส้มทองแดง" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "น้ำตาลสัญญาณ" +# AI Translated msgid "Fir orange" -msgstr "" +msgstr "ส้มเฟอร์" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "แดงสัญญาณ" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "แดงเรืองแสง" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "แดงคาร์ไมน์" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "แดงคาร์ไมน์มุก" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "แดงบริสุทธิ์" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "แดงเข้มเรืองแสง" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "แดงเคอร์แรนต์" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "แดงทับทิมมุก" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "แดงเพลิง" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "แดงทับทิม" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "แดงม่วง" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "แดงไวน์" +# AI Translated msgid "Black red" -msgstr "" +msgstr "แดงดำ" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "แดงออกไซด์" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "แดงน้ำตาล" +# AI Translated +# Needs human review: Source name "Pine red" looks unusual for a RAL color; translated literally msgid "Pine red" -msgstr "" +msgstr "แดงต้นสน" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "แดงมะเขือเทศ" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "ชมพูโบราณ" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "แดงปะการัง" +# AI Translated msgid "Rose" -msgstr "" +msgstr "กุหลาบ" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "แดงสตรอว์เบอร์รี" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "แดงจราจร" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "ชมพูแซลมอน" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "กุหลาบเรืองแสง" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "แดงสดเรืองแสง" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "แดงราสเบอร์รี" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "แดงตะวันออก" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "ทับทิมมุก" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "ม่วงแดง" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "ไวโอเล็ตแดง" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "ไวโอเล็ตเฮเทอร์" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "ไวโอเล็ตบอร์โดซ์" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "มะฮอกกานี" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "ม่วงเทา" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "ไวโอเล็ตสัญญาณ" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "เขียวเฟอร์" +# AI Translated msgid "Sabine grey" -msgstr "" +msgstr "เทาซาบีน" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "ไวโอเล็ตมุก" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "แบล็กเบอร์รีมุก" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "น้ำเงินเขียว" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "น้ำเงินอัลตรามารีน" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "น้ำเงินไพลิน" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "น้ำเงินดำ" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "น้ำเงินสัญญาณ" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "น้ำเงินสดใส" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "น้ำเงินเทา" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "ฟ้าอาซูร์" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "น้ำเงินเจนเชียน" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "น้ำเงินโคบอลต์" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "น้ำเงินนกพิราบ" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "น้ำเงินจราจร" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "น้ำเงินเทอร์ควอยซ์" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "น้ำเงินคาปรี" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "น้ำเงินมหาสมุทร" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "ฟ้าสีน้ำ" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "น้ำเงินราตรี" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "ฟ้าไกล" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "ฟ้าพาสเทล" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "น้ำเงินเจนเชียนมุก" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "น้ำเงินเที่ยงคืนมุก" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "เขียวสนิม" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "เขียวมรกต" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "เขียวใบไม้" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "เขียวมะกอก" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "เขียวน้ำเงิน" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "เขียวมอส" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "มะกอกเทา" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "เขียวสน" +# AI Translated +# Needs human review: Source name "Pine brown" looks unusual for a RAL color; translated literally msgid "Pine brown" -msgstr "" +msgstr "น้ำตาลสน" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "เขียวหญ้า" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "เขียวเรเซดา" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "เขียวน้ำตาล" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "เขียวต้นอ้อ" +# AI Translated msgid "Black green" -msgstr "" +msgstr "เขียวดำ" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "เขียวเทอร์ควอยซ์" +# AI Translated msgid "May green" -msgstr "" +msgstr "เขียวเดือนพฤษภาคม" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "เขียวโครมออกไซด์" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "เขียวจราจร" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "เขียวเฟิร์น" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "เขียวโอปอล" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "เขียวมินต์" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "เขียวบรอนซ์" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "เขียวมุก" +# AI Translated +# Needs human review: Unusual source name ("Sax turquoise"); translated literally msgid "Sax turquoise" -msgstr "" +msgstr "เทอร์ควอยซ์แซกซ์" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "เทอร์ควอยซ์มุก" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "หยกมุก" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "เขียวบริสุทธิ์" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "เขียวเรืองแสง" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "เทากระรอก" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "เทาเงิน" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "เทามะกอก" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "เทามอส" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "เทาสัญญาณ" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "เทาหนู" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "เทาเบจ" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "เทากากี" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "เทาเขียว" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "เทาผ้าใบ" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "เทาเหล็ก" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "เทาบะซอลต์" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "เทาน้ำตาล" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "เทาหินชนวน" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "เทาแอนทราไซต์" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "เทาอ่อน" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "เทาอัมเบอร์" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "เทาคอนกรีต" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "เทากราไฟต์" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "เทาหินแกรนิต" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "เทาหิน" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "เทาก้อนกรวด" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "เทาซีเมนต์" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "เทาเหลือง" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "เทาแพลทินัม" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "เทาฝุ่น" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "เทาอาเกต" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "เทาควอตซ์" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "เทาหน้าต่าง" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "เทาจราจร A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "เทาจราจร B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "เทาไหม" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "เทเลเกรย์ 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "เทเลเกรย์ 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "เทเลเกรย์ 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "เทาหนูมุก" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "น้ำตาลเขียว" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "น้ำตาลออคเคอร์" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "น้ำตาลดินเหนียว" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "น้ำตาลทองแดง" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "น้ำตาลช็อกโกแลต" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "น้ำตาลมะกอก" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "น้ำตาลถั่ว" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "น้ำตาลแดง" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "น้ำตาลซีเปีย" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "น้ำตาลเกาลัด" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "น้ำตาลมะฮอกกานี" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "น้ำตาลเทา" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "ทองแดงมุก" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "น้ำตาลเบจ" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "น้ำตาลม็อกค่ามุก" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "น้ำตาลดิน" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "น้ำตาลมุก" +# AI Translated msgid "Cream" -msgstr "" +msgstr "ครีม" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "ขาวเทา" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "ขาวสัญญาณ" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "ดำสัญญาณ" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "ดำสนิท" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "อะลูมิเนียมขาว" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "อะลูมิเนียมเทา" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "ขาวบริสุทธิ์" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "ดำกราไฟต์" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "ขาวจราจร" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "ดำจราจร" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "ขาวปาปิรุส" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "เทาอ่อนมุก" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "โลหะ: เงิน" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "โลหะ: ทองเหลือง" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "โลหะ: ทอง" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "โลหะ: ทองแดง" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "โลหะ: บรอนซ์" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "ธรรมชาติ: มุก" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "ธรรมชาติ: สายรุ้ง" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "ธรรมชาติ: ท้องฟ้าโปร่ง" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "ธรรมชาติ: พระอาทิตย์ตก" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "ไม้: เข้ม" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "ไม้: ปานกลาง" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "ไม้: อ่อน" # AI Translated msgid "Alternate nozzles:" @@ -32376,13 +32810,25 @@ msgstr "นำออกจาก พื้นผิวของฉัน" msgid "Built-in" msgstr "ในตัว" +# AI Translated +msgid "My textures" +msgstr "พื้นผิวของฉัน" + # AI Translated msgid "No textures found." msgstr "ไม่พบพื้นผิว" # AI Translated -msgid "My textures" -msgstr "พื้นผิวของฉัน" +msgid "Texture libraries" +msgstr "คลังพื้นผิว" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "สำรวจคลังพื้นผิวเพิ่มเติม" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "เปิด OrcaCloud ในหน้าแรกเพื่อเรียกดูปลั๊กอิน" # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -32785,11 +33231,13 @@ msgstr "แมปด้วยเลย์เอาต์ UV ของโมเ msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "ความกว้างของพื้นผิวหนึ่งชุดบนโมเดล ค่าที่เล็กลงจะทำให้ลวดลายซ้ำบ่อยขึ้นและมีรายละเอียดละเอียดขึ้น เมื่อปิด ไทล์ ค่านี้คือขนาดของสำเนาเดียว" +# AI Translated msgid "Larger" -msgstr "" +msgstr "ใหญ่ขึ้น" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "เล็กลง" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -32865,11 +33313,13 @@ msgstr "สีผสม" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "จำนวนเส้นพลาสติกผสมสูงสุดที่การอบอาจเพิ่มได้ โดยเลือกจากสีของพื้นผิว และจะสร้างเฉพาะเส้นที่การอบใช้จริงเท่านั้น" +# AI Translated msgid "Few" -msgstr "" +msgstr "น้อย" +# AI Translated msgid "Many" -msgstr "" +msgstr "มาก" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33220,11 +33670,13 @@ msgstr "การรีเมช" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "ขนาดสามเหลี่ยมที่ใช้สร้างทั้งโมเดลใหม่ หน่วยเป็นมม. การกระจัดทำงานได้ดีที่สุดบนเมชที่สม่ำเสมอ ซึ่งค่านี้จะช่วยสร้างเมชดังกล่าวจากไฟล์นำเข้าที่ไม่สม่ำเสมอ" +# AI Translated msgid "Before" -msgstr "" +msgstr "ก่อน" +# AI Translated msgid "After" -msgstr "" +msgstr "หลัง" # AI Translated msgid "Keep sharp edges" @@ -35077,6 +35529,10 @@ msgstr "สคริปต์" msgid "Slicing Pipeline" msgstr "ไปป์ไลน์การสไลซ์" +# AI Translated +msgid "Resource Texture" +msgstr "พื้นผิวทรัพยากร" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "UI การกำหนดค่าของปลั๊กอินว่างเปล่า กำลังแสดงตัวแก้ไขเริ่มต้น" @@ -35224,6 +35680,30 @@ msgstr "ไดเรกทอรีปลั๊กอินมีทั้งไ msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "ไดเรกทอรีปลั๊กอินไม่มีไฟล์ entry .py หรือ .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "ยังไม่ได้ตั้งค่าโฟลเดอร์พื้นผิวทรัพยากร" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "ไม่สามารถระบุโฟลเดอร์พื้นผิวทรัพยากรได้" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "พาธพื้นผิวทรัพยากรไม่ใช่โฟลเดอร์" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "ไม่สามารถระบุโฟลเดอร์ปลั๊กอินได้" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "โฟลเดอร์พื้นผิวทรัพยากรอยู่นอกโฟลเดอร์ปลั๊กอิน" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "ไม่สามารถอ่านโฟลเดอร์พื้นผิวทรัพยากรได้" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -35684,7 +36164,7 @@ msgstr "โหลดไฟล์การกำหนดค่า \"%1%\" ไม # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "ไม่ใช่ไฟล์ G-code ที่สร้างโดย %1%" # AI Translated @@ -35804,7 +36284,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "ไม่สามารถสร้างสำเนาชั่วคราวของไฟล์ G-code %1% ก่อนเรียกใช้สคริปต์หลังการประมวลผลได้: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "ตัวประมวลผลภายหลังไม่พบไฟล์ G-code ที่ส่งออก" # AI Translated @@ -36173,6 +36653,28 @@ msgstr "" "หลีกเลี่ยงการบิดเบี้ยว\n" "คุณรู้หรือไม่ว่าเมื่อพิมพ์วัสดุที่มีแนวโน้มที่จะเกิดการบิดเบี้ยว เช่น ABS การเพิ่มอุณหภูมิฐานพิมพ์อย่างเหมาะสมสามารถลดความน่าจะเป็นของการบิดเบี้ยวได้" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "เหลืองดัลเมเชียน" + +# AI Translated +# Needs human review: Source "Capsanthin violet" is probably a typo for RAL "Capri blue" (sits between Turquoise blue and Ocean blue); translated as Capri blue. Source string needs fixing +#~ msgid "Capsanthin violet" +#~ msgstr "น้ำเงินคาปรี" + +# AI Translated +# Needs human review: Source "Olivestone" is probably a typo for RAL "Olive grey" (sits between Silver grey and Moss grey); translated as Olive grey. Source string needs fixing +#~ msgid "Olivestone" +#~ msgstr "เทามะกอก" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "ใช้ได้ทุกที่ในหน้าต่าง แม้ขณะพิมพ์ในช่องข้อความ" + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "แป้นพิมพ์ลัดส่วนกลางจะทำงานแม้ขณะพิมพ์ข้อความ" + #~ msgid "Please choose the filament color" #~ msgstr "กรุณาเลือกสีเส้นพลาสติก" @@ -36642,9 +37144,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "ไม่มีเครื่องมือที่กำหนดค่าไว้" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "สิ้นสุด G-code เมื่อพิมพ์เสร็จทั้งหมด" - #~ msgid "Maximum X speed" #~ msgstr "ความเร็ว X สูงสุด" @@ -36661,25 +37160,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "ปลั๊กอิน Python ที่เรียกใช้ในแต่ละขั้นตอนของไปป์ไลน์การสไลซ์เพื่ออ่านและแก้ไขข้อมูลการสไลซ์ระหว่างกลาง รวมถึงขั้นตอนหลังประมวลผล G-code สุดท้าย สำหรับการวิจัย/ทดลอง" -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "เมื่อเปิดใช้งาน สไลเซอร์จะสร้าง G-code โดยให้เนื้อหาของโซนหลักอยู่กึ่งกลางที่จุดกำเนิดของฐานพิมพ์ (0,0) เฟิร์มแวร์ของเครื่องพิมพ์จะรับผิดชอบการวางสำเนา/ภาพกระจกเงาที่ตำแหน่งของแต่ละโซนจริง เปิดใช้งานเฉพาะกับเครื่องพิมพ์ที่เฟิร์มแวร์ใช้ค่าออฟเซ็ตโซนของตัวเองในโหมดสำเนา/กระจกเงา (เช่น โหมด duplication ของ IDEX ใน RepRapFirmware) ไม่มีผลในโหมดหลัก (Primary)" - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "ค่าแทนที่ต่อเพลตที่จับคู่หัวจริงกับช่องเส้นพลาสติก (เริ่มนับจาก 1) เว้นว่างหมายถึงใช้ค่าเริ่มต้นจาก pem-inversion" -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "แกนที่ใช้หมุนเมชก่อนการสไลซ์ นี่คือการเอียงของเครื่องพิมพ์สายพาน: การหมุนแบบไอโซเมตริก (ไม่บิดเบี้ยว) ซึ่งยังใช้กำหนดการแสดงผลฐานพิมพ์และการเอียงแรงโน้มถ่วงของส่วนรองรับ และการแปลงกลับของ G-code จะย้อนการหมุนนี้ก่อนการเฉือน/ปรับสเกลและการแมปแกนของระบบพิกัดเครื่อง X คือการเอียงแกนทรีที่ใช้ทั่วไป (สายพานเคลื่อนที่ตามแนว Y)" - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "การแทนที่สำหรับผู้เชี่ยวชาญ: ตั้งมุมเอียงของระบบพิกัดเครื่อง (การเฉือน/ปรับสเกล G-code) แยกจากมุมหมุนก่อนสไลซ์ เมื่อปิดใช้งาน การแปลงระบบพิกัดเครื่องจะคำนวณจากมุมเอียงสายพาน ดังนั้นมุมเดียวจะควบคุมทั้งสองขั้นตอน เปิดใช้งานเฉพาะเพื่อชดเชยเครื่องที่การเอียงจริงของแกนทรีต่างจากการหมุนสำหรับสไลซ์" - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "ค่าเบี่ยงเบนสูงสุดที่อนุญาตเมื่อลดความละเอียดสำหรับการตั้งค่า 'ความละเอียดสูงสุดของผนัง' หากเพิ่มค่านี้ การพิมพ์จะแม่นยำน้อยลง แต่ G-Code จะน้อยลง 'ค่าเบี่ยงเบนของผนังสูงสุด' จะจำกัด 'ความละเอียดของผนังสูงสุด' ดังนั้นหากทั้งสองข้อขัดแย้งกัน 'ค่าเบี่ยงเบนของผนังสูงสุด' จะมีความสำคัญเหนือกว่า" - #~ msgid " not in range " #~ msgstr "ไม่อยู่ในช่วง" diff --git a/localization/i18n/tr/OrcaSlicer_tr.po b/localization/i18n/tr/OrcaSlicer_tr.po index ead52e8b7b..ff66cc5b2d 100644 --- a/localization/i18n/tr/OrcaSlicer_tr.po +++ b/localization/i18n/tr/OrcaSlicer_tr.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-08-21 23:18+0300\n" "Last-Translator: GlauTech\n" "Language-Team: \n" @@ -783,18 +783,21 @@ msgstr "Seçim" msgid "Plate" msgstr "Plaka" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "Dağıt" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Dönüştürme işlemlerinde kullanılan koordinat sistemi." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Hizalama referansı" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "En az 3 parça veya nesne seçin" # AI Translated msgid "Align left" @@ -847,8 +850,9 @@ msgstr "Üst-alt yönünde dağıt" msgid "Drop" msgstr "Düşür" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Seçimi, en alçak noktası yatağa değecek şekilde Z ekseni boyunca taşır." # AI Translated msgid "Absolute" @@ -1714,10 +1718,10 @@ msgid "Undefined fill type" msgstr "Tanımsız dolgu türü" msgid "Linear gradient" -msgstr "Doğrusal degrade" +msgstr "Doğrusal gradyan" msgid "Radial gradient" -msgstr "Radyal degrade" +msgstr "Radyal gradyan" msgid "Open filled path" msgstr "Doldurulmuş yolu aç" @@ -1749,7 +1753,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Şeklin konturu (%1%) desteklenmeyenleri içeriyor: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Geçersiz durum, lütfen yeniden oluşturma adımlarını GitHub'da bildirin" # AI Translated @@ -1757,11 +1761,11 @@ msgid "No embossed file" msgstr "Kabartma dosyası yok" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Kabartmalı şekilde SVG dosyası eksik" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "SVG dosyasının verileri eksik" msgid "Face the camera" @@ -2089,17 +2093,21 @@ msgstr "Birleştirme gizmosuna giriliyor" msgid "Leaving Assembly gizmo" msgstr "Birleştirme gizmosundan çıkılıyor" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Kesilmiş bir nesnenin parçaları taşınamaz" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Plakaya hizalama yalnızca X ve Y'de kullanılabilir" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Seçilen nesneleri Z ekseninde taşımak için Otomatik düşürmeyi kapatın" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Seçilen tüm nesneler aynı plakada olmalıdır" msgid "Shift+" msgstr "Shift+" @@ -5013,7 +5021,7 @@ msgstr "Lütfen projeyi kaydedin ve programı yeniden başlatın." msgid "Unknown C++ exception." msgstr "Bilinmeyen C++ istisnası." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Önceki dosyadan G-code işleniyor…" msgid "Slicing complete" @@ -6557,8 +6565,10 @@ msgstr "Eksenler" msgid "Gridlines" msgstr "Kılavuz çizgileri" +# AI Translated +# Needs human review: Glossary has no Turkish rendering for Focus mode yet; check 'Odak modu' fits the view-mode name. msgid "Focus mode" -msgstr "" +msgstr "Odak modu" msgid "Labels" msgstr "Etiketler" @@ -6619,7 +6629,7 @@ msgstr "Hacim:" msgid "Size:" msgstr "Boyut:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "%d katmanında G-code yollarında çakışmalar bulundu, Z = %.2lfmm. Lütfen çakışan nesneleri daha uzağa ayırın (%s <-> %s)." @@ -10985,11 +10995,13 @@ msgstr "Desteklenmeyen ön ayarları göster" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Yazıcı ve filament açılır listelerinde uyumsuz/desteklenmeyen ön ayarları gösterir. Bu ön ayarlar seçilemez." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "İstatistikleri G-code ile dışa aktar" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Etkinleştirilirse, bir G-code dosyası dışa aktarılırken istatistikleri de yanına .statistics.json olarak JSON biçiminde yazılır; dışa aktarılan dilimlenmiş 3MF dosyası da bunları içinde barındırır: baskı süresi, filament ve çizgi türü toplamları ile katman ve nesne başına aynı bilgiler." # AI Translated msgid "Experimental Features" @@ -11853,6 +11865,10 @@ msgstr "Dosya yazıcının depolama alanına yüklenemedi. Lütfen tekrar deneyi msgid "Send Failed" msgstr "Gönderim Başarısız" +# AI Translated +msgid "No available printers" +msgstr "Kullanılabilir yazıcı yok" + msgid "The name length exceeds the limit." msgstr "Ad uzunluğu sınırı aşıyor." @@ -13721,8 +13737,8 @@ msgid "Left mouse" msgstr "Sol fare tuşu" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Pencerenin her yerinde, bir metin alanına yazarken bile kullanılabilir." +msgid "Available anywhere in the window." +msgstr "Pencerenin her yerinde kullanılabilir." # AI Translated msgid "Run favorite 1 to 10" @@ -13834,10 +13850,6 @@ msgstr "%s, %s için atanmış. %s için yeniden atansın mı?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Varsayılan %s, %s için atanmış. %s için yeniden atansın mı?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Genel kısayollar yazarken de geçerlidir." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Karakter yazan bir tuş genel kısayol olamaz." @@ -14294,9 +14306,10 @@ msgstr "\"%2%\" nesnesinin \"%1%\" değiştiricisinin (toplam %3%) dikiş üzeri msgid "Seam placement may differ from expected." msgstr "Dikiş yerleşimi beklenenden farklı olabilir." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "G-code istatistikleri %1% konumuna yazılamadı." msgid "Internal Bridge" msgstr "İç köprü" @@ -17740,6 +17753,14 @@ msgstr "Nesneleri hariç tut" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "G-code'a EXCLUDE OBJECT komutunu eklemek için bu seçeneği etkinleştirin." +# AI Translated +msgid "Outline tolerance" +msgstr "Dış hat toleransı" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "EXCLUDE_OBJECT_DEFINE'a yazılan nesne dış hattının orijinal dış hattan en fazla sapması. Daha büyük değerler daha az nokta üretir; bu, çok sayıda nesne içeren G-code'u ayrıştırırken takılan ürün yazılımına yardımcı olur. 0 her noktayı korur." + msgid "Verbose G-code" msgstr "Ayrıntılı G-code" @@ -21022,11 +21043,13 @@ msgstr "Çıkış dizini" msgid "This is the output directory for exported files." msgstr "Dışa aktarılan dosyalar için çıkış dizini." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "İstatistikleri dışa aktar" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Dilimlenen her plakanın istatistiklerini JSON olarak yazar: çıktı dizininde G-code'un yanına plate_N.statistics.json olarak ve --export-3mf ile oluşturulan 3MF'in içine; baskı süresi, filament ve çizgi türü toplamları ile katman ve nesne başına aynı bilgiler." msgid "Debug level" msgstr "Hata ayıklama düzeyi" @@ -23470,7 +23493,7 @@ msgstr "%s testi başlatılıyor..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "%s testi: IP çözümlendi = %s" # AI Translated @@ -30966,1231 +30989,1652 @@ msgid_plural "The current filament list does not contain %s. Project filaments r msgstr[0] "Mevcut filament listesi %s içermiyor. Karışık filamentin gerektirdiği bir proje filamenti, ayrıştırmadan sonra otomatik olarak oluşturulacak." msgstr[1] "Mevcut filament listesi %s içermiyor. Karışık filamentin gerektirdiği proje filamentleri, ayrıştırmadan sonra otomatik olarak oluşturulacak." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Renk seçici" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Temel renkler" +# AI Translated +# Needs human review: Glossary has no Turkish rendering for Palette; check 'palet' (also Paletler). #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Orca paleti" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Klasik" + +# AI Translated +# Needs human review: Glossary has no Turkish cell for Gradient; used 'Gradyan' (as in Karışık filament gradyanı), though 'Linear gradient' is 'Doğrusal degrade' in the catalog. msgid "Gradients" -msgstr "" +msgstr "Gradyanlar" +# AI Translated +# Needs human review: Color-picker sense (single color, not a gradient); check 'Düz' reads as 'solid color'. +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Düz" +# AI Translated +# Needs human review: Glossary has no Turkish cell for Gradient; used 'Gradyan' (as in Karışık filament gradyanı), though 'Linear gradient' is 'Doğrusal degrade' in the catalog. msgid "Gradient" -msgstr "" +msgstr "Gradyan" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Gradyan başlangıcı" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Gradyan sonu" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Gradyan rengi" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Renk ekle" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Rengi kaldır" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Doygunluk" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Orijinal renk" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Geçerli rengi kaydet" +# AI Translated +# Needs human review: Glossary has no Turkish rendering for Palette; check 'Paletler'. msgid "Palettes" -msgstr "" +msgstr "Paletler" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Renk ara" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Renkleri filtrele" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Eşleşen renk yok" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Onaltılık renk" # AI Translated msgid "Opacity" msgstr "Opaklık" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Opaklık yüzdesi" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Rengi kaydet" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Eksiksiz bir onaltılık renk girin" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Mevcut çok renkli seçim, farklı bir renk seçene kadar korunur." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "En fazla %d renk desteklenir." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Kızıl" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Turuncu kırmızı" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Domates" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Turuncu" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Koyu turuncu" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Altın" +# AI Translated +# Needs human review: CSS color; check 'Ahşap kahvesi' conveys burlywood (light tan wood). msgid "Burly wood" -msgstr "" +msgstr "Ahşap kahvesi" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Bisküvi" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Sisli gül" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Açık sarı" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Limon şifonu" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Bej" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Açık altın çubuk sarısı" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Soluk altın çubuk" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Haki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Koyu haki" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Şeftali kreması" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Mokasen" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Papaya kreması" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Soyulmuş badem" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Antik beyaz" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Navaho beyazı" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Buğday" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Altın çubuk" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Çikolata" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Tuğla kırmızısı" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Siyena" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Eyer kahvesi" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Kahverengi" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Gül kahvesi" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Somon" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Açık somon" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Koyu somon" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Kum kahvesi" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Mercan" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Açık mercan" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Hint kırmızısı" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Koyu kırmızı" +# AI Translated +# Needs human review: CSS maroon rendered 'Vişne çürüğü'; check. msgid "Maroon" -msgstr "" +msgstr "Vişne çürüğü" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Yeşil sarı" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Sarı yeşil" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Şartröz" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Çim yeşili" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Misket limonu yeşili" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Bahar yeşili" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Orta bahar yeşili" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Misket limonu" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Orman yeşili" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Koyu yeşil" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Mat zeytin yeşili" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Zeytin" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Koyu zeytin yeşili" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Soluk yeşil" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Açık yeşil" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Orta deniz yeşili" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Deniz yeşili" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Koyu deniz yeşili" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Harbiye mavisi" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Orta akuamarin" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Turkuaz" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Orta turkuaz" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Koyu turkuaz" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Soluk turkuaz" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Akua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Açık camgöbeği" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Nane kreması" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Bal kavunu" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Akuamarin" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Açık deniz yeşili" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Koyu camgöbeği" +# AI Translated +# Needs human review: Rendered 'Petrol mavisi'; check it reads as teal. msgid "Teal" -msgstr "" +msgstr "Petrol mavisi" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Koyu arduvaz grisi" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Açık arduvaz grisi" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Arduvaz grisi" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Derin gökyüzü mavisi" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Dodger mavisi" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Gökyüzü mavisi" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Açık gökyüzü mavisi" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Açık mavi" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Pudra mavisi" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Açık çelik mavisi" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Çelik mavisi" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Kantaron mavisi" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Kraliyet mavisi" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Orta mavi" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Gece yarısı mavisi" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Koyu mavi" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Lacivert" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Arduvaz mavisi" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Koyu arduvaz mavisi" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Orta arduvaz mavisi" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Mavi menekşe" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "İndigo" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Koyu menekşe" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Koyu orkide" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Orta orkide" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Orkide" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Menekşe" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Orta mor" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Mor" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Rebecca moru" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Orta menekşe kırmızısı" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Soluk menekşe kırmızısı" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Derin pembe" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Sıcak pembe" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Açık pembe" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Pembe" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Erik" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Devedikeni" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuşya" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Koyu macenta" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Keten" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Eski dantel" +# AI Translated msgid "Sea shell" -msgstr "" +msgstr "Deniz kabuğu" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Fildişi" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Çiçek beyazı" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Lavanta pembesi" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Hayalet beyazı" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Alice mavisi" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Lavanta" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Duman beyazı" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Siyah" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Mercan ateşi" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Deniz anemonu" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Derin uçurum" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Istakoz kırmızısı" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Kumlu kil" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Sürüklenmiş odun" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Deniz iğdesi" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Gün batımı resifi" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Kaplan mercanı" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Pembe mercan" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Deniz kabuğu parıltısı" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Kum" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Altın deniz yosunu" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Güneşli kumul" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Kehribar nautilus" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Deniz limonu" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Soluk deniz yıldızı" +# AI Translated +# Needs human review: Ocean-themed name; 'Büyük gelgit' is the oceanographic term; check it reads as a color name. msgid "Spring tide" -msgstr "" +msgstr "Büyük gelgit" +# AI Translated +# Needs human review: Ocean-themed name; check 'Misket limonu algi' reads right. msgid "Lime algae" -msgstr "" +msgstr "Misket limonu algi" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Deniz çimi" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Neon plankton" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Deniz yosunu ormanı" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Zümrüt dalga" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Balina gölgesi" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Deniz kaplumbağası" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Lagün" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Tropik akıntı" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Gece yarısı çukuru" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Koyu deniz yosunu" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Kristal dalga" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Turkuaz koy" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Resif üstü gökyüzü" +# AI Translated +# Needs human review: Ocean-themed color name; check 'Sığ gökyüzü' reads as a color. msgid "Shallow sky" -msgstr "" +msgstr "Sığ gökyüzü" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Elektrik mavisi" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Yunus" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Okyanus derinlikleri" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Balina" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "İndigo uçurum" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Deniz kestanesi" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Lavanta mercanı" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Menekşe gelgiti" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Derin deniz orkidesi" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Neon denizanası" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Fuşya mercan" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Pembe denizanası" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Köpük" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Deniz kabuğu beyazı" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Çakıl grisi" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Fırtına bulutu" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Mürekkep siyahı" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Yeşil bej" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Kum sarısı" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Sinyal sarısı" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Altın sarısı" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Bal sarısı" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Mısır sarısı" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Nergis sarısı" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Kahverengi bej" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Limon sarısı" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "İstiridye beyazı" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Açık fildişi" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Çinko sarısı" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Gri bej" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Zeytin sarısı" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Kolza sarısı" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Trafik sarısı" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Oker sarısı" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Trafik turuncu sarısı" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Köri" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Kavun sarısı" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Katırtırnağı sarısı" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Dahlia sarısı" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Pastel sarı" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "İnci bej" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "İnci altın" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Güneş sarısı" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Sarı turuncu" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Derin turuncu" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Vermilyon" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "İnci turuncu" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Saf turuncu" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Parlak turuncu" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Parlak açık turuncu" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Açık kırmızı turuncu" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Trafik turuncusu" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Sinyal turuncusu" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Somon turuncusu" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "İnci pembe" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Bakır turuncusu" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Sinyal kahvesi" +# AI Translated +# Needs human review: Odd RAL name; translated literally as Ladin turuncusu. msgid "Fir orange" -msgstr "" +msgstr "Ladin turuncusu" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Sinyal kırmızısı" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Parlak kırmızı" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Karmen kırmızısı" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "İnci karmen kırmızısı" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Saf kırmızı" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Parlak koyu kırmızı" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Frenk üzümü kırmızısı" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "İnci yakut kırmızısı" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Ateş kırmızısı" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Yakut kırmızısı" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Mor kırmızı" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Şarap kırmızısı" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Siyah kırmızı" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Oksit kırmızısı" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Kahverengi kırmızı" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Çam kırmızısı" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Domates kırmızısı" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Antik pembe" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Mercan kırmızısı" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Gül" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Çilek kırmızısı" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Trafik kırmızısı" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Somon pembesi" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Parlak gül" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Parlak açık kırmızı" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Ahududu kırmızısı" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Doğu kırmızısı" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "İnci yakut" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Kırmızı mor" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Kırmızı menekşe" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Funda moru" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Bordo moru" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Maun" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Gri mor" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Sinyal moru" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Ladin yeşili" +# AI Translated +# Needs human review: RAL name; check the Turkish form. msgid "Sabine grey" -msgstr "" +msgstr "Sabine grisi" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "İnci mor" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "İnci böğürtlen" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Yeşil mavi" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ultramarin mavisi" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Safir mavisi" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Siyah mavi" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Sinyal mavisi" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Canlı mavi" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Gri mavi" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Azur mavisi" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Centiyana mavisi" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Kobalt mavisi" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Güvercin mavisi" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Trafik mavisi" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Turkuaz mavisi" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Capri mavisi" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Okyanus mavisi" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Su mavisi" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Gece mavisi" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Uzak mavi" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Pastel mavi" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "İnci centiyana mavisi" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "İnci gece yarısı mavisi" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Patina yeşili" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Zümrüt yeşili" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Yaprak yeşili" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Zeytin yeşili" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Mavi yeşil" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Karayosunu yeşili" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Gri zeytin" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Çam yeşili" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Çam kahvesi" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Ot yeşili" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Reseda yeşili" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Kahverengi yeşil" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Sazlık yeşili" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Siyah yeşil" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Turkuaz yeşili" +# AI Translated msgid "May green" -msgstr "" +msgstr "Mayıs yeşili" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Krom oksit yeşili" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Trafik yeşili" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Eğrelti otu yeşili" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Opal yeşili" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Nane yeşili" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Bronz yeşili" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "İnci yeşil" +# AI Translated +# Needs human review: RAL name; check the Turkish form. msgid "Sax turquoise" -msgstr "" +msgstr "Sax turkuazı" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "İnci turkuaz" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "İnci yeşim" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Saf yeşil" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Parlak yeşil" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Sincap grisi" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Gümüş grisi" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Zeytin grisi" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Karayosunu grisi" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Sinyal grisi" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Fare grisi" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Bej gri" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Haki gri" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Yeşil gri" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Branda grisi" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Demir grisi" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Bazalt grisi" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Kahverengi gri" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Arduvaz grisi" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Antrasit grisi" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Açık gri" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Umber grisi" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Beton grisi" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Grafit grisi" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Granit grisi" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Taş grisi" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Çakıl grisi" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Çimento grisi" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Sarı gri" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Platin grisi" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Tozlu gri" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Akik grisi" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Kuvars grisi" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Pencere grisi" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Trafik grisi A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Trafik grisi B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "İpek grisi" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegri 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegri 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegri 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "İnci fare grisi" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Yeşil kahverengi" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Oker kahvesi" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Kil kahvesi" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Bakır kahvesi" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Çikolata kahvesi" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Zeytin kahvesi" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Ceviz kahvesi" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Kırmızı kahverengi" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Sepya kahvesi" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Kestane kahvesi" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Maun kahvesi" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Gri kahverengi" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "İnci bakır" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Bej kahverengi" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "İnci mokka kahvesi" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Toprak kahvesi" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "İnci kahverengi" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Krem" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Gri beyaz" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Sinyal beyazı" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Sinyal siyahı" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Jet siyahı" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Beyaz alüminyum" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Gri alüminyum" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Saf beyaz" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Grafit siyahı" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Trafik beyazı" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Trafik siyahı" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Papirüs beyazı" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "İnci açık gri" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Metal: Gümüş" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Metal: Pirinç" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Metal: Altın" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Metal: Bakır" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Metal: Bronz" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Doğa: İnci" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Doğa: Gökkuşağı" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Doğa: Açık gökyüzü" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Doğa: Gün batımı" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Ahşap: Koyu" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Ahşap: Orta" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Ahşap: Açık" # AI Translated msgid "Alternate nozzles:" @@ -32667,13 +33111,25 @@ msgstr "Dokularım'dan kaldır" msgid "Built-in" msgstr "Yerleşik" +# AI Translated +msgid "My textures" +msgstr "Dokularım" + # AI Translated msgid "No textures found." msgstr "Doku bulunamadı." # AI Translated -msgid "My textures" -msgstr "Dokularım" +msgid "Texture libraries" +msgstr "Doku kütüphaneleri" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Daha fazla doku kütüphanesi keşfedin" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Eklentilere göz atmak için OrcaCloud'u Ana sayfada açar." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33076,11 +33532,13 @@ msgstr "Modelin kendi UV düzeniyle haritalanır; bu düzen zaten yerleşimin ke msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Dokunun bir kopyasının model üzerindeki genişliği. Küçük değerler deseni daha sık tekrarlar ve ayrıntısını inceltir; Döşeme kapalıyken bu, tek kopyanın boyutudur." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Daha büyük" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Daha küçük" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33156,11 +33614,15 @@ msgstr "Karışık renkler" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Bir pişirmenin ekleyebileceği en fazla karışık filament sayısı. Bunlar dokunun renklerinden seçilir ve yalnızca pişirmenin gerçekten kullandıkları oluşturulur." +# AI Translated +# Needs human review: Bare label in the app; check Az/Çok fit their context. msgid "Few" -msgstr "" +msgstr "Az" +# AI Translated +# Needs human review: Bare label in the app; check Az/Çok fit their context. msgid "Many" -msgstr "" +msgstr "Çok" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33516,11 +33978,15 @@ msgstr "Yeniden mesh oluşturma" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Tüm modelin yeniden oluşturulacağı üçgen boyutu (milimetre). Yer değiştirme en iyi düzgün bir mesh üzerinde çalışır; düzensiz bir içe aktarmadan düzgün mesh bu şekilde elde edilir." +# AI Translated +# Needs human review: Bare label in the app; check Önce/Sonra fit their context. msgid "Before" -msgstr "" +msgstr "Önce" +# AI Translated +# Needs human review: Bare label in the app; check Önce/Sonra fit their context. msgid "After" -msgstr "" +msgstr "Sonra" # AI Translated msgid "Keep sharp edges" @@ -35381,6 +35847,10 @@ msgstr "Betik" msgid "Slicing Pipeline" msgstr "Dilimleme Hattı" +# AI Translated +msgid "Resource Texture" +msgstr "Kaynak dokusu" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Eklentinin yapılandırma arayüzü boştu. Varsayılan düzenleyici gösteriliyor." @@ -35528,6 +35998,30 @@ msgstr "Eklenti dizini hem .py hem de .whl giriş dosyaları içeriyor" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Eklenti dizini bir .py veya .whl giriş dosyası içermiyor" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Kaynak dokusu dizini ayarlanmamış" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Kaynak dokusu dizini belirlenemedi" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Kaynak dokusu yolu bir dizin değil" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Eklenti klasörü belirlenemedi" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Kaynak dokusu dizini eklenti klasörünün dışında" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Kaynak dokusu dizini okunamadı" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -35988,7 +36482,7 @@ msgstr "\"%1%\" yapılandırma dosyası yüklenemedi: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "%1% tarafından oluşturulmuş bir G-code dosyası değil." # AI Translated @@ -36108,7 +36602,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "İşlem sonrası komut dosyası çalıştırılmadan önce %1% G-code dosyasının geçici kopyası oluşturulamadı: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "İşlem sonrası işlemcisi dışa aktarılan G-code dosyasını bulamıyor" # AI Translated @@ -36478,6 +36972,28 @@ msgstr "" "Eğilmeyi önleyin\n" "ABS gibi bükülmeye yatkın malzemelere baskı yaparken, ısıtma yatağı sıcaklığının uygun şekilde arttırılmasının bükülme olasılığını azaltabileceğini biliyor muydunuz?" +# AI Translated +# Needs human review: Possibly meant Daffodil yellow (RAL 1007); translated literally. +#~ msgid "Dalmatian yellow" +#~ msgstr "Dalmaçya sarısı" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Kapsantin moru" + +# AI Translated +# Needs human review: Probably RAL Olive grey; translated as Zeytin grisi. +#~ msgid "Olivestone" +#~ msgstr "Zeytin grisi" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Pencerenin her yerinde, bir metin alanına yazarken bile kullanılabilir." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Genel kısayollar yazarken de geçerlidir." + #~ msgid "Please choose the filament color" #~ msgstr "Lütfen filament rengini seçin" @@ -36956,9 +37472,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "yapılandırılmış araç yok" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Tüm yazdırmayı tamamladığında çalışacak olan G-code." - #~ msgid "Maximum X speed" #~ msgstr "Maksimum X hızı" @@ -36975,26 +37488,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Ara dilimleme verilerini okumak ve değiştirmek için her dilimleme hattı adımında çağrılan Python eklentileri; son bir G-code son işleme adımı da buna dahildir. Araştırma/deneysel." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Etkinleştirildiğinde dilimleyici, birincil bölgenin içeriğini yatak orijininde (0,0) ortalanmış şekilde G-code üretir. Kopyaları/ayna görüntülerini her fiziksel bölge konumuna yerleştirmekten yazıcının ürün yazılımı sorumludur. Yalnızca ürün yazılımı kopya/ayna modunda kendi bölge ofsetlerini uygulayan yazıcılarda etkinleştirin (ör. RepRapFirmware IDEX çoğaltma modu). Birincil modda etkisi yoktur." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Fiziksel kafaları filament yuvalarına eşleyen plaka başına geçersiz kılma (1 tabanlı). Boş bırakılırsa pem-inversion varsayılanları kullanılır." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Dilimlemeden önce mesh'in etrafında döndürüldüğü eksen. Bu, bant yazıcının eğimidir: yatak görüntülemesini ve destek yerçekimi eğimini de belirleyen izometrik (bozulmasız) bir dönüş; G-code geri dönüşümü bunu, makine koordinat sistemi kesme/ölçekleme ve yeniden eşleme işlemlerinden önce tersine çevirir. Tipik portal eğimi X'tir (bant Y boyunca ilerler)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Uzman geçersiz kılması: makine koordinat sistemi (G-code kesme/ölçekleme) eğim açısını dilimleme öncesi dönüş açısından bağımsız olarak ayarlar. Devre dışı bırakıldığında makine koordinat sistemi dönüşümü bant eğim açısından türetilir; böylece tek bir açı her iki aşamayı da belirler. Yalnızca fiziksel portal eğimi dilimleme dönüşünden farklı olan bir makineyi telafi etmek için etkinleştirin." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "'Maksimum duvar çözünürlüğü' ayarı için çözünürlük düşürülürken izin verilen maksimum sapma. Bunu artırırsanız baskı daha az doğru olur ancak G-Code daha küçük olur. 'Maksimum duvar sapması', 'Maksimum duvar çözünürlüğü'nü sınırlar; dolayısıyla ikisi çakışırsa 'Maksimum duvar sapması' önceliklidir." - #~ msgid " not in range " #~ msgstr " aralıkta değil " diff --git a/localization/i18n/uk/OrcaSlicer_uk.po b/localization/i18n/uk/OrcaSlicer_uk.po index 00bdf873b3..6ae4916fef 100644 --- a/localization/i18n/uk/OrcaSlicer_uk.po +++ b/localization/i18n/uk/OrcaSlicer_uk.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: orcaslicerua\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-07-17 16:25+0300\n" "Last-Translator: Andrij Mizyk \n" "Language-Team: Ukrainian\n" @@ -772,17 +772,22 @@ msgstr "Вибір" msgid "Plate" msgstr "Пластина" +# AI Translated +# Needs human review: No glossary rendering yet (Ukrainian cell empty); Розподілити proposed. msgid "Distribute" -msgstr "" +msgstr "Розподілити" msgid "Coordinate system used for transform actions." msgstr "Система координат для дій перетворення." +# AI Translated +# Needs human review: Label in the Align/Distribute tool: what the objects are aligned to; check the wording in the UI. msgid "Reference for alignment" -msgstr "" +msgstr "Опора для вирівнювання" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Виберіть щонайменше 3 частини або обʼєкти" # AI Translated msgid "Align left" @@ -836,8 +841,9 @@ msgstr "Розподілити за висотою" msgid "Drop" msgstr "Кинути" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Перемістити виділене вздовж осі Z так, щоб його найнижча точка торкалася столу." msgid "Absolute" msgstr "Абсолютно" @@ -1740,7 +1746,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Обведення фігури (%1%) не підтримується: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Некоректний стан, будь ласка, повідомте кроки відтворення на GitHub" # AI Translated @@ -1748,11 +1754,11 @@ msgid "No embossed file" msgstr "Відсутній файл рельєфу" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "У рельєфній формі відсутній файл SVG" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Відсутні дані файлу SVG" msgid "Face the camera" @@ -2073,17 +2079,21 @@ msgstr "Вхід у gizmo-збирання" msgid "Leaving Assembly gizmo" msgstr "Вихід з gizmo-збирання" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Частини розрізаного обʼєкта не можна переміщувати" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Вирівнювання за пластиною доступне лише за осями X та Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Вимкніть авто-кидання для вибраних обʼєктів, щоб переміщувати їх за віссю Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Усі вибрані обʼєкти мають бути на одній пластині" msgid "Shift+" msgstr "Shift+" @@ -4964,7 +4974,7 @@ msgstr "Збережіть проект і перезапустіть прогр msgid "Unknown C++ exception." msgstr "Невідомий виняток C++." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Обробка G-code з попереднього файлу..." msgid "Slicing complete" @@ -6532,8 +6542,10 @@ msgstr "Осі" msgid "Gridlines" msgstr "Лінії сітки" +# AI Translated +# Needs human review: No glossary rendering yet (Ukrainian cell empty); check the term for hiding the interface to concentrate on the 3D canvas. msgid "Focus mode" -msgstr "" +msgstr "Режим фокусу" msgid "Labels" msgstr "Підписи" @@ -6596,7 +6608,7 @@ msgid "Size:" msgstr "Розмір:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Виявлено конфлікти шляхів G-code на шарі %d, Z = %.2lf мм. Будь ласка, рознесіть конфліктуючі обʼєкти далі один від одного (%s <-> %s)." @@ -11016,11 +11028,13 @@ msgstr "Показати непідтримувані пресети" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Показати несумісні/непідтримувані пресети у випадаючому списку принтера і філаменту. Ці пресети не можна вибрати." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Експортувати статистику разом із G-code" +# AI Translated msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Якщо ввімкнено, під час експорту файлу G-code поруч із ним записується його статистика у форматі JSON (.statistics.json), а експортований нарізаний файл 3MF містить її всередині: час друку, підсумки за філаментом і типами ліній, а також ті самі дані за шарами та обʼєктами." msgid "Experimental Features" msgstr "Експериментальні функції" @@ -11893,6 +11907,10 @@ msgstr "Не вдалося вивантажити файл у памʼять п msgid "Send Failed" msgstr "Не вдалося надіслати" +# AI Translated +msgid "No available printers" +msgstr "Немає доступних принтерів" + msgid "The name length exceeds the limit." msgstr "Довжина імені перевищує обмеження." @@ -13828,8 +13846,8 @@ msgid "Left mouse" msgstr "Ліва кнопка миші" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Доступно будь-де у вікні, навіть під час введення тексту в текстовому полі." +msgid "Available anywhere in the window." +msgstr "Доступно в будь-якому місці вікна." # AI Translated msgid "Run favorite 1 to 10" @@ -13941,10 +13959,6 @@ msgstr "%s призначено для %s. Перепризначити для % msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "Типову комбінацію %s призначено для %s. Перепризначити її для %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Глобальні комбінації клавіш діють і під час введення тексту." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Клавіша, яка вводить символ, не може бути глобальною комбінацією." @@ -14402,9 +14416,10 @@ msgstr "модифікатор \"%1%\" обʼєкта \"%2%\" (усього %3%) msgid "Seam placement may differ from expected." msgstr "Розташування шва може відрізнятися від очікуваного." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Не вдалося записати статистику G-code до %1%." msgid "Internal Bridge" msgstr "Внутрішній міст" @@ -17926,6 +17941,14 @@ msgstr "Виключити обʼєкт" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Увімкнути цей параметр для додавання команди ВИКЛЮЧИТИ ОБʼЄКТ у G-code" +# AI Translated +msgid "Outline tolerance" +msgstr "Допуск контуру" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Максимальне відхилення контуру обʼєкта, що записується в EXCLUDE_OBJECT_DEFINE, від вихідного контуру. Чим більше значення, тим менше точок, що допомагає прошивкам, які зависають під час розбору G-code з великою кількістю обʼєктів. 0 зберігає всі точки." + msgid "Verbose G-code" msgstr "Докладний G-code" @@ -21290,11 +21313,13 @@ msgstr "Вихідний каталог" msgid "This is the output directory for exported files." msgstr "Цільова папка для експортованих файлів." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Експорт статистики" +# AI Translated msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Записувати статистику кожної нарізаної пластини у форматі JSON: plate_N.statistics.json поруч із її G-code у вихідній теці та всередині 3MF для --export-3mf. Містить час друку, підсумки за філаментом і типами ліній, а також ті самі дані за шарами та обʼєктами." msgid "Debug level" msgstr "Рівень налагодження" @@ -23756,7 +23781,7 @@ msgstr "тест %s розпочато..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "тест %s: IP визначено = %s" # AI Translated @@ -31219,1231 +31244,1650 @@ msgstr[1] "Поточний список філаментів не містит msgstr[2] "Поточний список філаментів не містить %s. Філаменти проєкту, потрібні для змішаного філаменту, буде створено автоматично після розкладання." msgstr[3] "Поточний список філаментів не містить %s. Філаменти проєкту, потрібні для змішаного філаменту, буде створено автоматично після розкладання." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Вибір кольору" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Основні кольори" +# AI Translated +# Needs human review: No glossary rendering yet for Palette (Ukrainian cell empty); Палітра proposed. #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Палітра Orca" +# AI Translated +# Needs human review: Brand RAL kept; check whether Classic should be translated or kept in English. #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Класика" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Градієнти" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Однотонний" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Градієнт" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Початок градієнта" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Кінець градієнта" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Колір градієнта" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Додати колір" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Вилучити колір" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Насиченість" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Початковий колір" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Зберегти поточний колір" +# AI Translated +# Needs human review: No glossary rendering yet for Palette (Ukrainian cell empty); Палітра proposed. msgid "Palettes" -msgstr "" +msgstr "Палітри" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Пошук кольорів" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Фільтр кольорів" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Немає відповідних кольорів" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "HEX-колір" # AI Translated msgid "Opacity" msgstr "Непрозорість" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Непрозорість у відсотках" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Зберегти колір" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Введіть повний шістнадцятковий код кольору" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Поточний вибір кількох кольорів зберігається, доки ви не виберете інший колір." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Підтримується до %d кольорів." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Кармазин" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Помаранчево-червоний" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Томатний" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Помаранчевий" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Темно-помаранчевий" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Золотий" +# AI Translated +# Needs human review: CSS burlywood; check the natural Ukrainian color name. msgid "Burly wood" -msgstr "" +msgstr "Деревний" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Бісквітний" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Туманна троянда" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Світло-жовтий" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Лимонний шифон" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Бежевий" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Світло-золотисто-жовтий" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Блідо-золотистий" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Хакі" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Темний хакі" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Персиковий мус" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Мокасиновий" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Збита папайя" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Бланшований мигдаль" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Античний білий" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Білий навахо" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Пшеничний" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Золотистий" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Шоколадний" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Перу" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Цегляний" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Сієна" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Сідлово-коричневий" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Коричневий" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Рожево-коричневий" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Лососевий" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Світло-лососевий" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Темно-лососевий" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Піщано-коричневий" +# AI Translated msgid "Coral" -msgstr "" +msgstr "Кораловий" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "Світло-кораловий" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Індійський червоний" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Темно-червоний" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Бордовий" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Зелено-жовтий" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Жовто-зелений" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Шартрез" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Зелений газон" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Зелений лайм" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Весняний зелений" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Середній весняний зелений" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Лайм" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Лісовий зелений" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Темно-зелений" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Тьмяно-оливковий" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Оливковий" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Темно-оливковий" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Блідо-зелений" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Світло-зелений" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Середній морський зелений" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Морський зелений" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Темний морський зелений" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Кадетський синій" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Середній аквамарин" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Бірюзовий" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Середньо-бірюзовий" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Темно-бірюзовий" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Блідо-бірюзовий" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Аква" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Світло-ціановий" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Мʼятний крем" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Медова роса" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Аквамарин" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Світлий морський зелений" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Темно-ціановий" +# AI Translated +# Needs human review: CSS teal; check the natural Ukrainian color name. msgid "Teal" -msgstr "" +msgstr "Зелена бірюза" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Темний сланцево-сірий" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Світлий сланцево-сірий" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Сланцево-сірий" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Насичений небесно-блакитний" +# AI Translated +# Needs human review: CSS dodgerblue; check the natural Ukrainian color name. msgid "Dodger Blue" -msgstr "" +msgstr "Синій доджер" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Небесно-блакитний" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Світлий небесно-блакитний" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Світло-блакитний" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Пудрово-блакитний" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Світлий сталево-синій" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Сталево-синій" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Волошковий" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Королівський синій" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Середній синій" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Опівнічно-синій" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Темно-синій" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Морський синій" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Сланцево-синій" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Темний сланцево-синій" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Середній сланцево-синій" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Синьо-фіолетовий" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Індиго" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Темно-фіолетовий" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Темна орхідея" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Середня орхідея" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Орхідея" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Фіолетовий" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Середній пурпуровий" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Пурпуровий" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Пурпуровий Ребекки" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Середній фіолетово-червоний" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Блідий фіолетово-червоний" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Насичений рожевий" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Яскраво-рожевий" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Світло-рожевий" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Рожевий" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Сливовий" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Будяк" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Фуксія" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Темна маджента" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Льняний" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Старе мереживо" +# AI Translated +# Needs human review: Color name; the Shell glossary term does not apply. msgid "Sea shell" -msgstr "" +msgstr "Морська мушля" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Слонова кістка" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Квітково-білий" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Лавандовий румʼянець" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Примарно-білий" +# AI Translated +# Needs human review: CSS aliceblue; check the natural Ukrainian color name. msgid "Alice blue" -msgstr "" +msgstr "Блакитний Еліс" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Лавандовий" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Білий дим" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Гейнсборо" +# AI Translated msgid "Black" -msgstr "" +msgstr "Чорний" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "Кораловий вогонь" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Морська актинія" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Глибока безодня" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Червоний омар" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Піщана глина" +# AI Translated +# Needs human review: Ocean-themed color name; check it reads as a color. msgid "Driftwood" -msgstr "" +msgstr "Дрейфуюча деревина" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Обліпиха" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Захід сонця на рифі" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "Тигровий корал" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "Рожевий корал" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Сяйво мушлі" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Пісок" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Золота ламінарія" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Дюна на сонці" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Бурштиновий наутилус" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Морський лимон" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Бліда морська зірка" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Весняний приплив" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Лаймові водорості" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Морська трава" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Неоновий планктон" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Ліс ламінарії" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Смарагдова хвиля" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Тінь кита" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Морська черепаха" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Лагуна" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Тропічна течія" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Опівнічна западина" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Темна ламінарія" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Кришталевий прибій" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Бірюзова бухта" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Небо над рифом" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Небо мілководдя" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Електрик" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Дельфін" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Океанські глибини" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Кит" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Індигова безодня" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Морський їжак" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "Лавандовий корал" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Фіолетовий приплив" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Глибоководна орхідея" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Неонове желе" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "Фуксієвий корал" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Рожева медуза" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Піна" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Біла мушля" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Галечно-сірий" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Грозова хмара" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Чорнильно-чорний" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Зелено-бежевий" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Піщано-жовтий" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Сигнальний жовтий" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Золотисто-жовтий" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Медово-жовтий" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Кукурудзяно-жовтий" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Нарцисово-жовтий" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Коричнево-бежевий" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Лимонно-жовтий" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Устрично-білий" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Світла слонова кістка" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Цинково-жовтий" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Сіро-бежевий" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Оливково-жовтий" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Ріпаково-жовтий" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Дорожній жовтий" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Охристо-жовтий" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Дорожній помаранчево-жовтий" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Карі" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Динно-жовтий" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Дріково-жовтий" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Жоржиново-жовтий" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Пастельно-жовтий" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Перламутровий бежевий" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Перламутровий золотий" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Сонячно-жовтий" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Жовто-помаранчевий" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Насичений помаранчевий" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Кіновар" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Перламутровий помаранчевий" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Чистий помаранчевий" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Сяйний помаранчевий" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Сяйний яскраво-помаранчевий" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Яскраво-червоно-помаранчевий" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Дорожній помаранчевий" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Сигнальний помаранчевий" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Лососево-помаранчевий" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Перламутровий рожевий" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Мідно-помаранчевий" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Сигнальний коричневий" +# AI Translated +# Needs human review: Source name unclear; translated literally. msgid "Fir orange" -msgstr "" +msgstr "Ялицево-помаранчевий" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Сигнальний червоний" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Сяйний червоний" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Карміново-червоний" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Перламутровий карміново-червоний" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Чистий червоний" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Сяйний насичений червоний" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Смородиново-червоний" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Перламутровий рубіново-червоний" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Вогненно-червоний" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Рубіново-червоний" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Пурпурово-червоний" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Винно-червоний" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Чорно-червоний" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Оксидно-червоний" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Коричнево-червоний" +# AI Translated msgid "Pine red" -msgstr "" +msgstr "Сосново-червоний" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Томатно-червоний" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Античний рожевий" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Корало-червоний" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Троянда" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Полунично-червоний" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Дорожній червоний" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Лососево-рожевий" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Сяйна троянда" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Сяйний яскраво-червоний" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Малиново-червоний" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Східний червоний" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Перламутровий рубіновий" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Червоно-пурпуровий" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Червоно-фіолетовий" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Вересково-фіолетовий" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Бордово-фіолетовий" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Червоне дерево" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Сіро-пурпуровий" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Сигнальний фіолетовий" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Ялицево-зелений" +# AI Translated +# Needs human review: Source name unclear; translated literally. msgid "Sabine grey" -msgstr "" +msgstr "Сабінський сірий" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Перламутровий фіолетовий" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Перламутровий ожиновий" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Зелено-синій" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Ультрамарино-синій" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Сапфірово-синій" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Чорно-синій" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Сигнальний синій" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Бриліантово-синій" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Сіро-синій" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Лазурово-синій" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Тирличево-синій" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Кобальтово-синій" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Голубино-синій" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Дорожній синій" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Бірюзово-синій" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Синій Капрі" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Океанський синій" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Водяно-синій" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Нічно-синій" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Далекий синій" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Пастельно-синій" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Перламутровий тирличево-синій" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Перламутровий опівнічно-синій" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Патиново-зелений" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Смарагдово-зелений" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Листяно-зелений" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Оливково-зелений" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Синьо-зелений" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Мохово-зелений" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Сіро-оливковий" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Сосново-зелений" +# AI Translated msgid "Pine brown" -msgstr "" +msgstr "Сосново-коричневий" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Травʼяно-зелений" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Резедово-зелений" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Коричнево-зелений" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Очеретяно-зелений" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Чорно-зелений" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Бірюзово-зелений" +# AI Translated msgid "May green" -msgstr "" +msgstr "Травневий зелений" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Хромооксидний зелений" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Дорожній зелений" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Папоротево-зелений" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Опалово-зелений" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Мʼятно-зелений" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Бронзово-зелений" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Перламутровий зелений" +# AI Translated +# Needs human review: Source name unclear (Saxe blue?); translated literally. msgid "Sax turquoise" -msgstr "" +msgstr "Саксонсько-бірюзовий" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Перламутровий бірюзовий" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Перламутровий нефритовий" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Чистий зелений" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Сяйний зелений" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Білячий сірий" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Сріблясто-сірий" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Оливково-сірий" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Мохово-сірий" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Сигнальний сірий" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Мишачо-сірий" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Бежево-сірий" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Хакі-сірий" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Зелено-сірий" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Брезентово-сірий" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Залізно-сірий" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Базальтово-сірий" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Коричнево-сірий" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Сланцево-сірий" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Антрацитово-сірий" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Світло-сірий" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Умбро-сірий" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Бетонно-сірий" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Графітово-сірий" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Гранітно-сірий" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Камʼяно-сірий" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Галечно-сірий" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Цементно-сірий" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Жовто-сірий" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Платиново-сірий" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Пильно-сірий" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Агатово-сірий" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Кварцово-сірий" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Віконно-сірий" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Дорожній сірий A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Дорожній сірий B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Шовково-сірий" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Телесірий 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Телесірий 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Телесірий 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Перламутровий мишачо-сірий" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Зелено-коричневий" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Охристо-коричневий" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Глинисто-коричневий" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Мідно-коричневий" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Шоколадно-коричневий" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Оливково-коричневий" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Горіхово-коричневий" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Червоно-коричневий" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Сепієво-коричневий" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Каштаново-коричневий" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Махагонево-коричневий" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Сіро-коричневий" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Перламутровий мідний" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Бежево-коричневий" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Перламутровий мокко-коричневий" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Земляно-коричневий" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Перламутровий коричневий" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Кремовий" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Сіро-білий" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Сигнальний білий" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Сигнальний чорний" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Гагатово-чорний" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Білий алюміній" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Сірий алюміній" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Чистий білий" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Графітово-чорний" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Дорожній білий" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Дорожній чорний" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Папірусно-білий" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Перламутровий світло-сірий" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Метал: срібло" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Метал: латунь" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Метал: золото" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Метал: мідь" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Метал: бронза" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Природа: перлина" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Природа: веселка" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Природа: ясне небо" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Природа: захід сонця" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Дерево: темне" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Дерево: середнє" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Дерево: світле" # AI Translated msgid "Alternate nozzles:" @@ -32921,13 +33365,25 @@ msgstr "Вилучити з «Мої текстури»" msgid "Built-in" msgstr "Вбудовані" +# AI Translated +msgid "My textures" +msgstr "Мої текстури" + # AI Translated msgid "No textures found." msgstr "Текстур не знайдено." # AI Translated -msgid "My textures" -msgstr "Мої текстури" +msgid "Texture libraries" +msgstr "Бібліотеки текстур" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Знайти інші бібліотеки текстур" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Відкриває OrcaCloud на домашній сторінці для перегляду плагінів." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33330,11 +33786,15 @@ msgstr "Накладається за власною UV-розкладкою м msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Ширина однієї копії текстури на моделі. Менше значення частіше повторює візерунок і робить його деталі дрібнішими; якщо «Плитка» вимкнена, це розмір єдиної копії." +# AI Translated +# Needs human review: Caption of a tile-size picture in the texture-displacement tool; check it reads right. msgid "Larger" -msgstr "" +msgstr "Більше" +# AI Translated +# Needs human review: Caption of a tile-size picture in the texture-displacement tool; check it reads right. msgid "Smaller" -msgstr "" +msgstr "Менше" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33410,11 +33870,15 @@ msgstr "Змішані кольори" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Найбільша кількість змішаних філаментів, яку може додати запікання. Їх вибирають із кольорів текстури, і створюються лише ті, що справді використовуються під час запікання." +# AI Translated +# Needs human review: Caption under a mixed-colors image in the texture-displacement tool; check it reads right. msgid "Few" -msgstr "" +msgstr "Мало" +# AI Translated +# Needs human review: Caption under a mixed-colors image in the texture-displacement tool; check it reads right. msgid "Many" -msgstr "" +msgstr "Багато" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -33780,11 +34244,13 @@ msgstr "Перебудова сітки" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Розмір трикутника, з яким перебудовується вся модель, у міліметрах. Зміщення найкраще працює на рівномірній сітці; саме цей параметр робить її з нерівномірної імпортованої." +# AI Translated msgid "Before" -msgstr "" +msgstr "До" +# AI Translated msgid "After" -msgstr "" +msgstr "Після" # AI Translated msgid "Keep sharp edges" @@ -35716,6 +36182,10 @@ msgstr "Скрипт" msgid "Slicing Pipeline" msgstr "Конвеєр нарізки" +# AI Translated +msgid "Resource Texture" +msgstr "Текстура ресурсу" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Інтерфейс конфігурації плагіна порожній. Показано типовий редактор." @@ -35863,6 +36333,30 @@ msgstr "Каталог плагіна містить одночасно вхід msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Каталог плагіна не містить вхідного файлу .py або .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Теку текстур ресурсу не задано" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Не вдалося визначити теку текстур ресурсу" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Шлях до текстур ресурсу не є текою" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Не вдалося визначити теку плагіна" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Тека текстур ресурсу розташована поза текою плагіна" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Не вдалося прочитати теку текстур ресурсу" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36323,7 +36817,7 @@ msgstr "Не вдалося завантажити файл конфігурац # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Це не файл G-code, створений %1%." # AI Translated @@ -36443,7 +36937,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Не вдалося створити тимчасову копію файлу G-code %1% перед запуском скрипта постобробки: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Постпроцесор не може знайти експортований файл G-code" # AI Translated @@ -36816,6 +37310,28 @@ msgstr "" "Уникнення деформації\n" "Чи знаєте ви, що при друку матеріалами, схильними до деформації, такими як ABS, відповідне підвищення температури столу може зменшити ймовірність деформації?" +# AI Translated +# Needs human review: Not a known RAL name; translated literally. +#~ msgid "Dalmatian yellow" +#~ msgstr "Далматинський жовтий" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "Капсантиново-фіолетовий" + +# AI Translated +# Needs human review: Source name unclear; translated literally. +#~ msgid "Olivestone" +#~ msgstr "Оливково-камʼяний" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Доступно будь-де у вікні, навіть під час введення тексту в текстовому полі." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Глобальні комбінації клавіш діють і під час введення тексту." + #~ msgid "Please choose the filament color" #~ msgstr "Будь ласка, виберіть колір філаменту" @@ -37307,9 +37823,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "інструмент, якого немає в налаштуваннях" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "Завершальний G-code, коли закінчити весь друк" - #~ msgid "Maximum X speed" #~ msgstr "Максимальна швидкість X" @@ -37326,26 +37839,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "Плагіни Python, що викликаються на кожному кроці конвеєра нарізки для читання та зміни проміжних даних нарізки, включно з фінальним кроком постобробки G-code. Дослідницьке/експериментальне." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Якщо увімкнено, слайсер генерує G-code із вмістом основної зони, відцентрованим відносно початку координат столу (0,0). За розміщення копій і дзеркальних відображень у кожній фізичній зоні відповідає прошивка принтера. Вмикайте лише на принтерах, прошивка яких сама застосовує зміщення зон у режимі копії чи дзеркала (наприклад, режим дублювання IDEX у RepRapFirmware). Не діє в режимі «Основний»." - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Перевизначення для пластини, що зіставляє фізичні головки зі слотами філаменту (нумерація з 1). Порожнє значення означає типові значення з інверсії pem." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Вісь, навколо якої сітку повертають перед нарізкою. Це нахил стрічкового принтера: ізометричне (без спотворень) обертання, яке також визначає відображення столу й нахил сили тяжіння для підтримок і яке зворотне перетворення G-code скасовує перед зсувом/масштабуванням і перепризначенням осей у машинній системі координат. X — типовий нахил порталу (стрічка рухається вздовж Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Експертне перевизначення: задає кут нахилу машинної системи координат (зсув/масштаб G-code) незалежно від кута повороту перед нарізкою. Якщо вимкнено, перетворення машинної системи координат обчислюється з кута нахилу стрічки, тож один кут керує обома етапами. Вмикайте лише для компенсації машини, фізичний нахил порталу якої відрізняється від повороту під час нарізки." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Максимальне відхилення, дозволене при зниженні роздільності для налаштування «Максимальна роздільність стінки». Якщо його збільшити, друк буде менш точним, але G-code — меншим. «Максимальне відхилення стінки» обмежує «Максимальну роздільність стінки», тож у разі конфлікту пріоритет має «Максимальне відхилення стінки»." - #~ msgid " not in range " #~ msgstr " не в зоні " diff --git a/localization/i18n/vi/OrcaSlicer_vi.po b/localization/i18n/vi/OrcaSlicer_vi.po index 348289eec2..5c7f337df0 100644 --- a/localization/i18n/vi/OrcaSlicer_vi.po +++ b/localization/i18n/vi/OrcaSlicer_vi.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2025-10-02 17:43+0700\n" "Last-Translator: \n" "Language-Team: hainguyen.ts13@gmail.com\n" @@ -836,18 +836,21 @@ msgstr "Lựa chọn" msgid "Plate" msgstr "Plate" +# AI Translated msgid "Distribute" -msgstr "" +msgstr "Phân bố" # AI Translated msgid "Coordinate system used for transform actions." msgstr "Hệ tọa độ dùng cho các thao tác biến đổi." +# AI Translated msgid "Reference for alignment" -msgstr "" +msgstr "Tham chiếu để căn chỉnh" +# AI Translated msgid "Select at least 3 parts or objects" -msgstr "" +msgstr "Chọn ít nhất 3 phần hoặc vật thể" # AI Translated msgid "Align left" @@ -901,8 +904,9 @@ msgstr "Phân bố trên-dưới" msgid "Drop" msgstr "Thả xuống" +# AI Translated msgid "Move the selection along Z so that its lowest point touches the bed." -msgstr "" +msgstr "Di chuyển vùng chọn theo trục Z để điểm thấp nhất chạm bàn in." # AI Translated msgid "Absolute" @@ -1804,7 +1808,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "Nét của hình (%1%) chứa không hỗ trợ: %2%." # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "Trạng thái không hợp lệ, vui lòng báo cáo các bước tái hiện lỗi trên GitHub" # AI Translated @@ -1812,11 +1816,11 @@ msgid "No embossed file" msgstr "Không có file emboss" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "Thiếu file SVG trong hình emboss" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "Thiếu dữ liệu của file SVG" msgid "Face the camera" @@ -2147,17 +2151,21 @@ msgstr "Đang vào gizmo Lắp ráp" msgid "Leaving Assembly gizmo" msgstr "Đang rời gizmo Lắp ráp" +# AI Translated msgid "Parts of a cut object cannot be moved" -msgstr "" +msgstr "Không thể di chuyển các phần của vật thể đã cắt" +# AI Translated msgid "Aligning to the plate is available in X and Y only" -msgstr "" +msgstr "Căn chỉnh theo plate chỉ khả dụng theo X và Y" +# AI Translated msgid "Turn off Auto-Drop for the selected objects to move them in Z" -msgstr "" +msgstr "Tắt Tự động thả cho các vật thể đã chọn để di chuyển chúng theo Z" +# AI Translated msgid "All selected objects must be on the same plate" -msgstr "" +msgstr "Tất cả vật thể đã chọn phải ở trên cùng một plate" msgid "Shift+" msgstr "Shift+" @@ -5204,7 +5212,7 @@ msgstr "Vui lòng lưu dự án và khởi động lại chương trình." msgid "Unknown C++ exception." msgstr "Ngoại lệ C++ không xác định." -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "Đang xử lý G-code từ file trước..." msgid "Slicing complete" @@ -6843,8 +6851,9 @@ msgstr "Trục tọa độ" msgid "Gridlines" msgstr "Đường lưới" +# AI Translated msgid "Focus mode" -msgstr "" +msgstr "Chế độ tập trung" # AI Translated msgid "Labels" @@ -6906,7 +6915,7 @@ msgstr "Thể tích:" msgid "Size:" msgstr "Kích thước:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "Đã tìm thấy xung đột đường đi G-code tại lớp %d, Z = %.2lfmm. Vui lòng tách các vật thể xung đột ra xa hơn (%s <-> %s)." @@ -11460,11 +11469,14 @@ msgstr "Hiện cài đặt sẵn không được hỗ trợ" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "Hiện các cài đặt sẵn không tương thích/không được hỗ trợ trong danh sách thả xuống máy in và filament. Không thể chọn các cài đặt sẵn này." +# AI Translated msgid "Export statistics with G-code" -msgstr "" +msgstr "Xuất thống kê cùng với G-code" +# AI Translated +# Needs human review: "feature" rendered as line type (ประเภทเส้น / Loại đường); check this matches the per-feature totals in the exported JSON msgid "If enabled, exporting a G-code file also writes its statistics as JSON next to it, as .statistics.json, and an exported sliced 3MF file holds them inside: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Nếu bật, khi xuất file G-code, thống kê của nó cũng được ghi dưới dạng JSON cạnh file đó, với tên .statistics.json, và file 3MF đã slice được xuất sẽ chứa chúng bên trong: thời gian in, tổng filament và tổng theo loại đường, cùng số liệu tương tự theo từng lớp và từng vật thể." # AI Translated msgid "Experimental Features" @@ -12352,6 +12364,10 @@ msgstr "Tải file lên bộ nhớ của máy in thất bại. Vui lòng thử l msgid "Send Failed" msgstr "Gửi thất bại" +# AI Translated +msgid "No available printers" +msgstr "Không có máy in khả dụng" + msgid "The name length exceeds the limit." msgstr "Độ dài tên vượt quá giới hạn." @@ -14300,8 +14316,8 @@ msgid "Left mouse" msgstr "Chuột trái" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "Khả dụng ở mọi nơi trong cửa sổ, kể cả khi đang gõ trong ô văn bản." +msgid "Available anywhere in the window." +msgstr "Khả dụng ở mọi nơi trong cửa sổ." # AI Translated msgid "Run favorite 1 to 10" @@ -14414,10 +14430,6 @@ msgstr "%s đã được gán cho %s. Gán lại cho %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "%s mặc định đã được gán cho %s. Gán lại cho %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "Phím tắt toàn cục cũng có tác dụng khi đang gõ." - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "Phím gõ ra ký tự không thể là phím tắt toàn cục." @@ -14882,9 +14894,10 @@ msgstr "modifier \"%1%\" của \"%2%\" (tổng cộng %3%) không có tác dụn msgid "Seam placement may differ from expected." msgstr "Vị trí đường nối có thể khác với dự kiến." +# AI Translated #, boost-format msgid "Failed to write the G-code statistics to %1%." -msgstr "" +msgstr "Không thể ghi thống kê G-code vào %1%." msgid "Internal Bridge" msgstr "Cầu bên trong" @@ -18376,6 +18389,14 @@ msgstr "Loại trừ đối tượng" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "Bật tùy chọn này để thêm lệnh EXCLUDE OBJECT vào G-code." +# AI Translated +msgid "Outline tolerance" +msgstr "Dung sai đường viền" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "Độ lệch tối đa của đường viền vật thể được ghi vào EXCLUDE_OBJECT_DEFINE so với đường viền gốc. Giá trị lớn hơn cho ít điểm hơn, giúp ích cho firmware bị treo khi phân tích G-code có nhiều vật thể. 0 giữ lại mọi điểm." + msgid "Verbose G-code" msgstr "G-code chi tiết" @@ -21664,11 +21685,14 @@ msgstr "Thư mục đầu ra" msgid "This is the output directory for exported files." msgstr "Thư mục đầu ra cho các file được xuất." +# AI Translated msgid "Export statistics" -msgstr "" +msgstr "Xuất thống kê" +# AI Translated +# Needs human review: "feature" rendered as line type (ประเภทเส้น / Loại đường); check this matches the per-feature totals in the exported JSON msgid "Write the statistics of each sliced plate as JSON, as plate_N.statistics.json next to its G-code in the output directory and inside the 3MF of --export-3mf: print time, filament and feature totals, and the same per layer and per object." -msgstr "" +msgstr "Ghi thống kê của từng plate đã slice dưới dạng JSON, là plate_N.statistics.json cạnh file G-code của nó trong thư mục đầu ra và bên trong file 3MF của --export-3mf: thời gian in, tổng filament và tổng theo loại đường, cùng số liệu tương tự theo từng lớp và từng vật thể." msgid "Debug level" msgstr "Mức gỡ lỗi" @@ -24140,7 +24164,7 @@ msgstr "bắt đầu kiểm tra %s..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "kiểm tra %s: đã phân giải IP = %s" # AI Translated @@ -31675,1231 +31699,1641 @@ msgid "The current filament list does not contain %s. A project filament require msgid_plural "The current filament list does not contain %s. Project filaments required by the mixed filament will be created automatically after decomposition." msgstr[0] "Danh sách filament hiện tại không chứa %s. Một filament dự án mà filament pha trộn cần sẽ được tạo tự động sau khi phân tách." +# AI Translated msgid "Color Picker" -msgstr "" +msgstr "Bộ chọn màu" +# AI Translated msgid "Basic Colors" -msgstr "" - -msgid "Orca Palette" -msgstr "" +msgstr "Màu cơ bản" +# AI Translated #. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. -msgid "RAL Classic" -msgstr "" +msgid "Orca Palette" +msgstr "Bảng màu Orca" +# AI Translated #. TRN: Keep the standard/brand name "RAL" unchanged. +msgid "RAL Classic" +msgstr "RAL Cổ điển" + +# AI Translated msgid "Gradients" -msgstr "" +msgstr "Chuyển màu" +# AI Translated +msgctxt "Color picker" msgid "Solid" -msgstr "" +msgstr "Đơn sắc" +# AI Translated msgid "Gradient" -msgstr "" +msgstr "Chuyển màu" +# AI Translated msgid "Gradient start" -msgstr "" +msgstr "Điểm bắt đầu chuyển màu" +# AI Translated msgid "Gradient end" -msgstr "" +msgstr "Điểm kết thúc chuyển màu" +# AI Translated msgid "Gradient color" -msgstr "" +msgstr "Màu chuyển màu" +# AI Translated msgid "Add color" -msgstr "" +msgstr "Thêm màu" +# AI Translated msgid "Remove color" -msgstr "" +msgstr "Xóa màu" +# AI Translated msgid "Saturation" -msgstr "" +msgstr "Độ bão hòa" +# AI Translated msgid "Original color" -msgstr "" +msgstr "Màu gốc" +# AI Translated #. TRN: Clicking the current color preview adds it to the saved favorites. msgid "Save current color" -msgstr "" +msgstr "Lưu màu hiện tại" +# AI Translated msgid "Palettes" -msgstr "" +msgstr "Bảng màu" +# AI Translated msgid "Search colors" -msgstr "" +msgstr "Tìm màu" +# AI Translated msgid "Filter colors" -msgstr "" +msgstr "Lọc màu" +# AI Translated msgid "No matching colors" -msgstr "" +msgstr "Không có màu phù hợp" +# AI Translated msgid "Hex color" -msgstr "" +msgstr "Màu hex" # AI Translated msgid "Opacity" msgstr "Độ đục" +# AI Translated msgid "Opacity percent" -msgstr "" +msgstr "Phần trăm độ đục" +# AI Translated msgid "Save color" -msgstr "" +msgstr "Lưu màu" +# AI Translated msgid "Enter a complete hexadecimal color" -msgstr "" +msgstr "Nhập đầy đủ màu thập lục phân" +# AI Translated msgid "The current multi-color selection is kept until you choose a different color." -msgstr "" +msgstr "Lựa chọn nhiều màu hiện tại được giữ lại cho đến khi bạn chọn màu khác." +# AI Translated #, c-format, boost-format msgid "Up to %d colors supported." -msgstr "" +msgstr "Hỗ trợ tối đa %d màu." +# AI Translated msgid "Crimson" -msgstr "" +msgstr "Đỏ thẫm" +# AI Translated msgid "Orange red" -msgstr "" +msgstr "Đỏ cam" +# AI Translated msgid "Tomato" -msgstr "" +msgstr "Đỏ cà chua" +# AI Translated msgid "Orange" -msgstr "" +msgstr "Cam" +# AI Translated msgid "Dark orange" -msgstr "" +msgstr "Cam đậm" +# AI Translated msgid "Gold" -msgstr "" +msgstr "Vàng kim" +# AI Translated msgid "Burly wood" -msgstr "" +msgstr "Nâu gỗ nhạt" +# AI Translated msgid "Bisque" -msgstr "" +msgstr "Kem cam" +# AI Translated msgid "Misty rose" -msgstr "" +msgstr "Hồng sương" +# AI Translated msgid "Light yellow" -msgstr "" +msgstr "Vàng nhạt" +# AI Translated msgid "Lemon chiffon" -msgstr "" +msgstr "Kem chanh" +# AI Translated msgid "Beige" -msgstr "" +msgstr "Be" +# AI Translated msgid "Light golden rod yellow" -msgstr "" +msgstr "Vàng nghệ sáng" +# AI Translated msgid "Pale golden rod" -msgstr "" +msgstr "Vàng nghệ dịu" +# AI Translated msgid "Khaki" -msgstr "" +msgstr "Kaki" +# AI Translated msgid "Dark khaki" -msgstr "" +msgstr "Kaki đậm" +# AI Translated msgid "Peach puff" -msgstr "" +msgstr "Đào nhạt" +# AI Translated msgid "Moccasin" -msgstr "" +msgstr "Vàng da hươu" +# AI Translated msgid "Papaya whip" -msgstr "" +msgstr "Kem đu đủ" +# AI Translated msgid "Blanched almond" -msgstr "" +msgstr "Hạnh nhân lột vỏ" +# AI Translated msgid "Antique white" -msgstr "" +msgstr "Trắng cổ" +# AI Translated msgid "Navajo white" -msgstr "" +msgstr "Trắng Navajo" +# AI Translated msgid "Wheat" -msgstr "" +msgstr "Lúa mì" +# AI Translated msgid "Golden rod" -msgstr "" +msgstr "Vàng nghệ" +# AI Translated msgid "Chocolate" -msgstr "" +msgstr "Sô-cô-la" +# AI Translated msgid "Peru" -msgstr "" +msgstr "Nâu Peru" +# AI Translated msgid "Fire brick" -msgstr "" +msgstr "Gạch chịu lửa" +# AI Translated msgid "Sienna" -msgstr "" +msgstr "Nâu sienna" +# AI Translated msgid "Saddle brown" -msgstr "" +msgstr "Nâu yên ngựa" +# AI Translated msgid "Brown" -msgstr "" +msgstr "Nâu" +# AI Translated msgid "Rosy brown" -msgstr "" +msgstr "Nâu hồng" +# AI Translated msgid "Salmon" -msgstr "" +msgstr "Cá hồi" +# AI Translated msgid "Light salmon" -msgstr "" +msgstr "Cá hồi nhạt" +# AI Translated msgid "Dark salmon" -msgstr "" +msgstr "Cá hồi đậm" +# AI Translated msgid "Sandy brown" -msgstr "" +msgstr "Nâu cát" +# AI Translated msgid "Coral" -msgstr "" +msgstr "San hô" +# AI Translated msgid "Light coral" -msgstr "" +msgstr "San hô nhạt" +# AI Translated msgid "Indian red" -msgstr "" +msgstr "Đỏ Ấn Độ" +# AI Translated msgid "Dark red" -msgstr "" +msgstr "Đỏ đậm" +# AI Translated msgid "Maroon" -msgstr "" +msgstr "Nâu đỏ sẫm" +# AI Translated msgid "Green yellow" -msgstr "" +msgstr "Vàng lục" +# AI Translated msgid "Yellow green" -msgstr "" +msgstr "Xanh lá vàng" +# AI Translated msgid "Chartreuse" -msgstr "" +msgstr "Chartreuse" +# AI Translated msgid "Lawn green" -msgstr "" +msgstr "Xanh thảm cỏ" +# AI Translated msgid "Lime green" -msgstr "" +msgstr "Xanh lá chanh" +# AI Translated msgid "Spring green" -msgstr "" +msgstr "Xanh lá mùa xuân" +# AI Translated msgid "Medium spring green" -msgstr "" +msgstr "Xanh lá mùa xuân vừa" +# AI Translated msgid "Lime" -msgstr "" +msgstr "Xanh chanh" +# AI Translated msgid "Forest green" -msgstr "" +msgstr "Xanh lá rừng" +# AI Translated msgid "Dark green" -msgstr "" +msgstr "Xanh lá đậm" +# AI Translated msgid "Olive drab" -msgstr "" +msgstr "Xanh ô liu xỉn" +# AI Translated msgid "Olive" -msgstr "" +msgstr "Ô liu" +# AI Translated msgid "Dark olive green" -msgstr "" +msgstr "Xanh lá ô liu đậm" +# AI Translated msgid "Pale green" -msgstr "" +msgstr "Xanh lá dịu" +# AI Translated msgid "Light green" -msgstr "" +msgstr "Xanh lá nhạt" +# AI Translated msgid "Medium sea green" -msgstr "" +msgstr "Xanh lá biển vừa" +# AI Translated msgid "Sea green" -msgstr "" +msgstr "Xanh lá biển" +# AI Translated msgid "Dark sea green" -msgstr "" +msgstr "Xanh lá biển đậm" +# AI Translated msgid "Cadet blue" -msgstr "" +msgstr "Xanh dương cadet" +# AI Translated msgid "Medium aqua marine" -msgstr "" +msgstr "Aquamarine vừa" +# AI Translated msgid "Turquoise" -msgstr "" +msgstr "Ngọc lam" +# AI Translated msgid "Medium turquoise" -msgstr "" +msgstr "Ngọc lam vừa" +# AI Translated msgid "Dark turquoise" -msgstr "" +msgstr "Ngọc lam đậm" +# AI Translated msgid "Pale turquoise" -msgstr "" +msgstr "Ngọc lam dịu" +# AI Translated msgid "Aqua" -msgstr "" +msgstr "Aqua" +# AI Translated msgid "Light cyan" -msgstr "" +msgstr "Xanh lơ nhạt" +# AI Translated msgid "Mint cream" -msgstr "" +msgstr "Kem bạc hà" +# AI Translated msgid "Honey dew" -msgstr "" +msgstr "Dưa mật" +# AI Translated msgid "Aquamarine" -msgstr "" +msgstr "Aquamarine" +# AI Translated msgid "Light sea green" -msgstr "" +msgstr "Xanh lá biển nhạt" +# AI Translated msgid "Dark cyan" -msgstr "" +msgstr "Xanh lơ đậm" +# AI Translated msgid "Teal" -msgstr "" +msgstr "Xanh mòng két" +# AI Translated msgid "Dark slate gray" -msgstr "" +msgstr "Xám đá phiến đậm" +# AI Translated msgid "Light slate gray" -msgstr "" +msgstr "Xám đá phiến nhạt" +# AI Translated msgid "Slate gray" -msgstr "" +msgstr "Xám đá phiến" +# AI Translated msgid "Deep sky blue" -msgstr "" +msgstr "Xanh da trời đậm" +# AI Translated msgid "Dodger Blue" -msgstr "" +msgstr "Xanh dương Dodger" +# AI Translated msgid "Sky blue" -msgstr "" +msgstr "Xanh da trời" +# AI Translated msgid "Light sky blue" -msgstr "" +msgstr "Xanh da trời nhạt" +# AI Translated msgid "Light blue" -msgstr "" +msgstr "Xanh dương nhạt" +# AI Translated msgid "Powder blue" -msgstr "" +msgstr "Xanh dương phấn" +# AI Translated msgid "Light steel blue" -msgstr "" +msgstr "Xanh thép nhạt" +# AI Translated msgid "Steel blue" -msgstr "" +msgstr "Xanh thép" +# AI Translated msgid "Cornflower blue" -msgstr "" +msgstr "Xanh dương cornflower" +# AI Translated msgid "Royal blue" -msgstr "" +msgstr "Xanh hoàng gia" +# AI Translated msgid "Medium blue" -msgstr "" +msgstr "Xanh dương vừa" +# AI Translated msgid "Midnight blue" -msgstr "" +msgstr "Xanh dương nửa đêm" +# AI Translated msgid "Dark blue" -msgstr "" +msgstr "Xanh dương đậm" +# AI Translated msgid "Navy" -msgstr "" +msgstr "Xanh navy" +# AI Translated msgid "Slate blue" -msgstr "" +msgstr "Xanh dương đá phiến" +# AI Translated msgid "Dark slate blue" -msgstr "" +msgstr "Xanh dương đá phiến đậm" +# AI Translated msgid "Medium slate blue" -msgstr "" +msgstr "Xanh dương đá phiến vừa" +# AI Translated msgid "Blue violet" -msgstr "" +msgstr "Tím lam" +# AI Translated msgid "Indigo" -msgstr "" +msgstr "Chàm" +# AI Translated msgid "Dark violet" -msgstr "" +msgstr "Tím violet đậm" +# AI Translated msgid "Dark orchid" -msgstr "" +msgstr "Lan đậm" +# AI Translated msgid "Medium orchid" -msgstr "" +msgstr "Lan vừa" +# AI Translated msgid "Orchid" -msgstr "" +msgstr "Lan" +# AI Translated msgid "Violet" -msgstr "" +msgstr "Tím violet" +# AI Translated msgid "Medium purple" -msgstr "" +msgstr "Tím vừa" +# AI Translated msgid "Purple" -msgstr "" +msgstr "Tím" +# AI Translated msgid "Rebecca purple" -msgstr "" +msgstr "Tím Rebecca" +# AI Translated msgid "Medium violet red" -msgstr "" +msgstr "Đỏ tím vừa" -msgid "PaleV violet red" -msgstr "" +# AI Translated +msgid "Pale violet red" +msgstr "Đỏ tím dịu" +# AI Translated msgid "Deep pink" -msgstr "" +msgstr "Hồng đậm" +# AI Translated msgid "Hot pink" -msgstr "" +msgstr "Hồng tươi" +# AI Translated msgid "Light pink" -msgstr "" +msgstr "Hồng nhạt" +# AI Translated msgid "Pink" -msgstr "" +msgstr "Hồng" +# AI Translated msgid "Plum" -msgstr "" +msgstr "Mận" +# AI Translated msgid "Thistle" -msgstr "" +msgstr "Tím kế" +# AI Translated msgid "Fuchsia" -msgstr "" +msgstr "Fuchsia" +# AI Translated msgid "Dark magenta" -msgstr "" +msgstr "Magenta đậm" +# AI Translated msgid "Linen" -msgstr "" +msgstr "Vải lanh" +# AI Translated msgid "Old lace" -msgstr "" +msgstr "Ren cũ" +# AI Translated msgid "Sea shell" -msgstr "" +msgstr "Vỏ sò" +# AI Translated msgid "Ivory" -msgstr "" +msgstr "Ngà" +# AI Translated msgid "Floral white" -msgstr "" +msgstr "Trắng hoa" +# AI Translated msgid "Lavender blush" -msgstr "" +msgstr "Oải hương ửng hồng" +# AI Translated msgid "Ghost white" -msgstr "" +msgstr "Trắng bóng ma" +# AI Translated msgid "Alice blue" -msgstr "" +msgstr "Xanh Alice" +# AI Translated msgid "Lavender" -msgstr "" +msgstr "Oải hương" +# AI Translated msgid "White smoke" -msgstr "" +msgstr "Trắng khói" +# AI Translated msgid "Gainsboro" -msgstr "" +msgstr "Gainsboro" +# AI Translated msgid "Black" -msgstr "" +msgstr "Đen" +# AI Translated msgid "Coral fire" -msgstr "" +msgstr "San hô lửa" +# AI Translated msgid "Sea anemone" -msgstr "" +msgstr "Hải quỳ" +# AI Translated msgid "Deep abyss" -msgstr "" +msgstr "Vực sâu" +# AI Translated msgid "Lobster red" -msgstr "" +msgstr "Đỏ tôm hùm" +# AI Translated msgid "Sandy clay" -msgstr "" +msgstr "Đất sét cát" +# AI Translated msgid "Driftwood" -msgstr "" +msgstr "Gỗ trôi dạt" +# AI Translated msgid "Sea buckthorn" -msgstr "" +msgstr "Hắc mai biển" +# AI Translated msgid "Sunset reef" -msgstr "" +msgstr "Rạn san hô hoàng hôn" +# AI Translated msgid "Tiger coral" -msgstr "" +msgstr "San hô hổ" +# AI Translated msgid "Pink coral" -msgstr "" +msgstr "San hô hồng" +# AI Translated msgid "Seashell glow" -msgstr "" +msgstr "Ánh vỏ sò" +# AI Translated msgid "Sand" -msgstr "" +msgstr "Cát" +# AI Translated msgid "Golden kelp" -msgstr "" +msgstr "Tảo bẹ vàng" +# AI Translated msgid "Sunlit dune" -msgstr "" +msgstr "Cồn cát nắng" +# AI Translated msgid "Amber nautilus" -msgstr "" +msgstr "Ốc anh vũ hổ phách" +# AI Translated msgid "Sea lemon" -msgstr "" +msgstr "Chanh biển" +# AI Translated msgid "Pale starfish" -msgstr "" +msgstr "Sao biển dịu" +# AI Translated msgid "Spring tide" -msgstr "" +msgstr "Triều cường" +# AI Translated msgid "Lime algae" -msgstr "" +msgstr "Tảo xanh chanh" +# AI Translated msgid "Sea grass" -msgstr "" +msgstr "Cỏ biển" +# AI Translated msgid "Neon plankton" -msgstr "" +msgstr "Sinh vật phù du neon" +# AI Translated msgid "Kelp forest" -msgstr "" +msgstr "Rừng tảo bẹ" +# AI Translated msgid "Emerald wave" -msgstr "" +msgstr "Sóng ngọc lục bảo" +# AI Translated msgid "Whale shadow" -msgstr "" +msgstr "Bóng cá voi" +# AI Translated msgid "Sea turtle" -msgstr "" +msgstr "Rùa biển" +# AI Translated msgid "Lagoon" -msgstr "" +msgstr "Đầm phá" +# AI Translated msgid "Tropical current" -msgstr "" +msgstr "Dòng hải lưu nhiệt đới" +# AI Translated msgid "Midnight trench" -msgstr "" +msgstr "Rãnh biển nửa đêm" +# AI Translated msgid "Dark kelp" -msgstr "" +msgstr "Tảo bẹ đậm" +# AI Translated msgid "Crystal surf" -msgstr "" +msgstr "Sóng pha lê" +# AI Translated msgid "Turquoise bay" -msgstr "" +msgstr "Vịnh ngọc lam" +# AI Translated msgid "Sky over reef" -msgstr "" +msgstr "Bầu trời trên rạn san hô" +# AI Translated msgid "Shallow sky" -msgstr "" +msgstr "Bầu trời nước nông" -msgid "Electric bel" -msgstr "" +# AI Translated +msgid "Electric blue" +msgstr "Xanh dương điện" +# AI Translated msgid "Dolphin" -msgstr "" +msgstr "Cá heo" +# AI Translated msgid "Ocean depths" -msgstr "" +msgstr "Độ sâu đại dương" +# AI Translated msgid "Whale" -msgstr "" +msgstr "Cá voi" +# AI Translated msgid "Indigo abyss" -msgstr "" +msgstr "Vực sâu chàm" +# AI Translated msgid "Sea urchin" -msgstr "" +msgstr "Nhím biển" +# AI Translated msgid "Lavender coral" -msgstr "" +msgstr "San hô oải hương" +# AI Translated msgid "Violet tide" -msgstr "" +msgstr "Thủy triều tím" +# AI Translated msgid "Deep sea orchid" -msgstr "" +msgstr "Lan biển sâu" +# AI Translated msgid "Neon jelly" -msgstr "" +msgstr "Sứa neon" +# AI Translated msgid "Fuchsia coral" -msgstr "" +msgstr "San hô fuchsia" +# AI Translated msgid "Pink jellyfish" -msgstr "" +msgstr "Sứa hồng" +# AI Translated msgid "Foam" -msgstr "" +msgstr "Bọt sóng" +# AI Translated msgid "Seashell white" -msgstr "" +msgstr "Trắng vỏ sò" +# AI Translated msgid "Pebble gray" -msgstr "" +msgstr "Xám sỏi" +# AI Translated msgid "Storm cloud" -msgstr "" +msgstr "Mây bão" +# AI Translated msgid "Ink black" -msgstr "" +msgstr "Đen mực" +# AI Translated msgid "Green beige" -msgstr "" +msgstr "Be lục" +# AI Translated msgid "Sand yellow" -msgstr "" +msgstr "Vàng cát" +# AI Translated msgid "Signal yellow" -msgstr "" +msgstr "Vàng tín hiệu" +# AI Translated msgid "Golden yellow" -msgstr "" +msgstr "Vàng óng" +# AI Translated msgid "Honey yellow" -msgstr "" +msgstr "Vàng mật ong" +# AI Translated msgid "Maize yellow" -msgstr "" +msgstr "Vàng ngô" -msgid "Dalmatian yellow" -msgstr "" +# AI Translated +msgid "Daffodil yellow" +msgstr "Vàng thủy tiên" +# AI Translated msgid "Brown beige" -msgstr "" +msgstr "Be nâu" +# AI Translated msgid "Lemon yellow" -msgstr "" +msgstr "Vàng chanh" +# AI Translated msgid "Oyster white" -msgstr "" +msgstr "Trắng hàu" +# AI Translated msgid "Light ivory" -msgstr "" +msgstr "Ngà nhạt" +# AI Translated msgid "Zinc yellow" -msgstr "" +msgstr "Vàng kẽm" +# AI Translated msgid "Grey beige" -msgstr "" +msgstr "Be xám" +# AI Translated msgid "Olive yellow" -msgstr "" +msgstr "Vàng ô liu" +# AI Translated msgid "Rape yellow" -msgstr "" +msgstr "Vàng cải dầu" +# AI Translated msgid "Traffic yellow" -msgstr "" +msgstr "Vàng giao thông" +# AI Translated msgid "Ochre yellow" -msgstr "" +msgstr "Vàng ocher" +# AI Translated msgid "Traffic orange yellow" -msgstr "" +msgstr "Vàng cam giao thông" +# AI Translated msgid "Curry" -msgstr "" +msgstr "Cà ri" +# AI Translated msgid "Melon yellow" -msgstr "" +msgstr "Vàng dưa" +# AI Translated msgid "Broom yellow" -msgstr "" +msgstr "Vàng hoa chổi" +# AI Translated msgid "Dahlia yellow" -msgstr "" +msgstr "Vàng thược dược" +# AI Translated msgid "Pastel yellow" -msgstr "" +msgstr "Vàng pastel" +# AI Translated msgid "Pearl beige" -msgstr "" +msgstr "Be xà cừ" +# AI Translated msgid "Pearl gold" -msgstr "" +msgstr "Vàng kim xà cừ" +# AI Translated msgid "Sun yellow" -msgstr "" +msgstr "Vàng mặt trời" +# AI Translated msgid "Yellow orange" -msgstr "" +msgstr "Cam vàng" +# AI Translated msgid "Deep orange" -msgstr "" +msgstr "Cam sẫm" +# AI Translated msgid "Vermilion" -msgstr "" +msgstr "Đỏ son" +# AI Translated msgid "Pearl orange" -msgstr "" +msgstr "Cam xà cừ" +# AI Translated msgid "Pure orange" -msgstr "" +msgstr "Cam tinh khiết" +# AI Translated msgid "Luminous orange" -msgstr "" +msgstr "Cam huỳnh quang" +# AI Translated msgid "Luminous bright orange" -msgstr "" +msgstr "Cam huỳnh quang tươi" +# AI Translated msgid "Bright red orange" -msgstr "" +msgstr "Cam đỏ tươi" +# AI Translated msgid "Traffic orange" -msgstr "" +msgstr "Cam giao thông" +# AI Translated msgid "Signal orange" -msgstr "" +msgstr "Cam tín hiệu" +# AI Translated msgid "Salmon orange" -msgstr "" +msgstr "Cam cá hồi" +# AI Translated msgid "Pearl pink" -msgstr "" +msgstr "Hồng xà cừ" +# AI Translated msgid "Copper orange" -msgstr "" +msgstr "Cam đồng" +# AI Translated msgid "Signal brown" -msgstr "" +msgstr "Nâu tín hiệu" +# AI Translated msgid "Fir orange" -msgstr "" +msgstr "Cam linh sam" +# AI Translated msgid "Signal red" -msgstr "" +msgstr "Đỏ tín hiệu" +# AI Translated msgid "Luminous red" -msgstr "" +msgstr "Đỏ huỳnh quang" +# AI Translated msgid "Carmine red" -msgstr "" +msgstr "Đỏ carmine" +# AI Translated msgid "Pearl carmine red" -msgstr "" +msgstr "Đỏ carmine xà cừ" +# AI Translated msgid "Pure red" -msgstr "" +msgstr "Đỏ tinh khiết" +# AI Translated msgid "Luminous deep red" -msgstr "" +msgstr "Đỏ sẫm huỳnh quang" +# AI Translated msgid "Currant red" -msgstr "" +msgstr "Đỏ lý chua" +# AI Translated msgid "Pearl ruby red" -msgstr "" +msgstr "Đỏ ruby xà cừ" +# AI Translated msgid "Fire red" -msgstr "" +msgstr "Đỏ lửa" +# AI Translated msgid "Ruby red" -msgstr "" +msgstr "Đỏ ruby" +# AI Translated msgid "Purple red" -msgstr "" +msgstr "Đỏ tím" +# AI Translated msgid "Wine red" -msgstr "" +msgstr "Đỏ rượu vang" +# AI Translated msgid "Black red" -msgstr "" +msgstr "Đỏ đen" +# AI Translated msgid "Oxide red" -msgstr "" +msgstr "Đỏ oxit" +# AI Translated msgid "Brown red" -msgstr "" +msgstr "Đỏ nâu" +# AI Translated +# Needs human review: Source name "Pine red" looks unusual for a RAL color; translated literally msgid "Pine red" -msgstr "" +msgstr "Đỏ thông" +# AI Translated msgid "Tomato red" -msgstr "" +msgstr "Đỏ cà chua" +# AI Translated msgid "Antique pink" -msgstr "" +msgstr "Hồng cổ" +# AI Translated msgid "Coral red" -msgstr "" +msgstr "Đỏ san hô" +# AI Translated msgid "Rose" -msgstr "" +msgstr "Hoa hồng" +# AI Translated msgid "Strawberry red" -msgstr "" +msgstr "Đỏ dâu tây" +# AI Translated msgid "Traffic red" -msgstr "" +msgstr "Đỏ giao thông" +# AI Translated msgid "Salmon pink" -msgstr "" +msgstr "Hồng cá hồi" +# AI Translated msgid "Luminous rose" -msgstr "" +msgstr "Hoa hồng huỳnh quang" +# AI Translated msgid "Luminous bright red" -msgstr "" +msgstr "Đỏ huỳnh quang tươi" +# AI Translated msgid "Raspberry red" -msgstr "" +msgstr "Đỏ mâm xôi" +# AI Translated msgid "Orient red" -msgstr "" +msgstr "Đỏ phương Đông" +# AI Translated msgid "Pearl ruby" -msgstr "" +msgstr "Ruby xà cừ" +# AI Translated msgid "Red purple" -msgstr "" +msgstr "Tím đỏ" +# AI Translated msgid "Red violet" -msgstr "" +msgstr "Tím violet đỏ" +# AI Translated msgid "Heather violet" -msgstr "" +msgstr "Tím violet thạch nam" +# AI Translated msgid "Bordeaux violet" -msgstr "" +msgstr "Tím violet bordeaux" +# AI Translated msgid "Mahogany" -msgstr "" +msgstr "Gỗ gụ" +# AI Translated msgid "Grey purple" -msgstr "" +msgstr "Tím xám" +# AI Translated msgid "Signal violet" -msgstr "" +msgstr "Tím violet tín hiệu" +# AI Translated msgid "Fir green" -msgstr "" +msgstr "Xanh lá linh sam" +# AI Translated msgid "Sabine grey" -msgstr "" +msgstr "Xám Sabine" +# AI Translated msgid "Pearl violet" -msgstr "" +msgstr "Tím violet xà cừ" +# AI Translated msgid "Pearl blackberry" -msgstr "" +msgstr "Mâm xôi đen xà cừ" +# AI Translated msgid "Green blue" -msgstr "" +msgstr "Xanh dương lục" +# AI Translated msgid "Ultramarine blue" -msgstr "" +msgstr "Xanh dương ultramarine" +# AI Translated msgid "Sapphire blue" -msgstr "" +msgstr "Xanh dương sapphire" +# AI Translated msgid "Black blue" -msgstr "" +msgstr "Xanh dương đen" +# AI Translated msgid "Signal blue" -msgstr "" +msgstr "Xanh dương tín hiệu" +# AI Translated msgid "Brilliant blue" -msgstr "" +msgstr "Xanh dương rực rỡ" +# AI Translated msgid "Grey blue" -msgstr "" +msgstr "Xanh dương xám" +# AI Translated msgid "Azure blue" -msgstr "" +msgstr "Xanh thiên thanh" +# AI Translated msgid "Gentian blue" -msgstr "" +msgstr "Xanh dương long đởm" +# AI Translated msgid "Cobalt blue" -msgstr "" +msgstr "Xanh dương cobalt" +# AI Translated msgid "Pigeon blue" -msgstr "" +msgstr "Xanh dương bồ câu" +# AI Translated msgid "Traffic blue" -msgstr "" +msgstr "Xanh dương giao thông" +# AI Translated msgid "Turquoise blue" -msgstr "" +msgstr "Xanh dương ngọc lam" -msgid "Capsanthin violet" -msgstr "" +# AI Translated +msgid "Capri blue" +msgstr "Xanh dương Capri" +# AI Translated msgid "Ocean blue" -msgstr "" +msgstr "Xanh dương đại dương" +# AI Translated msgid "Water blue" -msgstr "" +msgstr "Xanh dương nước" +# AI Translated msgid "Night blue" -msgstr "" +msgstr "Xanh dương đêm" +# AI Translated msgid "Distant blue" -msgstr "" +msgstr "Xanh dương xa" +# AI Translated msgid "Pastel blue" -msgstr "" +msgstr "Xanh dương pastel" +# AI Translated msgid "Pearl gentian blue" -msgstr "" +msgstr "Xanh dương long đởm xà cừ" +# AI Translated msgid "Pearl midnight blue" -msgstr "" +msgstr "Xanh dương nửa đêm xà cừ" +# AI Translated msgid "Patina green" -msgstr "" +msgstr "Xanh lá gỉ đồng" +# AI Translated msgid "Emerald green" -msgstr "" +msgstr "Xanh lá ngọc lục bảo" +# AI Translated msgid "Leaf green" -msgstr "" +msgstr "Xanh diệp lục" +# AI Translated msgid "Olive green" -msgstr "" +msgstr "Xanh lá ô liu" +# AI Translated msgid "Blue green" -msgstr "" +msgstr "Xanh lá lam" +# AI Translated msgid "Moss green" -msgstr "" +msgstr "Xanh lá rêu" +# AI Translated msgid "Grey olive" -msgstr "" +msgstr "Ô liu xám" +# AI Translated msgid "Pine green" -msgstr "" +msgstr "Xanh lá thông" +# AI Translated +# Needs human review: Source name "Pine brown" looks unusual for a RAL color; translated literally msgid "Pine brown" -msgstr "" +msgstr "Nâu thông" +# AI Translated msgid "Grass green" -msgstr "" +msgstr "Xanh lá cỏ" +# AI Translated msgid "Reseda green" -msgstr "" +msgstr "Xanh lá reseda" +# AI Translated msgid "Brown green" -msgstr "" +msgstr "Xanh lá nâu" +# AI Translated msgid "Reed green" -msgstr "" +msgstr "Xanh lá lau sậy" +# AI Translated msgid "Black green" -msgstr "" +msgstr "Xanh lá đen" +# AI Translated msgid "Turquoise green" -msgstr "" +msgstr "Xanh lá ngọc lam" +# AI Translated msgid "May green" -msgstr "" +msgstr "Xanh lá tháng Năm" +# AI Translated msgid "Chrome oxide green" -msgstr "" +msgstr "Xanh lá crom oxit" +# AI Translated msgid "Traffic green" -msgstr "" +msgstr "Xanh lá giao thông" +# AI Translated msgid "Fern green" -msgstr "" +msgstr "Xanh lá dương xỉ" +# AI Translated msgid "Opal green" -msgstr "" +msgstr "Xanh lá opal" +# AI Translated msgid "Mint green" -msgstr "" +msgstr "Xanh lá bạc hà" +# AI Translated msgid "Bronze green" -msgstr "" +msgstr "Xanh lá đồng thanh" +# AI Translated msgid "Pearl green" -msgstr "" +msgstr "Xanh lá xà cừ" +# AI Translated +# Needs human review: Unusual source name ("Sax turquoise"); translated literally msgid "Sax turquoise" -msgstr "" +msgstr "Ngọc lam Sax" +# AI Translated msgid "Pearl turquoise" -msgstr "" +msgstr "Ngọc lam xà cừ" +# AI Translated msgid "Pearl jade" -msgstr "" +msgstr "Ngọc bích xà cừ" +# AI Translated msgid "Pure green" -msgstr "" +msgstr "Xanh lá tinh khiết" +# AI Translated msgid "Luminous green" -msgstr "" +msgstr "Xanh lá huỳnh quang" +# AI Translated msgid "Squirrel grey" -msgstr "" +msgstr "Xám sóc" +# AI Translated msgid "Silver grey" -msgstr "" +msgstr "Xám bạc" -msgid "Olivestone" -msgstr "" +# AI Translated +msgid "Olive grey" +msgstr "Xám ô liu" +# AI Translated msgid "Moss grey" -msgstr "" +msgstr "Xám rêu" +# AI Translated msgid "Signal grey" -msgstr "" +msgstr "Xám tín hiệu" +# AI Translated msgid "Mouse grey" -msgstr "" +msgstr "Xám chuột" +# AI Translated msgid "Beige grey" -msgstr "" +msgstr "Xám be" +# AI Translated msgid "Khaki grey" -msgstr "" +msgstr "Xám kaki" +# AI Translated msgid "Green grey" -msgstr "" +msgstr "Xám lục" +# AI Translated msgid "Tarpaulin grey" -msgstr "" +msgstr "Xám bạt" +# AI Translated msgid "Iron grey" -msgstr "" +msgstr "Xám sắt" +# AI Translated msgid "Basalt grey" -msgstr "" +msgstr "Xám bazan" +# AI Translated msgid "Brown grey" -msgstr "" +msgstr "Xám nâu" +# AI Translated msgid "Slate grey" -msgstr "" +msgstr "Xám đá phiến" +# AI Translated msgid "Anthracite grey" -msgstr "" +msgstr "Xám antraxit" +# AI Translated msgid "Light grey" -msgstr "" +msgstr "Xám nhạt" +# AI Translated msgid "Umber grey" -msgstr "" +msgstr "Xám umber" +# AI Translated msgid "Concrete grey" -msgstr "" +msgstr "Xám bê tông" +# AI Translated msgid "Graphite grey" -msgstr "" +msgstr "Xám than chì" +# AI Translated msgid "Granite grey" -msgstr "" +msgstr "Xám đá granit" +# AI Translated msgid "Stone grey" -msgstr "" +msgstr "Xám đá" +# AI Translated msgid "Pebble grey" -msgstr "" +msgstr "Xám sỏi" +# AI Translated msgid "Cement grey" -msgstr "" +msgstr "Xám xi măng" +# AI Translated msgid "Yellow grey" -msgstr "" +msgstr "Xám vàng" +# AI Translated msgid "Platinum grey" -msgstr "" +msgstr "Xám bạch kim" +# AI Translated msgid "Dusty grey" -msgstr "" +msgstr "Xám bụi" +# AI Translated msgid "Agate grey" -msgstr "" +msgstr "Xám mã não" +# AI Translated msgid "Quartz grey" -msgstr "" +msgstr "Xám thạch anh" +# AI Translated msgid "Window grey" -msgstr "" +msgstr "Xám cửa sổ" +# AI Translated msgid "Traffic grey A" -msgstr "" +msgstr "Xám giao thông A" +# AI Translated msgid "Traffic grey B" -msgstr "" +msgstr "Xám giao thông B" +# AI Translated msgid "Silk grey" -msgstr "" +msgstr "Xám lụa" +# AI Translated msgid "Telegrey 1" -msgstr "" +msgstr "Telegrey 1" +# AI Translated msgid "Telegrey 2" -msgstr "" +msgstr "Telegrey 2" +# AI Translated msgid "Telegrey 4" -msgstr "" +msgstr "Telegrey 4" +# AI Translated msgid "Pearl mouse grey" -msgstr "" +msgstr "Xám chuột xà cừ" +# AI Translated msgid "Green brown" -msgstr "" +msgstr "Nâu lục" +# AI Translated msgid "Ochre brown" -msgstr "" +msgstr "Nâu ocher" +# AI Translated msgid "Clay brown" -msgstr "" +msgstr "Nâu đất sét" +# AI Translated msgid "Copper brown" -msgstr "" +msgstr "Nâu đồng" +# AI Translated msgid "Chocolate brown" -msgstr "" +msgstr "Nâu sô-cô-la" +# AI Translated msgid "Olive brown" -msgstr "" +msgstr "Nâu ô liu" +# AI Translated msgid "Nut brown" -msgstr "" +msgstr "Nâu quả hạch" +# AI Translated msgid "Red brown" -msgstr "" +msgstr "Nâu đỏ" +# AI Translated msgid "Sepia brown" -msgstr "" +msgstr "Nâu sepia" +# AI Translated msgid "Chestnut brown" -msgstr "" +msgstr "Nâu hạt dẻ" +# AI Translated msgid "Mahogany brown" -msgstr "" +msgstr "Nâu gỗ gụ" +# AI Translated msgid "Grey brown" -msgstr "" +msgstr "Nâu xám" +# AI Translated msgid "Pearl copper" -msgstr "" +msgstr "Đồng xà cừ" +# AI Translated msgid "Beige brown" -msgstr "" +msgstr "Nâu be" +# AI Translated msgid "Pearl mocha brown" -msgstr "" +msgstr "Nâu mocha xà cừ" +# AI Translated msgid "Earth brown" -msgstr "" +msgstr "Nâu đất" +# AI Translated msgid "Pearl brown" -msgstr "" +msgstr "Nâu xà cừ" +# AI Translated msgid "Cream" -msgstr "" +msgstr "Kem" +# AI Translated msgid "Grey white" -msgstr "" +msgstr "Trắng xám" +# AI Translated msgid "Signal white" -msgstr "" +msgstr "Trắng tín hiệu" +# AI Translated msgid "Signal black" -msgstr "" +msgstr "Đen tín hiệu" +# AI Translated msgid "Jet black" -msgstr "" +msgstr "Đen tuyền" +# AI Translated msgid "White aluminium" -msgstr "" +msgstr "Nhôm trắng" +# AI Translated msgid "Grey aluminium" -msgstr "" +msgstr "Nhôm xám" +# AI Translated msgid "Pure white" -msgstr "" +msgstr "Trắng tinh khiết" +# AI Translated msgid "Graphite black" -msgstr "" +msgstr "Đen than chì" +# AI Translated msgid "Traffic white" -msgstr "" +msgstr "Trắng giao thông" +# AI Translated msgid "Traffic black" -msgstr "" +msgstr "Đen giao thông" +# AI Translated msgid "Papyrus white" -msgstr "" +msgstr "Trắng giấy cói" +# AI Translated msgid "Pearl light grey" -msgstr "" +msgstr "Xám nhạt xà cừ" +# AI Translated msgid "Metal: Silver" -msgstr "" +msgstr "Kim loại: Bạc" +# AI Translated msgid "Metal: Brass" -msgstr "" +msgstr "Kim loại: Đồng thau" +# AI Translated msgid "Metal: Gold" -msgstr "" +msgstr "Kim loại: Vàng" +# AI Translated msgid "Metal: Copper" -msgstr "" +msgstr "Kim loại: Đồng" +# AI Translated msgid "Metal: Bronze" -msgstr "" +msgstr "Kim loại: Đồng thanh" +# AI Translated msgid "Nature: Pearl" -msgstr "" +msgstr "Thiên nhiên: Ngọc trai" +# AI Translated msgid "Nature: Rainbow" -msgstr "" +msgstr "Thiên nhiên: Cầu vồng" +# AI Translated msgid "Nature: Clear Sky" -msgstr "" +msgstr "Thiên nhiên: Trời quang" +# AI Translated msgid "Nature: Sunset" -msgstr "" +msgstr "Thiên nhiên: Hoàng hôn" +# AI Translated msgid "Wood: Dark" -msgstr "" +msgstr "Gỗ: Đậm" +# AI Translated msgid "Wood: Medium" -msgstr "" +msgstr "Gỗ: Vừa" +# AI Translated msgid "Wood: Light" -msgstr "" +msgstr "Gỗ: Nhạt" # AI Translated msgid "Alternate nozzles:" @@ -33375,13 +33809,25 @@ msgstr "Xóa khỏi Kết cấu của tôi" msgid "Built-in" msgstr "Tích hợp sẵn" +# AI Translated +msgid "My textures" +msgstr "Kết cấu của tôi" + # AI Translated msgid "No textures found." msgstr "Không tìm thấy kết cấu nào." # AI Translated -msgid "My textures" -msgstr "Kết cấu của tôi" +msgid "Texture libraries" +msgstr "Thư viện kết cấu" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "Khám phá thêm thư viện kết cấu" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "Mở OrcaCloud trong trang chủ để duyệt plugin." # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -33784,11 +34230,13 @@ msgstr "Được ánh xạ theo bố cục UV riêng của mô hình, vốn đã msgid "How wide one copy of the texture is on the model. Smaller repeats the pattern more often and makes its detail finer; with Tile off, this is the size of the single copy." msgstr "Chiều rộng của một bản kết cấu trên mô hình. Nhỏ hơn thì mẫu lặp lại nhiều hơn và chi tiết mịn hơn; khi tắt Xếp ô, đây là kích thước của bản duy nhất." +# AI Translated msgid "Larger" -msgstr "" +msgstr "Lớn hơn" +# AI Translated msgid "Smaller" -msgstr "" +msgstr "Nhỏ hơn" # AI Translated msgid "Turns the texture on the surface, in degrees - for lining a pattern up with an edge of the model." @@ -33864,11 +34312,13 @@ msgstr "Màu pha trộn" msgid "The most mixed filaments a bake may add. They are picked from the texture's colors, and only the ones the bake actually uses are created." msgstr "Số filament pha trộn tối đa mà một lần nướng có thể thêm. Chúng được chọn từ các màu của kết cấu, và chỉ những filament mà lần nướng thực sự dùng mới được tạo." +# AI Translated msgid "Few" -msgstr "" +msgstr "Ít" +# AI Translated msgid "Many" -msgstr "" +msgstr "Nhiều" # AI Translated #. TRN The %2% part of "%1% printable colors %2%"; %1% is the number of filaments. @@ -34219,11 +34669,13 @@ msgstr "Tạo lại lưới" msgid "Triangle size the whole model is rebuilt with, in millimetres. Displacement works best on an even mesh; this is what makes one out of an uneven import." msgstr "Kích thước tam giác dùng để dựng lại toàn bộ mô hình, tính bằng milimét. Dịch chuyển hoạt động tốt nhất trên lưới đều; đây là cách tạo lưới đều từ một mô hình nhập vào không đều." +# AI Translated msgid "Before" -msgstr "" +msgstr "Trước" +# AI Translated msgid "After" -msgstr "" +msgstr "Sau" # AI Translated msgid "Keep sharp edges" @@ -36075,6 +36527,10 @@ msgstr "Script" msgid "Slicing Pipeline" msgstr "Quy trình slice" +# AI Translated +msgid "Resource Texture" +msgstr "Kết cấu tài nguyên" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "Giao diện cấu hình của plugin trống. Đang hiển thị trình chỉnh sửa mặc định." @@ -36222,6 +36678,30 @@ msgstr "Thư mục plugin chứa cả file đầu vào .py và .whl" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "Thư mục plugin không chứa file đầu vào .py hoặc .whl" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "Chưa đặt thư mục kết cấu tài nguyên" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "Không thể xác định thư mục kết cấu tài nguyên" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "Đường dẫn kết cấu tài nguyên không phải là thư mục" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "Không thể xác định thư mục plugin" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "Thư mục kết cấu tài nguyên nằm ngoài thư mục plugin" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "Không thể đọc thư mục kết cấu tài nguyên" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36680,7 +37160,7 @@ msgstr "Tải file cấu hình \"%1%\" thất bại: %2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "Không phải file gcode do %1% tạo ra." # AI Translated @@ -36800,7 +37280,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "Không thể tạo bản sao tạm của file G-code %1% trước khi chạy script hậu xử lý: %2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "Trình hậu xử lý không tìm thấy file G-code đã xuất" # AI Translated @@ -37169,6 +37649,28 @@ msgstr "" "Tránh cong vênh\n" "Bạn có biết rằng khi in vật liệu dễ cong vênh như ABS, tăng nhiệt độ bàn nóng một cách thích hợp có thể giảm xác suất cong vênh không?" +# AI Translated +#~ msgid "Dalmatian yellow" +#~ msgstr "Vàng Dalmatia" + +# AI Translated +# Needs human review: Source "Capsanthin violet" is probably a typo for RAL "Capri blue" (sits between Turquoise blue and Ocean blue); translated as Capri blue. Source string needs fixing +#~ msgid "Capsanthin violet" +#~ msgstr "Xanh dương Capri" + +# AI Translated +# Needs human review: Source "Olivestone" is probably a typo for RAL "Olive grey" (sits between Silver grey and Moss grey); translated as Olive grey. Source string needs fixing +#~ msgid "Olivestone" +#~ msgstr "Xám ô liu" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "Khả dụng ở mọi nơi trong cửa sổ, kể cả khi đang gõ trong ô văn bản." + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "Phím tắt toàn cục cũng có tác dụng khi đang gõ." + # AI Translated #~ msgid "Please choose the filament color" #~ msgstr "Vui lòng chọn màu filament" @@ -37660,9 +38162,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "không có công cụ nào được cấu hình" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "G-code kết thúc khi hoàn thành toàn bộ bản in." - #~ msgid "Maximum X speed" #~ msgstr "Tốc độ X tối đa" @@ -37679,27 +38178,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "(Các) plugin Python được gọi ở mỗi bước của quy trình slice để đọc và sửa đổi dữ liệu slice trung gian, bao gồm một bước hậu xử lý G-code cuối cùng. Mang tính nghiên cứu/thử nghiệm." -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "Khi bật, phần mềm slice xuất G-code với nội dung của vùng chính được căn giữa tại gốc tọa độ bàn in (0,0). Firmware máy in chịu trách nhiệm đặt các bản sao/bản đối xứng tại vị trí vật lý của từng vùng. Chỉ bật trên máy in có firmware tự áp dụng độ lệch vùng ở chế độ Sao chép (Copy)/Gương (Mirror) (ví dụ chế độ nhân bản IDEX của RepRapFirmware). Không có tác dụng ở chế độ Chính." - # AI Translated # Needs human review: "pem-inversion" is developer jargon (physical extruder map inversion) kept in English; check it reads acceptably in this Printer/plate setting tooltip. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "Ghi đè theo từng plate, ánh xạ các đầu vật lý đến khe filament (đánh số từ 1). Để trống nghĩa là dùng giá trị mặc định pem-inversion." -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "Trục mà lưới được xoay quanh trước khi slice. Đây là độ nghiêng của máy in băng chuyền: một phép xoay đẳng cự (không biến dạng), đồng thời điều khiển việc hiển thị bàn in và độ nghiêng trọng lực cho support, và được phép biến đổi ngược G-code đảo lại trước bước trượt/co giãn và ánh xạ lại của hệ tọa độ máy. X là độ nghiêng giàn trục thông thường (băng chuyền chạy dọc theo Y)." - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "Ghi đè cho chuyên gia: đặt góc nghiêng hệ tọa độ máy (trượt/co giãn G-code) độc lập với góc xoay trước khi slice. Khi tắt, phép biến đổi hệ tọa độ máy được suy ra từ góc nghiêng băng chuyền, nên một góc duy nhất điều khiển cả hai bước. Chỉ bật để bù cho máy có độ nghiêng giàn trục vật lý khác với góc xoay khi slice." - -# AI Translated -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "Độ lệch tối đa cho phép khi giảm độ phân giải cho cài đặt 'Độ phân giải thành tối đa'. Nếu bạn tăng giá trị này, bản in sẽ kém chính xác hơn nhưng G-Code sẽ nhỏ hơn. 'Độ lệch thành tối đa' giới hạn 'Độ phân giải thành tối đa', nên nếu hai giá trị xung đột, 'Độ lệch thành tối đa' được ưu tiên." - #~ msgid " not in range " #~ msgstr " không trong phạm vi " diff --git a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po index 2b00f52e4b..79bfbfd6c2 100644 --- a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po +++ b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Slic3rPE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2026-06-11 12:37-0300\n" "Last-Translator: Handle \n" "Language-Team: \n" @@ -1751,7 +1751,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "形状(%1%)的描边包含不受支持的内容:%2%。" # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "状态无效,请在 GitHub 上报告复现步骤" # AI Translated @@ -1759,11 +1759,11 @@ msgid "No embossed file" msgstr "没有浮雕文件" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "浮雕形状中缺少 SVG 文件" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "缺少 SVG 文件数据" # AI Translated @@ -5008,7 +5008,7 @@ msgid "Unknown C++ exception." msgstr "未知的 C++ 异常。" # AI Translated -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "正在处理之前文件的 G-code…" msgid "Slicing complete" @@ -6699,7 +6699,7 @@ msgstr "体积:" msgid "Size:" msgstr "尺寸:" -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "发现G-code路径在层%d,高度为%.2lf mm处有冲突。请将有冲突的对象分离得更远(%s <-> %s)。" @@ -12013,6 +12013,10 @@ msgstr "上传文件到打印机存储失败,请重试。" msgid "Send Failed" msgstr "发送失败" +# AI Translated +msgid "No available printers" +msgstr "没有可用的打印机" + msgid "The name length exceeds the limit." msgstr "名称长度超过限制。" @@ -13922,8 +13926,8 @@ msgid "Left mouse" msgstr "鼠标左键" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "在窗口任意位置可用,即使正在文本框中输入。" +msgid "Available anywhere in the window." +msgstr "在窗口任意位置可用。" # AI Translated msgid "Run favorite 1 to 10" @@ -14039,10 +14043,6 @@ msgstr "%s 已分配给 %s。是否将其重新分配给 %s?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "默认的 %s 已分配给 %s。是否将其重新分配给 %s?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "全局快捷键在输入文字时同样生效。" - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "会输入字符的按键不能用作全局快捷键。" @@ -18086,6 +18086,14 @@ msgstr "对象排除" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "启用此选项以在G-code中添加EXCLUDE OBJECT命令。" +# AI Translated +msgid "Outline tolerance" +msgstr "轮廓线公差" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "写入 EXCLUDE_OBJECT_DEFINE 的对象轮廓线与原始轮廓线之间的最大偏差。数值越大,点数越少,有助于避免固件在解析包含大量对象的 G-code 时卡顿。0 表示保留所有点。" + msgid "Verbose G-code" msgstr "注释G-code" @@ -24004,7 +24012,7 @@ msgstr "开始测试 %s..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "测试 %s:IP 解析结果 = %s" # AI Translated @@ -31498,20 +31506,21 @@ msgid "Basic Colors" msgstr "基本颜色" # AI Translated +#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. msgid "Orca Palette" msgstr "Orca 调色板" # AI Translated -#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. +#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "RAL Classic" msgstr "RAL 经典色" # AI Translated -#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "Gradients" msgstr "渐变预设" # AI Translated +msgctxt "Color picker" msgid "Solid" msgstr "纯色" @@ -32010,7 +32019,7 @@ msgid "Medium violet red" msgstr "中紫罗兰红" # AI Translated -msgid "PaleV violet red" +msgid "Pale violet red" msgstr "浅紫罗兰红" # AI Translated @@ -32226,8 +32235,7 @@ msgid "Shallow sky" msgstr "浅空" # AI Translated -# Needs human review: The English “Electric bel” looks like a typo (Electric blue? Electric eel?); the color is #1E90FF, so 电光蓝 was chosen. Recheck once the source name is fixed. -msgid "Electric bel" +msgid "Electric blue" msgstr "电光蓝" # AI Translated @@ -32319,9 +32327,8 @@ msgid "Maize yellow" msgstr "玉米黄" # AI Translated -# Needs human review: RAL 1007 is “Daffodil yellow” (水仙黄); the English name in the palette looks wrong. Recheck once the source name is fixed. -msgid "Dalmatian yellow" -msgstr "达尔马提亚黄" +msgid "Daffodil yellow" +msgstr "水仙黄" # AI Translated msgid "Brown beige" @@ -32668,8 +32675,8 @@ msgid "Turquoise blue" msgstr "绿松石蓝" # AI Translated -msgid "Capsanthin violet" -msgstr "辣椒红素紫" +msgid "Capri blue" +msgstr "卡普里蓝" # AI Translated msgid "Ocean blue" @@ -32820,8 +32827,8 @@ msgid "Silver grey" msgstr "银灰色" # AI Translated -msgid "Olivestone" -msgstr "橄榄石色" +msgid "Olive grey" +msgstr "橄榄灰" # AI Translated msgid "Moss grey" @@ -33597,13 +33604,25 @@ msgstr "从“我的纹理”中移除" msgid "Built-in" msgstr "内置" +# AI Translated +msgid "My textures" +msgstr "我的纹理" + # AI Translated msgid "No textures found." msgstr "未找到纹理。" # AI Translated -msgid "My textures" -msgstr "我的纹理" +msgid "Texture libraries" +msgstr "纹理库" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "探索更多纹理库" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "在主页中打开 OrcaCloud,浏览插件。" # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -36285,6 +36304,10 @@ msgstr "脚本" msgid "Slicing Pipeline" msgstr "切片流水线" +# AI Translated +msgid "Resource Texture" +msgstr "资源纹理" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "插件的配置界面为空。正在显示默认编辑器。" @@ -36433,6 +36456,30 @@ msgstr "插件目录同时包含 .py 和 .whl 入口文件" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "插件目录不包含 .py 或 .whl 入口文件" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "未设置资源纹理目录" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "无法解析资源纹理目录" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "资源纹理路径不是目录" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "无法解析插件文件夹" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "资源纹理目录位于插件文件夹之外" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "无法读取资源纹理目录" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -36891,7 +36938,7 @@ msgstr "加载配置文件“%1%”失败:%2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "不是由 %1% 生成的 G-code 文件。" # AI Translated @@ -37011,7 +37058,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "运行后处理脚本之前,无法创建 G-code 文件 %1% 的临时副本:%2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "后处理器找不到导出的 G-code 文件" # AI Translated @@ -37400,6 +37447,40 @@ msgstr "" "避免翘曲\n" "您知道吗?打印ABS这类易翘曲材料时,适当提高热床温度可以降低翘曲的概率。" +# AI Translated +# Needs human review: RAL 1007 is “Daffodil yellow” (水仙黄); the English name in the palette looks wrong. Recheck once the source name is fixed. +#~ msgid "Dalmatian yellow" +#~ msgstr "达尔马提亚黄" + +# AI Translated +#~ msgid "Capsanthin violet" +#~ msgstr "辣椒红素紫" + +# AI Translated +#~ msgid "Olivestone" +#~ msgstr "橄榄石色" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "在窗口任意位置可用,即使正在文本框中输入。" + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "全局快捷键在输入文字时同样生效。" + +# AI Translated +#~ msgid "Solid" +#~ msgstr "纯色" + +# AI Translated +#~ msgid "PaleV violet red" +#~ msgstr "浅紫罗兰红" + +# AI Translated +# Needs human review: The English “Electric bel” looks like a typo (Electric blue? Electric eel?); the color is #1E90FF, so 电光蓝 was chosen. Recheck once the source name is fixed. +#~ msgid "Electric bel" +#~ msgstr "电光蓝" + #~ msgid "Please choose the filament color" #~ msgstr "请选择耗材丝颜色" @@ -37865,9 +37946,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "未配置的工具头" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "所有打印结束时的结尾G-code" - #~ msgid "Maximum X speed" #~ msgstr "X最大速度" @@ -37884,26 +37962,11 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "在每个切片流水线步骤中调用的 Python 插件,用于读取和修改中间切片数据,包括最终的 G-code 后处理步骤。研究/实验性。" -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "启用后,切片软件输出的 G-code 会以热床原点 (0,0) 为中心放置主区域的内容,由打印机固件负责把复制件/镜像件放到各个物理区域。仅当打印机固件在复制/镜像模式下会自行应用区域偏移时才启用(例如 RepRapFirmware 的 IDEX 复制模式)。主模式下无效。" - # AI Translated # Needs human review: "pem-inversion defaults": confirm pem is the physical extruder map and that the default is its inverse. #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "按盘单独设置物理工具头到耗材丝槽位的映射(从 1 开始编号),覆盖默认映射。留空则使用由物理挤出机映射(pem)反推的默认值。" -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "切片前模型网格的旋转轴。这一旋转即传送带打印机的倾斜:它是保距(无畸变)旋转,同时用于热床渲染和支撑的重力倾斜;生成 G-code 时,逆变换会先还原这一旋转,再进行机器坐标系剪切/缩放和重映射。X 是典型的龙门倾斜轴(传送带沿 Y 方向移动)。" - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "专家选项:单独设置机器坐标系(G-code 剪切/缩放)的倾斜角度,与切片前的旋转角度互不影响。禁用时,机器坐标系变换由传送带倾斜角度推导,两个阶段使用同一个角度。仅当机器实际的龙门倾角与切片旋转角度不一致时,才需启用此项进行补偿。" - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "在为“最大墙体分辨率”设置降低分辨率时所允许的最大偏差。如果增大此值,打印精度会降低,但 G-code 会更小。“最大墙体偏差”会限制“最大墙体分辨率”,因此当两者冲突时,以“最大墙体偏差”为准。" - #~ msgid " not in range " #~ msgstr " 不在合理范围内" diff --git a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po index 69c1fc755e..893078edf8 100644 --- a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po +++ b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-10-15 17:40+0800\n" +"POT-Creation-Date: 2026-10-19 09:48-0300\n" "PO-Revision-Date: 2025-11-28 13:48-0600\n" "Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n" "Language-Team: \n" @@ -1826,7 +1826,7 @@ msgid "Stroke of shape (%1%) contains unsupported: %2%." msgstr "形狀(%1%)的筆劃包含不支援的內容:%2%。" # AI Translated -msgid "Not valid state please report reproduction steps on github" +msgid "Not valid state please report reproduction steps on GitHub" msgstr "狀態無效,請在 GitHub 上回報重現步驟" # AI Translated @@ -1834,11 +1834,11 @@ msgid "No embossed file" msgstr "沒有浮雕檔案" # AI Translated -msgid "Missing svg file in embossed shape" +msgid "Missing SVG file in embossed shape" msgstr "浮雕形狀中缺少 SVG 檔案" # AI Translated -msgid "Missing data of svg file" +msgid "Missing data of SVG file" msgstr "缺少 SVG 檔案的資料" msgid "Face the camera" @@ -5219,7 +5219,7 @@ msgid "Unknown C++ exception." msgstr "未知的 C++ 例外。" # AI Translated -msgid "Processing G-Code from previous file…" +msgid "Processing G-code from previous file…" msgstr "正在處理先前檔案的 G-code…" msgid "Slicing complete" @@ -6912,7 +6912,7 @@ msgid "Size:" msgstr "尺寸:" # AI Translated -#, boost-format +#, c-format, boost-format msgid "Conflicts of G-code paths have been found at layer %d, Z = %.2lfmm. Please separate the conflicted objects farther (%s <-> %s)." msgstr "在第 %d 層(Z = %.2lf mm)發現 G-code 路徑衝突。請將有衝突的物件分開得更遠(%s <-> %s)。" @@ -12298,6 +12298,10 @@ msgstr "無法將檔案上傳至列印裝置的儲存空間,請重試。" msgid "Send Failed" msgstr "傳送失敗" +# AI Translated +msgid "No available printers" +msgstr "沒有可用的列印裝置" + msgid "The name length exceeds the limit." msgstr "名稱長度超過限制。" @@ -14251,8 +14255,8 @@ msgid "Left mouse" msgstr "滑鼠左鍵" # AI Translated -msgid "Available anywhere in the window, even while typing in a text field." -msgstr "在視窗中任何位置皆可使用,即使正在文字欄位中輸入也可以。" +msgid "Available anywhere in the window." +msgstr "在視窗中任何位置皆可使用。" # AI Translated msgid "Run favorite 1 to 10" @@ -14372,10 +14376,6 @@ msgstr "%s 已指派給 %s。要改為指派給 %s 嗎?" msgid "The default %s is assigned to %s. Reassign it to %s?" msgstr "預設的 %s 已指派給 %s。要改為指派給 %s 嗎?" -# AI Translated -msgid "Global shortcuts also apply while typing." -msgstr "全域快速鍵在輸入文字時也會生效。" - # AI Translated msgid "A key that types a character cannot be a global shortcut." msgstr "會輸入字元的按鍵不能作為全域快速鍵。" @@ -18513,6 +18513,14 @@ msgstr "物件排除" msgid "Enable this option to add EXCLUDE OBJECT command in G-code." msgstr "啟用此選項以在 G-code 中加入 EXCLUDE OBJECT 指令。" +# AI Translated +msgid "Outline tolerance" +msgstr "輪廓線公差" + +# AI Translated +msgid "Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the original outline. Larger values give fewer points, which helps firmware that stalls while parsing G-code with many objects. 0 keeps every point." +msgstr "寫入 EXCLUDE_OBJECT_DEFINE 的物件輪廓線與原始輪廓線之間的最大偏差。數值越大,點數越少,有助於避免韌體在解析包含大量物件的 G-code 時卡住。0 表示保留所有點。" + msgid "Verbose G-code" msgstr "詳細 G-code" @@ -24597,7 +24605,7 @@ msgstr "測試 %s 開始..." # AI Translated #, c-format, boost-format -msgid "test %s ip resolved = %s" +msgid "test %s IP resolved = %s" msgstr "測試 %s IP 解析結果 = %s" # AI Translated @@ -32124,21 +32132,22 @@ msgid "Basic Colors" msgstr "基本顏色" # AI Translated +#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. msgid "Orca Palette" msgstr "Orca 調色盤" # AI Translated -#. TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. +#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "RAL Classic" msgstr "RAL 經典色" # AI Translated # Needs human review: Palette dropdown entry for the gradient presets (next to 基本顏色 / Orca 調色盤 / RAL 經典色); 漸層配色 keeps it apart from the Solid/Gradient switch label 漸層. Check it reads right in the dropdown. -#. TRN: Keep the standard/brand name "RAL" unchanged. msgid "Gradients" msgstr "漸層配色" # AI Translated +msgctxt "Color picker" msgid "Solid" msgstr "純色" @@ -32637,7 +32646,7 @@ msgid "Medium violet red" msgstr "中紫羅蘭紅" # AI Translated -msgid "PaleV violet red" +msgid "Pale violet red" msgstr "淡紫羅蘭紅" # AI Translated @@ -32853,8 +32862,7 @@ msgid "Shallow sky" msgstr "淺色天空" # AI Translated -# Needs human review: Orca palette: the English is a typo for "Electric blue" (hex #1E90FF); translated as 電光藍. Revisit if the source keeps a different name. -msgid "Electric bel" +msgid "Electric blue" msgstr "電光藍" # AI Translated @@ -32946,9 +32954,8 @@ msgid "Maize yellow" msgstr "玉米黃" # AI Translated -# Needs human review: RAL 1007 in the RAL Classic list: the English name looks wrong (1007 is Daffodil yellow, 水仙黃); translated literally. Revisit once the source name is fixed. -msgid "Dalmatian yellow" -msgstr "達爾馬提亞黃" +msgid "Daffodil yellow" +msgstr "水仙黃" # AI Translated msgid "Brown beige" @@ -33296,9 +33303,8 @@ msgid "Turquoise blue" msgstr "綠松石藍" # AI Translated -# Needs human review: RAL 5019 in the RAL Classic list: the English name is not a RAL Classic name (5019 is Capri blue); translated literally. Revisit once the source name is fixed. -msgid "Capsanthin violet" -msgstr "辣椒紅素紫" +msgid "Capri blue" +msgstr "卡布里藍" # AI Translated msgid "Ocean blue" @@ -33449,8 +33455,8 @@ msgid "Silver grey" msgstr "銀灰" # AI Translated -msgid "Olivestone" -msgstr "橄欖石色" +msgid "Olive grey" +msgstr "橄欖灰" # AI Translated msgid "Moss grey" @@ -34226,13 +34232,25 @@ msgstr "從「我的紋理」移除" msgid "Built-in" msgstr "內建" +# AI Translated +msgid "My textures" +msgstr "我的紋理" + # AI Translated msgid "No textures found." msgstr "找不到紋理。" # AI Translated -msgid "My textures" -msgstr "我的紋理" +msgid "Texture libraries" +msgstr "紋理庫" + +# AI Translated +msgid "Explore more texture libraries" +msgstr "探索更多紋理庫" + +# AI Translated +msgid "Opens OrcaCloud in the Home page to browse for plugins." +msgstr "在首頁中開啟 OrcaCloud,瀏覽外掛。" # AI Translated msgid "Import your own image as a height map. It is converted to the format the slicer bakes from and saved to your personal texture folder, kept separate from the textures shipped with OrcaSlicer." @@ -36928,6 +36946,10 @@ msgstr "指令碼" msgid "Slicing Pipeline" msgstr "切片管線" +# AI Translated +msgid "Resource Texture" +msgstr "資源紋理" + # AI Translated msgid "The plugin's configuration UI was empty. Showing the default editor." msgstr "外掛的設定介面為空。將顯示預設編輯器。" @@ -37075,6 +37097,30 @@ msgstr "外掛目錄同時包含 .py 和 .whl 進入點檔案" msgid "Plugin directory does not contain a .py or .whl entry file" msgstr "外掛目錄不包含 .py 或 .whl 進入點檔案" +# AI Translated +msgid "Resource texture directory is not set" +msgstr "未設定資源紋理目錄" + +# AI Translated +msgid "Resource texture directory could not be resolved" +msgstr "無法解析資源紋理目錄" + +# AI Translated +msgid "Resource texture path is not a directory" +msgstr "資源紋理路徑不是目錄" + +# AI Translated +msgid "Plugin folder could not be resolved" +msgstr "無法解析外掛資料夾" + +# AI Translated +msgid "Resource texture directory is outside the plugin folder" +msgstr "資源紋理目錄位於外掛資料夾之外" + +# AI Translated +msgid "Resource texture directory could not be read" +msgstr "無法讀取資源紋理目錄" + # AI Translated #, boost-format msgid "Slicing pipeline plugin '%1%' error: %2%" @@ -37533,7 +37579,7 @@ msgstr "載入設定檔「%1%」失敗:%2%" # AI Translated #. TRN %1% is the application name. #, boost-format -msgid "Not a gcode file generated by %1%." +msgid "Not a G-code file generated by %1%." msgstr "不是由 %1% 產生的 G-code 檔案。" # AI Translated @@ -37653,7 +37699,7 @@ msgid "Failed making a temporary copy of G-code file %1% before running a post-p msgstr "執行後處理腳本前,無法建立 G-code 檔案 %1% 的暫存副本:%2%" # AI Translated -msgid "Post-processor can't find exported gcode file" +msgid "Post-processor can't find exported G-code file" msgstr "後處理程式找不到匯出的 G-code 檔案" # AI Translated @@ -38049,6 +38095,41 @@ msgstr "" "避免翹曲\n" "您知道嗎?當列印容易翹曲的材料(如 ABS)時,適當提高熱床溫度可以降低翹曲的機率。" +# AI Translated +# Needs human review: RAL 1007 in the RAL Classic list: the English name looks wrong (1007 is Daffodil yellow, 水仙黃); translated literally. Revisit once the source name is fixed. +#~ msgid "Dalmatian yellow" +#~ msgstr "達爾馬提亞黃" + +# AI Translated +# Needs human review: RAL 5019 in the RAL Classic list: the English name is not a RAL Classic name (5019 is Capri blue); translated literally. Revisit once the source name is fixed. +#~ msgid "Capsanthin violet" +#~ msgstr "辣椒紅素紫" + +# AI Translated +#~ msgid "Olivestone" +#~ msgstr "橄欖石色" + +# AI Translated +#~ msgid "Available anywhere in the window, even while typing in a text field." +#~ msgstr "在視窗中任何位置皆可使用,即使正在文字欄位中輸入也可以。" + +# AI Translated +#~ msgid "Global shortcuts also apply while typing." +#~ msgstr "全域快速鍵在輸入文字時也會生效。" + +# AI Translated +#~ msgid "Solid" +#~ msgstr "純色" + +# AI Translated +#~ msgid "PaleV violet red" +#~ msgstr "淡紫羅蘭紅" + +# AI Translated +# Needs human review: Orca palette: the English is a typo for "Electric blue" (hex #1E90FF); translated as 電光藍. Revisit if the source keeps a different name. +#~ msgid "Electric bel" +#~ msgstr "電光藍" + #~ msgid "Please choose the filament color" #~ msgstr "請選擇線材顏色" @@ -38513,9 +38594,6 @@ msgstr "" #~ msgid "no configured tool" #~ msgstr "未設定的工具頭" -#~ msgid "Add end G-Code when finishing the entire print." -#~ msgstr "所有列印結束時的結尾 G-code" - #~ msgid "Maximum X speed" #~ msgstr "X 最大速度" @@ -38532,25 +38610,10 @@ msgstr "" #~ msgid "Python plugin(s) invoked at each slicing pipeline step to read and modify intermediate slicing data, including a final G-code post-processing step. Research/experimental." #~ msgstr "在每個切片管線步驟呼叫的 Python 外掛,用於讀取與修改中介切片資料,包括最終的 G-code 後處理步驟。研究/實驗性質。" -# AI Translated -#~ msgid "When enabled, the slicer emits g-code with the primary zone's contents centered on bed origin (0,0). The printer firmware is responsible for placing copies/mirrors at each physical zone position. Enable only on printers whose firmware applies its own zone offsets in copy/mirror mode (e.g. RepRapFirmware IDEX duplication mode). Has no effect in Primary mode." -#~ msgstr "啟用後,切片軟體輸出的 G-code 會將主區域的內容以列印板原點 (0,0) 為中心放置,並由列印裝置韌體負責將複製件/鏡像件放到各個實體區域位置。僅在韌體會於複製/鏡像模式下自行套用區域偏移的列印裝置上啟用(例如 RepRapFirmware 的 IDEX 複製模式)。在主模式下無效。" - # AI Translated #~ msgid "Per-plate override mapping physical heads to filament slots (1-based). Empty means use pem-inversion defaults." #~ msgstr "依列印板覆寫實體工具頭到線材槽位的映射(從 1 開始編號)。留空表示使用由 pem 反推的預設映射。" -# AI Translated -#~ msgid "Axis the mesh is rotated about before slicing. This is the belt printer's tilt: an isometric (no distortion) rotation that also drives bed rendering and support gravity tilt, and that the g-code back-transform inverts before the machine-frame shear/scale and remap. X is the typical gantry tilt (belt travels along Y)." -#~ msgstr "切片前網格旋轉所繞的軸。這就是輸送帶列印裝置的傾斜:一種等距(無變形)旋轉,同時用於列印板渲染與支撐的重力傾斜;G-code 反向轉換會先還原此旋轉,再進行機器座標系的剪切/縮放與重新映射。X 是典型的龍門傾斜軸(輸送帶沿 Y 方向移動)。" - -# AI Translated -#~ msgid "Expert override: set the machine-frame (g-code shear/scale) tilt angle independently of the pre-slice rotation angle. When disabled, the machine-frame transform is derived from the belt tilt angle, so a single angle drives both stages. Enable only to compensate for a machine whose physical gantry tilt differs from the slicing rotation." -#~ msgstr "專家覆寫選項:獨立於切片前的旋轉角度,單獨設定機器座標系(G-code 剪切/縮放)的傾斜角度。停用時,機器座標系變換由輸送帶傾斜角度推導,兩個階段使用同一個角度。僅在機器實際的龍門傾角與切片旋轉角度不同時,才啟用此選項進行補償。" - -#~ msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -#~ msgstr "「最大牆解析度」設定在降低解析度時所允許的最大偏差。若增加此值,列印會較不精確,但 G-Code 會更小。「最大牆偏差」會限制「最大牆解析度」,因此若兩者衝突,將以「最大牆偏差」為準。" - #~ msgid " not in range " #~ msgstr " 不在合理的區間" diff --git a/resources/fonts/NotoSansKR-Bold.ttf b/resources/fonts/NotoSansKR-Bold.ttf deleted file mode 100644 index 6cf639eb7d..0000000000 Binary files a/resources/fonts/NotoSansKR-Bold.ttf and /dev/null differ diff --git a/resources/fonts/NotoSansKR-Regular.ttf b/resources/fonts/NotoSansKR-Regular.ttf deleted file mode 100644 index 1b14d32473..0000000000 Binary files a/resources/fonts/NotoSansKR-Regular.ttf and /dev/null differ diff --git a/resources/web/dialog/ColorPickerDialog/palettes.js b/resources/web/dialog/ColorPickerDialog/palettes.js index 4f65f101db..5c17ad5402 100644 --- a/resources/web/dialog/ColorPickerDialog/palettes.js +++ b/resources/web/dialog/ColorPickerDialog/palettes.js @@ -109,7 +109,7 @@ const cssColors = [ {hex: "#800080", name: "Purple"}, {hex: "#663399", name: "Rebecca purple"}, {hex: "#C71585", name: "Medium violet red"}, - {hex: "#DB7093", name: "PaleV violet red"}, + {hex: "#DB7093", name: "Pale violet red"}, {hex: "#FF1493", name: "Deep pink"}, {hex: "#FF69B4", name: "Hot pink"}, {hex: "#FFB6C1", name: "Light pink"}, @@ -193,7 +193,7 @@ const palettes = { {hex: "#40E0D0", name: "Turquoise bay"}, {hex: "#2EBDEF", name: "Sky over reef"}, {hex: "#87CEEB", name: "Shallow sky"}, - {hex: "#1E90FF", name: "Electric bel"}, + {hex: "#1E90FF", name: "Electric blue"}, {hex: "#4169E1", name: "Dolphin"}, {hex: "#0000CD", name: "Ocean depths"}, {hex: "#191970", name: "Whale"}, @@ -219,7 +219,7 @@ const palettes = { {hex: "#EFBF04", name: "1004 Golden yellow"}, {hex: "#D7A500", name: "1005 Honey yellow"}, {hex: "#F2D185", name: "1006 Maize yellow"}, - {hex: "#FDD185", name: "1007 Dalmatian yellow"}, + {hex: "#FDD185", name: "1007 Daffodil yellow"}, {hex: "#8B7D6B", name: "1011 Brown beige"}, {hex: "#F5DB50", name: "1012 Lemon yellow"}, {hex: "#F3E5AB", name: "1013 Oyster white"}, @@ -318,7 +318,7 @@ const palettes = { {hex: "#0384A7", name: "5015 Sky blue"}, {hex: "#006A9E", name: "5017 Traffic blue"}, {hex: "#005F87", name: "5018 Turquoise blue"}, - {hex: "#5A3D5B", name: "5019 Capsanthin violet"}, + {hex: "#1B5583", name: "5019 Capri blue"}, {hex: "#04749F", name: "5020 Ocean blue"}, {hex: "#009AAA", name: "5021 Water blue"}, {hex: "#1A3D5F", name: "5022 Night blue"}, @@ -366,7 +366,7 @@ const palettes = { {hex: "#00A550", name: "6039 Mint green"}, {hex: "#7D7D7D", name: "7000 Squirrel grey"}, {hex: "#A8A9AD", name: "7001 Silver grey"}, - {hex: "#6F7368", name: "7002 Olivestone"}, + {hex: "#6F7368", name: "7002 Olive grey"}, {hex: "#8F9080", name: "7003 Moss grey"}, {hex: "#8E9291", name: "7004 Signal grey"}, {hex: "#8B8788", name: "7005 Mouse grey"}, diff --git a/scripts/check_exception_throw_info.ps1 b/scripts/check_exception_throw_info.ps1 new file mode 100644 index 0000000000..5fd76599b8 --- /dev/null +++ b/scripts/check_exception_throw_info.ps1 @@ -0,0 +1,126 @@ +<# +.SYNOPSIS + Fails when a Windows build has an exception class with broken throw info. + +.DESCRIPTION + Clang on the MSVC ABI can leave the copy constructor out of the CatchableType it emits for + an exception class that comes through a precompiled header + (https://github.com/llvm/llvm-project/issues/53486). The linker keeps one throw info per + class, so when it keeps such a record, a copy of that exception (std::exception_ptr, a catch + by value) shares its data with the original and the data is freed twice. + + A class is either trivially copyable or not, so a binary should never have both a CatchableType + without a copy constructor (_CT??_R0?AV@@@8) and one with it + (_CT??_R0?AV@@@8??0...). The script lists each PDB's public symbols with the + llvm-pdbutil next to the build's compiler and reports every class that has both. + + scripts\test_check_exception_throw_info.ps1 tests it. + +.PARAMETER BuildDir + The slicer build directory. Its CMakeCache.txt names the compiler, and its src\ + holds the PDBs to check, which must include OrcaSlicer.pdb. + +.PARAMETER Config + The configuration whose PDBs to check (default: Release). + +.PARAMETER Pdb + PDBs to check instead of the ones in \src\, as a list or comma-separated. + +.PARAMETER Dump + Saved `llvm-pdbutil dump --publics` output to check instead of PDBs. Needs no build. + +.EXAMPLE + scripts\check_exception_throw_info.ps1 -BuildDir build +#> +param( + [string] $BuildDir, + [string] $Config = 'Release', + [string[]] $Pdb, + [string[]] $Dump +) +$ErrorActionPreference = 'Stop' + +# powershell -File passes "a.pdb,b.pdb" as one string. A path that exists as given stays whole. +function Split-PathList([string[]] $values) { + @($values | Where-Object { $_ } | ForEach-Object { + if ((Test-Path -LiteralPath $_) -or $_ -notmatch ',') { $_ } else { $_ -split ',' | Where-Object { $_ } } + }) +} + +$Dump = Split-PathList $Dump +if (-not $Dump) { + if (-not $BuildDir) { + throw 'Name the slicer build directory with -BuildDir.' + } + $cache = Join-Path $BuildDir 'CMakeCache.txt' + if (-not (Test-Path $cache)) { + throw "No CMakeCache.txt in $BuildDir. Name the slicer build directory." + } + $entry = Select-String -Path $cache -Pattern '^CMAKE_CXX_COMPILER:\w+=(.+)$' | Select-Object -First 1 + if (-not $entry) { + throw "No CMAKE_CXX_COMPILER in $cache." + } + $compiler = $entry.Matches[0].Groups[1].Value + # A tree configured with a bare compiler name found it on PATH. + if (-not (Split-Path $compiler)) { + $found = Get-Command $compiler -CommandType Application -ErrorAction SilentlyContinue | Select-Object -First 1 + if (-not $found) { + throw "$compiler, the compiler in $cache, is not on PATH." + } + $compiler = $found.Source + } + $pdbutil = Join-Path (Split-Path $compiler) 'llvm-pdbutil.exe' + if (-not (Test-Path $pdbutil)) { + throw "No llvm-pdbutil.exe next to $compiler. This check needs a build made with Clang." + } + + $Pdb = Split-PathList $Pdb + if (-not $Pdb) { + # OrcaSlicer.dll holds the slicer itself, so a check without it proves nothing. + $pdbDir = Join-Path $BuildDir "src\$Config" + if (-not (Test-Path (Join-Path $pdbDir 'OrcaSlicer.pdb'))) { + throw "No OrcaSlicer.pdb in $pdbDir." + } + $Pdb = @(Get-ChildItem $pdbDir -Filter *.pdb | ForEach-Object FullName) + } +} + +$catchable = [regex]'`_CT\?\?_R0\?A[UV](.+?)@@@8([^`]*)`' +$tmp = [IO.Path]::GetTempFileName() +$failed = $false +$classes = 0 +try { + foreach ($file in $(if ($Dump) { $Dump } else { $Pdb })) { + $text = $file + if (-not $Dump) { + $run = Start-Process -FilePath $pdbutil -ArgumentList 'dump', '--publics', "`"$file`"" -NoNewWindow -Wait -PassThru -RedirectStandardOutput $tmp + if ($run.ExitCode -ne 0) { + throw "llvm-pdbutil failed on $file." + } + $text = $tmp + } + + $kinds = @{} + foreach ($match in $catchable.Matches([IO.File]::ReadAllText((Resolve-Path -LiteralPath $text).Path))) { + $class = $match.Groups[1].Value + if (-not $kinds.ContainsKey($class)) { $kinds[$class] = @{} } + $kinds[$class][$(if ($match.Groups[2].Value.StartsWith('??0')) { 'copy' } else { 'bitwise' })] = $true + } + + $broken = @($kinds.Keys | Where-Object { $kinds[$_].Count -eq 2 } | Sort-Object) + "$(Split-Path -Leaf $file): $($kinds.Count) exception classes, $($broken.Count) with broken throw info" + foreach ($class in $broken) { " $class" } + if ($broken.Count -gt 0) { $failed = $true } + $classes += $kinds.Count + } +} finally { + Remove-Item $tmp -ErrorAction SilentlyContinue +} + +# The slicer's PDBs always contain exception throw info, so finding none means the dump format or the PDBs changed. +if ($classes -eq 0) { + 'No exception classes found. Check that llvm-pdbutil still prints public symbols in backticks.' + $failed = $true +} + +exit [int]$failed diff --git a/scripts/test_build_win.ps1 b/scripts/test_build_win.ps1 index 5f36fb7ac9..0c2a26c952 100644 --- a/scripts/test_build_win.ps1 +++ b/scripts/test_build_win.ps1 @@ -301,6 +301,10 @@ $cases = @( Contains = @('Precompiled header: off') } @{ Name = 'the precompiled header is on unless asked'; Args = @('-s') NotContains = @('SLIC3R_PCH') } + @{ Name = '-l turns the precompiled header off'; Args = @('-s', '-l') + Contains = @('-DSLIC3R_PCH=OFF', 'Precompiled header: off') } + @{ Name = 'a deps-only build says nothing about the precompiled header'; Args = @('-d', '-l') + NotContains = @('Precompiled header') } @{ Name = '--no-pch works without a cache'; Args = @('-s', '--no-pch') NotContains = @('COMPILER_LAUNCHER') } @{ Name = 'the slicer build runs gettext'; Args = @('-s') diff --git a/scripts/test_check_exception_throw_info.ps1 b/scripts/test_check_exception_throw_info.ps1 new file mode 100644 index 0000000000..0c2ef2edfb --- /dev/null +++ b/scripts/test_check_exception_throw_info.ps1 @@ -0,0 +1,93 @@ +<# +.SYNOPSIS + Tests scripts/check_exception_throw_info.ps1 on canned llvm-pdbutil dumps. + +.DESCRIPTION + Each case runs the check in its own powershell -File process, as CI does, and asserts on the + exit code and output. Dumps are written to a temporary folder, so no build is needed. + +.EXAMPLE + powershell -File scripts/test_check_exception_throw_info.ps1 +#> +$ErrorActionPreference = 'Stop' + +$check = Join-Path $PSScriptRoot 'check_exception_throw_info.ps1' +$work = Join-Path ([IO.Path]::GetTempPath()) 'check_exception_throw_info_tests' +Remove-Item -Recurse -Force $work -ErrorAction SilentlyContinue +New-Item -ItemType Directory -Force -Path $work | Out-Null + +function Write-Dump([string] $path, [string[]] $symbols) { + New-Item -ItemType Directory -Force -Path (Split-Path $path) | Out-Null + $i = 0 + $lines = @(' Public Symbols', '============================================================') + foreach ($symbol in $symbols) { + $i++ + $lines += " $i | S_PUB32 [size = 48] ``$symbol``", ' flags = none, addr = 0007:0000' + } + Set-Content -Path $path -Encoding ascii -Value $lines +} + +$bitwise = '_CT??_R0?AVfuture_error@std@@@840' +$copy = '_CT??_R0?AVfuture_error@std@@@8??0future_error@std@@QEAA@AEBV01@@Z40' +$trivial = '_CT??_R0?AUtag@@@81' +Write-Dump "$work\broken.txt" @($bitwise, $copy, $trivial) +Write-Dump "$work\clean.txt" @($copy, $trivial) +Write-Dump "$work\empty.txt" @() +Write-Dump "$work\a dir, with a comma\clean.txt" @($copy) + +# A build directory whose compiler has an llvm-pdbutil beside it but no OrcaSlicer.pdb. +# Nothing runs the stand-in; the check stops before it gets there. +$build = "$work\build" +New-Item -ItemType Directory -Force -Path "$build\bin", "$build\src\Release" | Out-Null +Copy-Item "$env:SystemRoot\System32\where.exe" "$build\bin\llvm-pdbutil.exe" +Set-Content -Path "$build\CMakeCache.txt" -Encoding ascii -Value "CMAKE_CXX_COMPILER:FILEPATH=$build\bin\clang-cl.exe" +Set-Content -Path "$build\src\Release\orca-slicer.pdb" -Value '' +$bare = "$work\bare" +New-Item -ItemType Directory -Force -Path $bare | Out-Null +Set-Content -Path "$bare\CMakeCache.txt" -Encoding ascii -Value 'CMAKE_CXX_COMPILER:STRING=no-such-clang-cl.exe' + +$cases = @( + @{ Name = 'a class with and without a copy constructor fails'; Args = @('-Dump', "$work\broken.txt") + Exit = 1; Contains = @('1 with broken throw info', 'future_error@std') } + @{ Name = 'copy constructors and trivially copyable classes pass'; Args = @('-Dump', "$work\clean.txt") + Exit = 0; Contains = @('2 exception classes, 0 with broken throw info') } + @{ Name = 'no exception classes at all fails'; Args = @('-Dump', "$work\empty.txt") + Exit = 1; Contains = @('No exception classes found') } + @{ Name = 'a comma-separated list checks each dump'; Args = @('-Dump', "$work\broken.txt,$work\clean.txt") + Exit = 1; Contains = @('broken.txt: 2 exception classes', 'clean.txt: 2 exception classes') } + @{ Name = 'a path with a comma stays whole'; Args = @('-Dump', "$work\a dir, with a comma\clean.txt") + Exit = 0; Contains = @('clean.txt: 1 exception classes') } + @{ Name = 'a build without OrcaSlicer.pdb fails'; Args = @('-BuildDir', $build) + Exit = 1; Contains = @('No OrcaSlicer.pdb in') } + @{ Name = 'a compiler that is not on PATH is named'; Args = @('-BuildDir', $bare) + Exit = 1; Contains = @('no-such-clang-cl.exe, the compiler in') } + @{ Name = 'a missing build directory is named'; Args = @('-BuildDir', "$work\nowhere") + Exit = 1; Contains = @('No CMakeCache.txt in') } + @{ Name = 'no build directory and no dump fails'; Args = @() + Exit = 1; Contains = @('Name the slicer build directory') } +) + +$failed = 0 +foreach ($case in $cases) { + $ErrorActionPreference = 'Continue' + $output = (& powershell -NoProfile -File $check @($case.Args) 2>&1 | Out-String) + $code = $LASTEXITCODE + $ErrorActionPreference = 'Stop' + $problems = @() + if ($code -ne $case.Exit) { $problems += "exit $code, expected $($case.Exit)" } + foreach ($text in $case.Contains) { + if (-not $output.Contains($text)) { $problems += "no '$text' in the output" } + } + if ($problems) { + $failed++ + " FAIL $($case.Name)" + $problems | ForEach-Object { " $_" } + $output.TrimEnd() -split "`r?`n" | ForEach-Object { " | $_" } + } else { + " ok $($case.Name)" + } +} + +Remove-Item -Recurse -Force $work -ErrorAction SilentlyContinue +"$($cases.Count - $failed) passed, $failed failed" +exit [int]($failed -gt 0) diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index fa9aec8531..4acea143cc 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -182,8 +182,8 @@ set(lisbslic3r_sources Fill/FillPlanePath.hpp Fill/FillRectilinear.cpp Fill/FillRectilinear.hpp - Fill/FillTpmsAdaptive.cpp - Fill/FillTpmsAdaptive.hpp + Fill/AdaptiveInfillField.cpp + Fill/AdaptiveInfillField.hpp Fill/FillTpmsD.cpp Fill/FillTpmsD.hpp Fill/FillTpmsFK.cpp @@ -666,6 +666,9 @@ endif () encoding_check(libslic3r) target_compile_definitions(libslic3r PUBLIC -DUSE_TBB -DTBB_USE_CAPTURED_EXCEPTION=0) +# CGAL changes Kd_tree's member layout when TBB is enabled. Match libslic3r_cgal +# in every consumer so inline constructors/destructors cannot mix the two layouts. +target_compile_definitions(libslic3r PUBLIC CGAL_LINKED_WITH_TBB) if (USE_SLIC3R_CONSOLE_LOG) target_compile_definitions(libslic3r PRIVATE $<$:SLIC3R_CONSOLE_LOG>) endif() diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index ee6078596a..4667674bf0 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -1432,7 +1432,7 @@ ConfigSubstitutions ConfigBase::load_from_gcode_file(const std::string &file, Fo } if (!header_found) { // TRN %1% is the application name. - std::string error_message = format(_u8L("Not a gcode file generated by %1%."), SLIC3R_APP_FULL_NAME); + std::string error_message = format(_u8L("Not a G-code file generated by %1%."), SLIC3R_APP_FULL_NAME); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << error_message; throw Slic3r::RuntimeError(error_message.c_str()); } diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 9d76262ec6..9f70498499 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -377,7 +377,8 @@ public: virtual void set(const ConfigOption* rhs, size_t start, size_t len) = 0; virtual void set_with_restore(const ConfigOptionVectorBase* rhs, std::vector& restore_index, int stride) = 0; virtual void set_with_restore_2(const ConfigOptionVectorBase* rhs, std::vector& restore_index, int start, int len, bool skip_error = false) = 0; - virtual void set_only_diff(const ConfigOptionVectorBase* rhs, std::vector& diff_index, int stride) = 0; + // keep_nil: copy a nil column from rhs as well, for options whose nil means "disabled" rather than "inherit". + virtual void set_only_diff(const ConfigOptionVectorBase* rhs, std::vector& diff_index, int stride, bool keep_nil = false) = 0; virtual void set_to_index(const ConfigOptionVectorBase* rhs, std::vector& dest_index, int stride) = 0; virtual void set_with_nil(const ConfigOptionVectorBase* rhs, const ConfigOptionVectorBase* inherits, int stride) = 0; // Resize the vector of values, copy the newly added values from opt_default if provided. @@ -580,7 +581,7 @@ public: //set a item related with extruder variants when loading user config, only set the different value of some extruder //rhs: item from user config //diff_index: which index in this vector need to be set - virtual void set_only_diff(const ConfigOptionVectorBase* rhs, std::vector& diff_index, int stride) override + virtual void set_only_diff(const ConfigOptionVectorBase* rhs, std::vector& diff_index, int stride, bool keep_nil) override { if (rhs->type() == this->type()) { // Assign the first value of the rhs vector. @@ -592,7 +593,7 @@ public: for (size_t i = 0; i < diff_index.size(); i++) { if (diff_index[i] != -1) { for (size_t j = 0; j < stride; j++) { - if (!other->is_nil(diff_index[i] * stride)) + if (keep_nil || !other->is_nil(diff_index[i] * stride)) this->values[i * stride + j] = other->values[diff_index[i] * stride + j]; } } @@ -841,8 +842,12 @@ public: { UNUSED(append); std::istringstream iss(str); - iss >> this->value; - return !iss.fail(); + double value; + iss >> value; + if (iss.fail()) + return false; + this->value = value; + return true; } bool operator==(const ConfigOption &rhs) const override @@ -1033,8 +1038,12 @@ public: { UNUSED(append); std::istringstream iss(str); - iss >> this->value; - return !iss.fail(); + int value; + iss >> value; + if (iss.fail()) + return false; + this->value = value; + return true; } ConfigOptionInt& operator=(const ConfigOption *opt) @@ -1252,8 +1261,12 @@ public: UNUSED(append); // don't try to parse the trailing % since it's optional std::istringstream iss(str); - iss >> this->value; - return !iss.fail(); + double value; + iss >> value; + if (iss.fail()) + return false; + this->value = value; + return true; } private: @@ -1365,10 +1378,14 @@ public: bool deserialize(const std::string &str, bool append = false) override { UNUSED(append); - this->percent = str.find_first_of("%") != std::string::npos; std::istringstream iss(str); - iss >> this->value; - return !iss.fail(); + double value; + iss >> value; + if (iss.fail()) + return false; + this->value = value; + this->percent = str.find_first_of("%") != std::string::npos; + return true; } private: @@ -1538,8 +1555,12 @@ public: { UNUSED(append); char dummy; - return sscanf(str.data(), " %lf , %lf %c", &this->value(0), &this->value(1), &dummy) == 2 || - sscanf(str.data(), " %lf x %lf %c", &this->value(0), &this->value(1), &dummy) == 2; + Vec2d value; + if (sscanf(str.data(), " %lf , %lf %c", &value(0), &value(1), &dummy) != 2 && + sscanf(str.data(), " %lf x %lf %c", &value(0), &value(1), &dummy) != 2) + return false; + this->value = value; + return true; } private: @@ -1658,8 +1679,12 @@ public: { UNUSED(append); char dummy; - return sscanf(str.data(), " %lf , %lf , %lf %c", &this->value(0), &this->value(1), &this->value(2), &dummy) == 3 || - sscanf(str.data(), " %lf x %lf x %lf %c", &this->value(0), &this->value(1), &this->value(2), &dummy) == 3; + Vec3d value; + if (sscanf(str.data(), " %lf , %lf , %lf %c", &value(0), &value(1), &value(2), &dummy) != 3 && + sscanf(str.data(), " %lf x %lf x %lf %c", &value(0), &value(1), &value(2), &dummy) != 3) + return false; + this->value = value; + return true; } private: diff --git a/src/libslic3r/EdgeGrid.cpp b/src/libslic3r/EdgeGrid.cpp index c6e003505a..35d3608dd8 100644 --- a/src/libslic3r/EdgeGrid.cpp +++ b/src/libslic3r/EdgeGrid.cpp @@ -616,7 +616,7 @@ struct PropagateDanielssonSingleStep { if ((signs[addr] & 2) == 0) { float *v = &L[addr << 1]; float l = v[0] * v[0] + v[1] * v[1]; - float *v2s = v + (addr_delta << 1); + float *v2s = v + 2 * addr_delta; float v2[2] = { v2s[0] + INCX * resolution, v2s[1] + INCY * resolution diff --git a/src/libslic3r/Fill/FillTpmsAdaptive.cpp b/src/libslic3r/Fill/AdaptiveInfillField.cpp similarity index 91% rename from src/libslic3r/Fill/FillTpmsAdaptive.cpp rename to src/libslic3r/Fill/AdaptiveInfillField.cpp index 2dcd2930b9..1f5ea234d3 100644 --- a/src/libslic3r/Fill/FillTpmsAdaptive.cpp +++ b/src/libslic3r/Fill/AdaptiveInfillField.cpp @@ -1,4 +1,4 @@ -#include "FillTpmsAdaptive.hpp" +#include "AdaptiveInfillField.hpp" #include #include @@ -146,11 +146,11 @@ void rasterize(const ExPolygons &expolygons, const Vec2d &origin, double cell, i } // Scale of the pattern relative to the surface at a depth from 0 at the surface to 1 at the deepest point. -double target_scale(double ratio, TpmsAdaptiveGradient gradient, double depth) +double target_scale(double ratio, AdaptiveInfillGradient gradient, double depth) { switch (gradient) { - case TpmsAdaptiveGradient::Quadratic: return 1. + (ratio - 1.) * depth * depth; - case TpmsAdaptiveGradient::Exponential: return std::pow(ratio, depth); + case AdaptiveInfillGradient::Quadratic: return 1. + (ratio - 1.) * depth * depth; + case AdaptiveInfillGradient::Exponential: return std::pow(ratio, depth); default: return 1. + (ratio - 1.) * depth; } } @@ -159,7 +159,7 @@ double target_scale(double ratio, TpmsAdaptiveGradient gradient, double depth) // continuous level of the target of a depth. struct DensityLevels { - DensityLevels(double ratio, double step, TpmsAdaptiveGradient gradient) + DensityLevels(double ratio, double step, AdaptiveInfillGradient gradient) : ratio(ratio), gradient(gradient), count(int(std::ceil(std::abs(std::log(ratio)) / std::log(step) - EPSILON))) {} @@ -170,7 +170,7 @@ struct DensityLevels } double ratio; - TpmsAdaptiveGradient gradient; + AdaptiveInfillGradient gradient; int count; }; @@ -212,12 +212,12 @@ private: } // namespace -TpmsRadialField::TpmsRadialField(const std::vector &slices, const BoundingBox &bbox, TpmsAdaptiveMode mode, +AdaptiveInfillField::AdaptiveInfillField(const std::vector &slices, const BoundingBox &bbox, AdaptiveInfillMode mode, const std::function &throw_if_canceled) : m_mode(mode) - , m_axis(mode == TpmsAdaptiveMode::NormalX ? 0 : mode == TpmsAdaptiveMode::NormalY ? 1 : mode == TpmsAdaptiveMode::NormalZ ? 2 : -1) + , m_axis(mode == AdaptiveInfillMode::NormalX ? 0 : mode == AdaptiveInfillMode::NormalY ? 1 : mode == AdaptiveInfillMode::NormalZ ? 2 : -1) { - assert(!slices.empty() && mode != TpmsAdaptiveMode::Disabled); + assert(!slices.empty() && mode != AdaptiveInfillMode::Disabled); const Vec3d min(unscaled(bbox.min.x()), unscaled(bbox.min.y()), slices.front().bottom_z); const Vec3d extent = Vec3d(unscaled(bbox.max.x()), unscaled(bbox.max.y()), slices.back().top_z) - min; @@ -269,7 +269,7 @@ TpmsRadialField::TpmsRadialField(const std::vector &slices, const Boundin // Bodies are the connected inside nodes, none of which is on the border. The deepest nodes of a body are the // centers of its lobes, unless the depth between them stays above NeckRatio; where the depth ties, the center // is the node nearest to the middle of the tied nodes. - const bool lobes = m_mode != TpmsAdaptiveMode::SteppedShells && m_mode != TpmsAdaptiveMode::SmoothBlend; + const bool lobes = m_mode != AdaptiveInfillMode::SteppedShells && m_mode != AdaptiveInfillMode::SmoothBlend; m_body.assign(depth.size(), -1); std::vector body_nodes; for (size_t seed = 0; seed < depth.size(); ++seed) { @@ -341,7 +341,7 @@ TpmsRadialField::TpmsRadialField(const std::vector &slices, const Boundin } throw_if_canceled(); - if (m_mode == TpmsAdaptiveMode::SteppedShells || m_mode == TpmsAdaptiveMode::SmoothBlend || m_mode == TpmsAdaptiveMode::DistanceWarp) { + if (m_mode == AdaptiveInfillMode::SteppedShells || m_mode == AdaptiveInfillMode::SmoothBlend || m_mode == AdaptiveInfillMode::DistanceWarp) { m_depth.assign(depth.size(), 0.f); for (size_t i = 0; i < depth.size(); ++i) if (m_body[i] >= 0) @@ -421,7 +421,7 @@ TpmsRadialField::TpmsRadialField(const std::vector &slices, const Boundin lobe.reach.resize(log_reach.size()); std::transform(log_reach.begin(), log_reach.end(), lobe.reach.begin(), [](double v) { return float(std::exp(v)); }); - if (m_mode == TpmsAdaptiveMode::DistanceWarp) { + if (m_mode == AdaptiveInfillMode::DistanceWarp) { std::vector mean(log_reach.size() * (Samples + 1)); for (size_t d = 0; d < log_reach.size(); ++d) { const Vec3d dir = direction(int(d) / Azimuth, int(d) % Azimuth); @@ -488,7 +488,7 @@ TpmsRadialField::TpmsRadialField(const std::vector &slices, const Boundin } } -double TpmsRadialField::depth(const Vec3d &pt) const +double AdaptiveInfillField::depth(const Vec3d &pt) const { assert(!m_depth.empty()); const Vec3d f = (pt - m_origin) / m_cell; @@ -508,7 +508,7 @@ double TpmsRadialField::depth(const Vec3d &pt) const return value; } -Vec3d TpmsRadialField::offset(const Vec3d &pt, const Vec3d ¢er) const +Vec3d AdaptiveInfillField::offset(const Vec3d &pt, const Vec3d ¢er) const { Vec3d d = pt - center; if (m_axis >= 0) @@ -516,7 +516,7 @@ Vec3d TpmsRadialField::offset(const Vec3d &pt, const Vec3d ¢er) const return d; } -double TpmsRadialField::radial(const Lobe &lobe, const Vec3d &pt) const +double AdaptiveInfillField::radial(const Lobe &lobe, const Vec3d &pt) const { const Vec3d d = this->offset(pt, lobe.center); const double r = d.norm(); @@ -562,7 +562,7 @@ double TpmsRadialField::radial(const Lobe &lobe, const Vec3d &pt) const return warp(mean); } -size_t TpmsRadialField::radial(const Vec3d &pt, Radials &out) const +size_t AdaptiveInfillField::radial(const Vec3d &pt, Radials &out) const { assert(!this->empty()); Vec3i32 idx; @@ -588,7 +588,7 @@ size_t TpmsRadialField::radial(const Vec3d &pt, Radials &out) const return count; } -size_t TpmsRadialField::body_radial(size_t node, const Vec3d &pt, float weight, Radial *out) const +size_t AdaptiveInfillField::body_radial(size_t node, const Vec3d &pt, float weight, Radial *out) const { const Body &body = m_bodies[m_body[node]]; if (body.lobes == 1) { @@ -641,7 +641,7 @@ struct AdaptiveTpmsField const long gsize = std::lround(gsizef / rsizef); const AdaptiveTpms &tpms; - const TpmsRadialField &radial_field; + const AdaptiveInfillField &radial_field; RadialScale scale; DensityLevels levels; Point size; @@ -650,7 +650,7 @@ struct AdaptiveTpmsField double cos_angle; double sin_angle; - AdaptiveTpmsField(const AdaptiveTpms &tpms, const TpmsRadialField &radial_field, const BoundingBox &bbox, coordf_t z, float angle) + AdaptiveTpmsField(const AdaptiveTpms &tpms, const AdaptiveInfillField &radial_field, const BoundingBox &bbox, coordf_t z, float angle) : tpms(tpms), radial_field(radial_field), scale(tpms, radial_field.axis() < 0 ? 3 : 2) , levels(std::max(tpms.interior_frequency / tpms.surface_frequency, 1e-3), BlendRatio, tpms.gradient) , size(bbox.size()), offs(bbox.min), z(z) @@ -666,7 +666,7 @@ struct AdaptiveTpmsField const double x = unscaled(pt.x()); const double y = unscaled(pt.y()); const Vec3d obj(cos_angle * x - sin_angle * y, sin_angle * x + cos_angle * y, z); - if (radial_field.mode() == TpmsAdaptiveMode::SmoothBlend) { + if (radial_field.mode() == AdaptiveInfillMode::SmoothBlend) { // The regular patterns of the two levels around the target of the depth, blended by a smoothstep. auto lattice = [this, x, y](int level) { const double frequency = tpms.surface_frequency * levels.scale(level); @@ -681,7 +681,7 @@ struct AdaptiveTpmsField return float((w < 1. ? (1. - w) * lattice(k) : 0.) + (w > 0. ? w * lattice(k + 1) : 0.)); } const int axis = radial_field.axis(); - TpmsRadialField::Radials radials; + AdaptiveInfillField::Radials radials; const size_t count = radial_field.radial(obj, radials); float value = 0.f; for (size_t i = 0; i < count; ++i) { @@ -708,20 +708,20 @@ template<> struct _RasterTraits }; // Continuous density level of the depth over a layer, in the object frame. -struct TpmsLevelField +struct AdaptiveLevelField { static constexpr float gsizef = 0.5f; static constexpr float rsizef = 0.05f; const coord_t rsize = scaled(rsizef); const long gsize = std::lround(gsizef / rsizef); - const TpmsRadialField &field; + const AdaptiveInfillField &field; const DensityLevels &levels; Point size; Point offs; double z; - TpmsLevelField(const TpmsRadialField &field, const DensityLevels &levels, const BoundingBox &bbox, coordf_t z) + AdaptiveLevelField(const AdaptiveInfillField &field, const DensityLevels &levels, const BoundingBox &bbox, coordf_t z) : field(field), levels(levels), size(bbox.size()), offs(bbox.min), z(z) {} @@ -736,19 +736,19 @@ struct TpmsLevelField inline Point to_Point(const Coord &p) const { return Point(to_coord(p.c) + offs.x(), to_coord(p.r) + offs.y()); } }; -template<> struct _RasterTraits +template<> struct _RasterTraits { using ValueType = float; - static float get(const TpmsLevelField &sf, size_t row, size_t col) { return sf.get_scalar(Coord(long(row), long(col))); } - static size_t rows(const TpmsLevelField &sf) { return sf.to_coordr(sf.size.y()); } - static size_t cols(const TpmsLevelField &sf) { return sf.to_coordr(sf.size.x()); } + static float get(const AdaptiveLevelField &sf, size_t row, size_t col) { return sf.get_scalar(Coord(long(row), long(col))); } + static size_t rows(const AdaptiveLevelField &sf) { return sf.to_coordr(sf.size.y()); } + static size_t cols(const AdaptiveLevelField &sf) { return sf.to_coordr(sf.size.x()); } }; } // namespace marchsq namespace Slic3r { -Polylines make_adaptive_tpms(const AdaptiveTpms &tpms, const TpmsRadialField &field, BoundingBox bbox, +Polylines make_adaptive_tpms(const AdaptiveTpms &tpms, const AdaptiveInfillField &field, BoundingBox bbox, coordf_t z, coordf_t layer_height, coordf_t spacing, float angle) { // A cell of margin for the rings closed along the raster border, and a fixed sampling grid for every region. @@ -775,21 +775,21 @@ Polylines make_adaptive_tpms(const AdaptiveTpms &tpms, const TpmsRadialField &fi return polylines; } -std::vector make_tpms_shells(const TpmsRadialField &field, const ExPolygon &expolygon, coordf_t z, - float surface_density, float interior_density, TpmsAdaptiveGradient gradient) +std::vector make_adaptive_infill_shells(const AdaptiveInfillField &field, const ExPolygon &expolygon, coordf_t z, + float surface_density, float interior_density, AdaptiveInfillGradient gradient) { const DensityLevels levels(interior_density / surface_density, ShellRatio, gradient); if (levels.count == 0) return {{surface_density, {expolygon}}}; // A fixed sampling grid, so that every region of a layer gets the same shells. - const coord_t cell = scaled(marchsq::TpmsLevelField::gsizef); + const coord_t cell = scaled(marchsq::AdaptiveLevelField::gsizef); BoundingBox bbox = get_extents(expolygon); bbox.offset(cell); bbox.merge(align_to_grid(bbox.min, Point(cell, cell))); - const marchsq::TpmsLevelField raster(field, levels, bbox, z); + const marchsq::AdaptiveLevelField raster(field, levels, bbox, z); // Each level takes the part deeper than the middle between it and the previous one. - std::vector shells; + std::vector shells; ExPolygons remaining{expolygon}; for (int level = 0; level < levels.count && !remaining.empty(); ++level) { Polygons deeper; @@ -808,12 +808,12 @@ std::vector make_tpms_shells(const TpmsRadialField &field, const ExPo return shells; } -void fill_tpms_shells(const TpmsRadialField &field, const ExPolygon &expolygon, coordf_t z, const FillParams ¶ms, coordf_t spacing, +void fill_adaptive_infill_shells(const AdaptiveInfillField &field, const ExPolygon &expolygon, coordf_t z, const FillParams ¶ms, coordf_t spacing, const std::function &fill_shell) { FillParams shell_params = params; - shell_params.tpms_adaptive = TpmsAdaptiveMode::Disabled; - for (const TpmsShell &shell : make_tpms_shells(field, expolygon, z, params.density, params.tpms_interior_density, params.tpms_adaptive_gradient)) { + shell_params.adaptive_infill_mode = AdaptiveInfillMode::Disabled; + for (const AdaptiveInfillShell &shell : make_adaptive_infill_shells(field, expolygon, z, params.density, params.adaptive_infill_interior_density, params.adaptive_infill_gradient)) { shell_params.density = shell.density; for (const ExPolygon &part : offset_ex(shell.expolygons, -float(scale_(0.5 * spacing)))) fill_shell(shell_params, part); diff --git a/src/libslic3r/Fill/FillTpmsAdaptive.hpp b/src/libslic3r/Fill/AdaptiveInfillField.hpp similarity index 84% rename from src/libslic3r/Fill/FillTpmsAdaptive.hpp rename to src/libslic3r/Fill/AdaptiveInfillField.hpp index 8e7b9db6cd..bfeaf07692 100644 --- a/src/libslic3r/Fill/FillTpmsAdaptive.hpp +++ b/src/libslic3r/Fill/AdaptiveInfillField.hpp @@ -21,7 +21,7 @@ namespace Slic3r { // lobe, 1 at its surface. Lobes are parts of a body separated by a neck, like two spheres united. In the 2D modes, // every section normal to the axis has its own bodies and lobes, and distances are measured within the section. The // modes following the distance to the surface use the depth of every point instead; Distance warp also the lobes. -class TpmsRadialField +class AdaptiveInfillField { public: struct Slice @@ -39,7 +39,7 @@ public: }; // Slices sorted by z, in the XY coordinates of the fill and the print Z. - TpmsRadialField(const std::vector &slices, const BoundingBox &bbox, TpmsAdaptiveMode mode, + AdaptiveInfillField(const std::vector &slices, const BoundingBox &bbox, AdaptiveInfillMode mode, const std::function &throw_if_canceled); // Lobes blended near the sides between them, from a body or from each of the two sections around a point. @@ -56,7 +56,7 @@ public: // Axis normal to the sections in the 2D modes, -1 in the modes graded in 3D. int axis() const { return m_axis; } - TpmsAdaptiveMode mode() const { return m_mode; } + AdaptiveInfillMode mode() const { return m_mode; } // In the modes following the distance to the surface: depth relative to the deepest point of the body, from 0 at // the surface to 1. @@ -91,7 +91,7 @@ private: static constexpr int Polar = 24; static constexpr int Azimuth = 48; - TpmsAdaptiveMode m_mode; + AdaptiveInfillMode m_mode; int m_axis; Vec3d m_origin; double m_cell; @@ -106,9 +106,9 @@ private: std::vector m_depth; }; -using TpmsRadialFieldPtr = std::unique_ptr; +using AdaptiveInfillFieldPtr = std::unique_ptr; // A field for every adaptive mode in use, indexed by the mode. -using TpmsRadialFields = std::array; +using AdaptiveInfillFields = std::array; struct AdaptiveTpms { @@ -117,14 +117,14 @@ struct AdaptiveTpms // Pattern frequencies at the surface and at the center, in radians per mm. double surface_frequency; double interior_frequency; - TpmsAdaptiveGradient gradient; + AdaptiveInfillGradient gradient; }; // Infill lines in the fill frame, the object frame rotated by -angle; z is the print_z of the layer. -Polylines make_adaptive_tpms(const AdaptiveTpms &tpms, const TpmsRadialField &field, BoundingBox bbox, +Polylines make_adaptive_tpms(const AdaptiveTpms &tpms, const AdaptiveInfillField &field, BoundingBox bbox, coordf_t z, coordf_t layer_height, coordf_t spacing, float angle); -struct TpmsShell +struct AdaptiveInfillShell { float density; ExPolygons expolygons; @@ -132,12 +132,12 @@ struct TpmsShell // Stepped shells: the parts of an expolygon in the object frame at each density, from the surface inwards; z is the // middle of the layer. -std::vector make_tpms_shells(const TpmsRadialField &field, const ExPolygon &expolygon, coordf_t z, - float surface_density, float interior_density, TpmsAdaptiveGradient gradient); +std::vector make_adaptive_infill_shells(const AdaptiveInfillField &field, const ExPolygon &expolygon, coordf_t z, + float surface_density, float interior_density, AdaptiveInfillGradient gradient); // Stepped shells: fills every shell with fill_shell at its density, each shrunk by half a line like a filled region, // so the lines connected along the boundaries of two shells don't overlap. -void fill_tpms_shells(const TpmsRadialField &field, const ExPolygon &expolygon, coordf_t z, const FillParams ¶ms, coordf_t spacing, +void fill_adaptive_infill_shells(const AdaptiveInfillField &field, const ExPolygon &expolygon, coordf_t z, const FillParams ¶ms, coordf_t spacing, const std::function &fill_shell); } // namespace Slic3r diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index 146d3ee7b4..1e6eade821 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -312,9 +312,9 @@ struct SurfaceFillParams bool gyroid_optimized = false; // For TPMS: grade the density from the surface to the interior of the object. - TpmsAdaptiveMode tpms_adaptive = TpmsAdaptiveMode::Disabled; - float tpms_interior_density = 0.f; - TpmsAdaptiveGradient tpms_adaptive_gradient = TpmsAdaptiveGradient::Linear; + AdaptiveInfillMode adaptive_infill_mode = AdaptiveInfillMode::Disabled; + float adaptive_infill_interior_density = 0.f; + AdaptiveInfillGradient adaptive_infill_gradient = AdaptiveInfillGradient::Linear; // Orca: corner smoothing factor in the range [0, 1]. double smooth_factor { 0. }; @@ -358,9 +358,9 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(skin_infill_depth); RETURN_COMPARE_NON_EQUAL(infill_overhang_angle); RETURN_COMPARE_NON_EQUAL(gyroid_optimized); - RETURN_COMPARE_NON_EQUAL(tpms_adaptive); - RETURN_COMPARE_NON_EQUAL(tpms_interior_density); - RETURN_COMPARE_NON_EQUAL(tpms_adaptive_gradient); + RETURN_COMPARE_NON_EQUAL(adaptive_infill_mode); + RETURN_COMPARE_NON_EQUAL(adaptive_infill_interior_density); + RETURN_COMPARE_NON_EQUAL(adaptive_infill_gradient); RETURN_COMPARE_NON_EQUAL(smooth_factor); RETURN_COMPARE_NON_EQUAL(center_of_surface_pattern); RETURN_COMPARE_NON_EQUAL(separated_infills); @@ -394,9 +394,9 @@ struct SurfaceFillParams this->center_of_surface_pattern == rhs.center_of_surface_pattern && this->separated_infills == rhs.separated_infills && this->gyroid_optimized == rhs.gyroid_optimized && - this->tpms_adaptive == rhs.tpms_adaptive && - this->tpms_interior_density == rhs.tpms_interior_density && - this->tpms_adaptive_gradient == rhs.tpms_adaptive_gradient && + this->adaptive_infill_mode == rhs.adaptive_infill_mode && + this->adaptive_infill_interior_density == rhs.adaptive_infill_interior_density && + this->adaptive_infill_gradient == rhs.adaptive_infill_gradient && this->smooth_factor == rhs.smooth_factor && this->fill_order == rhs.fill_order; } @@ -1010,17 +1010,17 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p params.extrusion_role != erTopSolidInfill && params.extrusion_role != erBottomSurface; // Orca: only the TPMS sparse infill is graded; reset otherwise, as params is reused. - params.tpms_adaptive = is_tpms_adaptive_pattern(params.pattern) && params.extrusion_role == erInternalInfill ? - region_config.tpms_adaptive.value : TpmsAdaptiveMode::Disabled; - const bool tpms_adaptive = params.tpms_adaptive != TpmsAdaptiveMode::Disabled; - params.tpms_interior_density = tpms_adaptive ? std::max(1.f, float(region_config.tpms_interior_density)) : 0.f; - params.tpms_adaptive_gradient = tpms_adaptive ? region_config.tpms_adaptive_gradient.value : TpmsAdaptiveGradient::Linear; + params.adaptive_infill_mode = is_adaptive_infill_pattern(params.pattern) && params.extrusion_role == erInternalInfill ? + region_config.adaptive_infill_mode.value : AdaptiveInfillMode::Disabled; + const bool adaptive_infill_mode = params.adaptive_infill_mode != AdaptiveInfillMode::Disabled; + params.adaptive_infill_interior_density = adaptive_infill_mode ? std::max(1.f, float(region_config.adaptive_infill_interior_density)) : 0.f; + params.adaptive_infill_gradient = adaptive_infill_mode ? region_config.adaptive_infill_gradient.value : AdaptiveInfillGradient::Linear; // Pass through gyroid_optimized only when the effective pattern is Gyroid, // so non-Gyroid fills do not differ in SurfaceFillParams by an irrelevant flag // (which would unnecessarily split fill batching). Adaptive density replaces it. // Stored on SurfaceFillParams; copied to FillParams during conversion. - params.gyroid_optimized = (params.pattern == ipGyroid) && region_config.gyroid_optimized && !tpms_adaptive; + params.gyroid_optimized = (params.pattern == ipGyroid) && region_config.gyroid_optimized && !adaptive_infill_mode; if (params.extrusion_role == erInternalInfill) { params.angle = calculate_infill_rotation_angle(layer.object(), layer.id(), region_config.infill_direction.value, @@ -1373,7 +1373,7 @@ void Layer::make_fills(const FillAdaptive::RegionOctrees* fill_octrees, FillLigh f->angle = surface_fill.params.angle; f->fixed_angle = surface_fill.params.fixed_angle; const FillAdaptive::Octrees *octrees = fill_octrees ? fill_octrees->region(surface_fill.region_id) : nullptr; - f->tpms_radial_field = this->object()->tpms_radial_field(surface_fill.params.tpms_adaptive); + f->adaptive_infill_field = this->object()->adaptive_infill_field(surface_fill.params.adaptive_infill_mode); f->print_config = &this->object()->print()->config(); f->print_object_config = &this->object()->config(); if (surface_fill.params.pattern == ipConcentricInternal) { @@ -1423,9 +1423,9 @@ void Layer::make_fills(const FillAdaptive::RegionOctrees* fill_octrees, FillLigh params.lateral_lattice_angle_2 = surface_fill.params.lateral_lattice_angle_2; params.infill_overhang_angle = surface_fill.params.infill_overhang_angle; params.gyroid_optimized = surface_fill.params.gyroid_optimized; - params.tpms_adaptive = surface_fill.params.tpms_adaptive; - params.tpms_interior_density = float(0.01 * surface_fill.params.tpms_interior_density); - params.tpms_adaptive_gradient = surface_fill.params.tpms_adaptive_gradient; + params.adaptive_infill_mode = surface_fill.params.adaptive_infill_mode; + params.adaptive_infill_interior_density = float(0.01 * surface_fill.params.adaptive_infill_interior_density); + params.adaptive_infill_gradient = surface_fill.params.adaptive_infill_gradient; params.smooth_factor = surface_fill.params.smooth_factor; // BBS @@ -1598,7 +1598,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(const FillAdapti f->angle = surface_fill.params.angle; f->fixed_angle = surface_fill.params.fixed_angle; const FillAdaptive::Octrees *octrees = fill_octrees ? fill_octrees->region(surface_fill.region_id) : nullptr; - f->tpms_radial_field = this->object()->tpms_radial_field(surface_fill.params.tpms_adaptive); + f->adaptive_infill_field = this->object()->adaptive_infill_field(surface_fill.params.adaptive_infill_mode); f->print_config = &this->object()->print()->config(); f->print_object_config = &this->object()->config(); @@ -1638,9 +1638,9 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(const FillAdapti params.infill_overhang_angle = surface_fill.params.infill_overhang_angle; params.multiline = surface_fill.params.multiline; params.gyroid_optimized = surface_fill.params.gyroid_optimized; - params.tpms_adaptive = surface_fill.params.tpms_adaptive; - params.tpms_interior_density = float(0.01 * surface_fill.params.tpms_interior_density); - params.tpms_adaptive_gradient = surface_fill.params.tpms_adaptive_gradient; + params.adaptive_infill_mode = surface_fill.params.adaptive_infill_mode; + params.adaptive_infill_interior_density = float(0.01 * surface_fill.params.adaptive_infill_interior_density); + params.adaptive_infill_gradient = surface_fill.params.adaptive_infill_gradient; params.smooth_factor = surface_fill.params.smooth_factor; // Orca: Match make_fills() when choosing the origin of plane-path patterns. // Without the sparse extrusion role, the filler uses each surface's bounds diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index a852f2c42b..63ebff49c2 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -11,6 +11,10 @@ #include #include #include +#include +#include +#include +#include "../AABBTreeLines.hpp" #include "../ClipperUtils.hpp" #include "../EdgeGrid.hpp" #include "../Geometry.hpp" @@ -206,6 +210,9 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para thick_polylines.clear(); } else { + // Orca: sparse infill lines whose ends are next to each other print as one path, without a travel between them. + if (params.extrusion_role == erInternalInfill && ! eec->no_sort) + join_close_ends(polylines, scale_(2. * this->spacing), params.can_reverse); extrusion_entities_append_paths( eec->entities, std::move(polylines), params.extrusion_role, @@ -1644,6 +1651,8 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector SCALED_EPSILON ? std::max(anchor_length_max, 2. * (anchor_length + line_half_width)) : anchor_length_max; #if 0 // Connection from end of one infill line to the start of another infill line. @@ -1720,6 +1729,10 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector open_end(graph.map_infill_end_point_to_boundary.size(), 1); + auto end_index = [&graph](const ContourIntersectionPoint *cp) { return size_t(cp - graph.map_infill_end_point_to_boundary.data()); }; + struct Arc { ContourIntersectionPoint *intersection; double arc_length; @@ -1731,6 +1744,81 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector &order) { + std::vector consumed(graph.map_infill_end_point_to_boundary.size()); + for (size_t i = 0; i < consumed.size(); ++ i) + consumed[i] = graph.map_infill_end_point_to_boundary[i].consumed; + std::vector parent(infill_ordered.size()); + std::iota(parent.begin(), parent.end(), 0); + auto find = [&parent](size_t i) { + while (parent[i] != i) + i = parent[i] = parent[parent[i]]; + return i; + }; + size_t joins = 0; + for (const Arc &arc : order) { + const size_t end1 = end_index(arc.intersection), end2 = end_index(arc.intersection->next_on_contour); + if (consumed[end1] || consumed[end2] || (params.multiline > 1 && arc.arc_length < scale_(spacing) * params.multiline)) + continue; + const size_t polyline1 = find(end1 / 2), polyline2 = find(end2 / 2); + if (polyline1 == polyline2) + continue; + if (arc.arc_length < join_length) { + parent[polyline2] = polyline1; + ++ joins; + } else if (anchor_length <= SCALED_EPSILON) + continue; + consumed[end1] = consumed[end2] = 1; + } + // The last pass joins the open ends next to each other, also those of a multiline group. + for (size_t end = 0; end < consumed.size(); ++ end) { + const ContourIntersectionPoint &cp = graph.map_infill_end_point_to_boundary[end]; + if (consumed[end] || cp.contour_idx == boundary_idx_unconnected) + continue; + const double length = graph.boundary_params[cp.contour_idx].back(); + auto open = [&](const ContourIntersectionPoint *other, bool trimmed) { + return other != &cp && ! consumed[end_index(other)] && ! trimmed; + }; + const double lprev = open(cp.prev_on_contour, cp.prev_trimmed || cp.prev_on_contour->next_trimmed) ? + path_length_along_contour_ccw(cp.prev_on_contour, &cp, length) : std::numeric_limits::max(); + const double lnext = open(cp.next_on_contour, cp.next_trimmed || cp.next_on_contour->prev_trimmed) ? + path_length_along_contour_ccw(&cp, cp.next_on_contour, length) : std::numeric_limits::max(); + consumed[end] = anchor_length > SCALED_EPSILON; + for (const double l : { std::min(lprev, lnext), std::max(lprev, lnext) }) { + if (l > join_length) + break; + const size_t other = end_index(l == lprev ? cp.prev_on_contour : cp.next_on_contour); + const size_t polyline1 = find(end / 2), polyline2 = find(other / 2); + if (polyline1 == polyline2) + continue; + parent[polyline2] = polyline1; + consumed[end] = consumed[other] = 1; + ++ joins; + break; + } + } + return joins; + }; + // Equal arcs taken along the contour pair a wall in one phase; keep the order that joins the most lines. + size_t best_joins = count_joins(arches); + const double bucket = 0.5 * scale_(spacing); + for (const bool backwards : { false, true }) { + std::vector along_contour = arches; + std::sort(along_contour.begin(), along_contour.end(), [bucket, backwards](const Arc &l, const Arc &r) { + const long long bucket_l = std::llround(l.arc_length / bucket), bucket_r = std::llround(r.arc_length / bucket); + if (bucket_l != bucket_r) + return bucket_l < bucket_r; + if (l.intersection->contour_idx != r.intersection->contour_idx) + return l.intersection->contour_idx < r.intersection->contour_idx; + return backwards ? l.intersection->param > r.intersection->param : l.intersection->param < r.intersection->param; + }); + if (const size_t joins = count_joins(along_contour); joins > best_joins) { + best_joins = joins; + arches = std::move(along_contour); + } + } } //FIXME improve the Traveling Salesman problem with 2-opt and 3-opt local optimization. @@ -1752,7 +1840,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vectorpoint_idx] == polyline1.points.front() || contour[cp1->point_idx] == polyline1.points.back()); if (contour[cp1->point_idx] == polyline1.points.front()) @@ -1761,6 +1849,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vectorpoint_idx] == polyline2.points.back()) polyline2.reverse(); take(polyline1, polyline2, contour, cp1, cp2, false); + open_end[end_index(cp1)] = open_end[end_index(cp2)] = 0; // Mark the second polygon as merged with the first one. if (polyline_idx2 < polyline_idx1) { polyline2 = std::move(polyline1); @@ -1778,6 +1867,23 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vectorprev_on_contour : cp->next_on_contour; + if (other == nullptr || other == &from) + break; + distance += backwards ? closed_contour_distance_cw(cp->param, other->param, length) : closed_contour_distance_ccw(cp->param, other->param, length); + if (open_end[end_index(other)] && get_and_update_merged_with(end_index(other) / 2) != polyline_idx) + return distance; + cp = other; + } + return std::numeric_limits::max(); + }; + // Connect the remaining open infill lines to the perimeter lines if possible. for (ContourIntersectionPoint &contour_point : graph.map_infill_end_point_to_boundary) if (! contour_point.consumed && contour_point.contour_idx != boundary_idx_unconnected) { @@ -1796,7 +1902,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector::max() || l > anchor_length_max) + if (l == std::numeric_limits::max() || l > join_length) break; // Take the complete contour. bool reversed = l == lprev; @@ -1815,6 +1921,7 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vectorpoint_idx] == polyline2.points.back()) polyline2.reverse(); take(polyline, polyline2, contour, &contour_point, cp2, reversed); + open_end[end_index(&contour_point)] = open_end[end_index(cp2)] = 0; if (polyline_idx < polyline_idx2) { // Mark the second polyline as merged with the first one. merged_with[polyline_idx2] = polyline_idx; @@ -1829,18 +1936,35 @@ void Fill::connect_infill(Polylines &&infill_ordered, const std::vector SCALED_EPSILON) { - // Which to take? One could optimize for: - // 1) Shortest path - // 2) Hook length - // ... - // Let's take the longer now, as this improves the chance of another hook to be placed on the other side of this contour point. - double l = std::max(contour_point.contour_not_taken_length_prev, contour_point.contour_not_taken_length_next); - if (l > SCALED_EPSILON) { - if (contour_point.contour_not_taken_length_prev > contour_point.contour_not_taken_length_next) - take_limited(polyline, contour, contour_params, &contour_point, contour_point.prev_on_contour, true, anchor_length, line_half_width); - else - take_limited(polyline, contour, contour_params, &contour_point, contour_point.next_on_contour, false, anchor_length, line_half_width); + // Hook toward the nearest open end of another polyline, where the next path likely starts. + const double free_prev = contour_point.contour_not_taken_length_prev; + const double free_next = contour_point.contour_not_taken_length_next; + const double to_prev = distance_to_open_end(contour_point, polyline_idx, true); + const double to_next = distance_to_open_end(contour_point, polyline_idx, false); + bool backwards = free_prev > free_next; + if (to_prev < to_next && free_prev > SCALED_EPSILON) + backwards = true; + else if (to_next < to_prev && free_next > SCALED_EPSILON) + backwards = false; + // Orca: with multiline, a hook toward a copy stops short of it; the copy takes half a width over the sine of its wall angle. + double length = anchor_length; + if (const ContourIntersectionPoint *other = backwards ? contour_point.prev_on_contour : contour_point.next_on_contour; + params.multiline > 1 && other != &contour_point) { + const Point &end = contour[contour_point.point_idx]; + Vec2d dir = Vec2d::Zero(); + for (size_t i = 1; i < polyline.size() && dir.squaredNorm() < sqr(2. * scale_(spacing) * params.multiline); ++ i) + dir = (end - polyline.points[polyline.points.front() == end ? i : polyline.size() - 1 - i]).cast(); + const Vec2d to_copy = (contour[other->point_idx] - end).cast(); + const double across = dir.squaredNorm() > 0. ? std::abs(cross2(dir.normalized(), to_copy)) : 0.; + if (across > SCALED_EPSILON && across < scale_(spacing) * params.multiline) { + const double gap = backwards ? path_length_along_contour_ccw(other, &contour_point, contour_params.back()) : + path_length_along_contour_ccw(&contour_point, other, contour_params.back()); + length = std::min(length, gap - line_half_width * (1. + to_copy.norm() / across)); + } } + if ((backwards ? free_prev : free_next) > SCALED_EPSILON) + take_limited(polyline, contour, contour_params, &contour_point, backwards ? contour_point.prev_on_contour : contour_point.next_on_contour, + backwards, std::max(0., length), line_half_width); } } @@ -2798,4 +2922,123 @@ void multiline_fill(Polylines& polylines, const FillParams& params, float spacin polylines = std::move(all_polylines); } +void join_close_ends(Polylines &polylines, double max_gap, bool can_reverse) +{ + const size_t n = polylines.size(); + if (n < 2 || max_gap <= 0.) + return; + static constexpr size_t npos = size_t(-1); + // End 2 * i is the first point of polyline i, 2 * i + 1 its last. + auto end_point = [&polylines](size_t e) -> const Point & { return (e & 1) ? polylines[e >> 1].points.back() : polylines[e >> 1].points.front(); }; + // Ends in cells of max_gap, so the ends within max_gap of one are in its cell or the eight around it. + auto cell_of = [max_gap](const Point &p) { return Vec2i64(int64_t(std::floor(p.x() / max_gap)), int64_t(std::floor(p.y() / max_gap))); }; + auto key = [](const Vec2i64 &c) { return (uint64_t(c.x()) << 32) ^ uint64_t(uint32_t(c.y())); }; + std::unordered_map> grid; + for (size_t e = 0; e < 2 * n; ++ e) + if (polylines[e >> 1].size() >= 2) + grid[key(cell_of(end_point(e)))].push_back(e); + + // The end of a polyline that comes last along its overall direction, taken along the dominant axis. + std::vector backwards(n, 0); + for (size_t i = 0; i < n; ++ i) + if (polylines[i].size() >= 2) { + const Vec2d dir = (polylines[i].points.back() - polylines[i].points.front()).cast(); + backwards[i] = std::abs(dir.x()) >= std::abs(dir.y()) ? dir.x() < 0. : dir.y() < 0.; + } + auto trailing = [&backwards](size_t e) { return bool(e & 1) != bool(backwards[e >> 1]); }; + // Ends that meet first, then shortest gaps between leading ends, then the others: the copies of neighboring multiline + // groups are all joined at the same side, which leaves their open ends next to each other rather than on alternating walls. + std::vector> gaps; + for (const auto &[cell_key, ends] : grid) { + const Vec2i64 c = cell_of(end_point(ends.front())); + for (int64_t dx = -1; dx <= 1; ++ dx) + for (int64_t dy = -1; dy <= 1; ++ dy) + if (auto it = grid.find(key(c + Vec2i64(dx, dy))); it != grid.end()) + for (size_t a : ends) + for (size_t b : it->second) + if (a < b && (a >> 1) != (b >> 1) && (can_reverse || (a & 1) != (b & 1))) + if (const double d = (end_point(a) - end_point(b)).cast().norm(); d <= max_gap) + gaps.emplace_back(d > SCALED_EPSILON, d > SCALED_EPSILON && (trailing(a) || trailing(b)), d, a, b); + } + if (gaps.empty()) + return; + std::sort(gaps.begin(), gaps.end()); + + std::vector partner(2 * n, npos), parent(n); + std::iota(parent.begin(), parent.end(), 0); + auto find = [&parent](size_t i) { + while (parent[i] != i) + i = parent[i] = parent[parent[i]]; + return i; + }; + // A join may not cross a line or another join; touching them at its own ends is fine, as where a line ends on another. + // Only the segments through a cell next to a candidate join can cross one. + std::unordered_set near_gaps; + for (const auto &[apart, trail, d, a, b] : gaps) + for (size_t e : { a, b }) + for (int64_t dx = -1; dx <= 1; ++ dx) + for (int64_t dy = -1; dy <= 1; ++ dy) + near_gaps.insert(key(cell_of(end_point(e)) + Vec2i64(dx, dy))); + Lines near_lines; + for (const Polyline &pl : polylines) + for (size_t i = 1; i < pl.size(); ++ i) { + const Vec2i64 c0 = cell_of(pl.points[i - 1]), c1 = cell_of(pl.points[i]); + const Vec2i64 lo = c0.cwiseMin(c1), hi = c0.cwiseMax(c1); + bool near = (hi - lo).maxCoeff() > 3; + for (int64_t x = lo.x(); x <= hi.x() && ! near; ++ x) + for (int64_t y = lo.y(); y <= hi.y() && ! near; ++ y) + near = near_gaps.count(key(Vec2i64(x, y))) > 0; + if (near) + near_lines.emplace_back(pl.points[i - 1], pl.points[i]); + } + const AABBTreeLines::LinesDistancer lines(std::move(near_lines)); + auto crosses = [&](size_t a, size_t b) { + const Vec2d p = end_point(a).cast(), q = end_point(b).cast(); + const double length = (q - p).norm(); + if (length <= 2. * SCALED_EPSILON) + return false; + const Vec2d dir = (q - p) / length; + const Line inner(Point((p + SCALED_EPSILON * dir).cast()), Point((q - SCALED_EPSILON * dir).cast())); + if (! lines.get_lines().empty() && ! lines.intersections_with_line(inner).empty()) + return true; + const Vec2i64 c = cell_of(end_point(a)); + for (int64_t dx = -3; dx <= 3; ++ dx) + for (int64_t dy = -3; dy <= 3; ++ dy) + if (auto it = grid.find(key(c + Vec2i64(dx, dy))); it != grid.end()) + for (size_t e : it->second) + if (partner[e] != npos && Geometry::segments_intersect(inner.a, inner.b, end_point(e), end_point(partner[e]))) + return true; + return false; + }; + for (const auto &[apart, trail, d, a, b] : gaps) + if (partner[a] == npos && partner[b] == npos && find(a >> 1) != find(b >> 1) && ! crosses(a, b)) { + partner[a] = b; + partner[b] = a; + parent[find(a >> 1)] = find(b >> 1); + } + + // Walk each group from a polyline with a free end, entering the next polyline at the end joined to the last one. + Polylines out; + std::vector done(n, 0); + auto walk = [&](size_t first_end) { + Polyline joined; + for (size_t e = first_end; e != npos;) { + Polyline &pl = polylines[e >> 1]; + done[e >> 1] = 1; + if (e & 1) + pl.reverse(); + joined.points.insert(joined.points.end(), pl.points.begin() + (! joined.empty() && joined.points.back() == pl.points.front()), pl.points.end()); + e = partner[e ^ 1]; + } + out.emplace_back(std::move(joined)); + }; + for (size_t i = 0; i < n; ++ i) + if (! done[i] && partner[2 * i] == npos) + walk(2 * i); + for (size_t i = 0; i < n; ++ i) + if (! done[i] && partner[2 * i + 1] == npos) + walk(2 * i + 1); + polylines = std::move(out); +} + } // namespace Slic3r diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index e0308c9450..f60fde6d1d 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -33,7 +33,7 @@ namespace Slic3r { class ExtrusionEntityCollection; } namespace Slic3r { class Surface; -class TpmsRadialField; +class AdaptiveInfillField; enum InfillPattern : int; namespace FillAdaptive { @@ -93,9 +93,9 @@ struct FillParams bool gyroid_optimized { false }; // For TPMS: grade the density from the surface to the interior of the object. Density fraction. - TpmsAdaptiveMode tpms_adaptive { TpmsAdaptiveMode::Disabled }; - float tpms_interior_density { 0.f }; - TpmsAdaptiveGradient tpms_adaptive_gradient { TpmsAdaptiveGradient::Linear }; + AdaptiveInfillMode adaptive_infill_mode { AdaptiveInfillMode::Disabled }; + float adaptive_infill_interior_density { 0.f }; + AdaptiveInfillGradient adaptive_infill_gradient { AdaptiveInfillGradient::Linear }; // Orca: corner smoothing factor in the range [0, 1]. double smooth_factor { 0. }; @@ -162,7 +162,7 @@ public: FillAdaptive::Octree* adapt_fill_octree = nullptr; // Radial coordinate inside the object for the adaptive TPMS infill - const TpmsRadialField* tpms_radial_field = nullptr; + const AdaptiveInfillField* adaptive_infill_field = nullptr; // PrintConfig and PrintObjectConfig are used by infills that use Arachne (Concentric and FillEnsuring). // Orca: also used by gap fill function. @@ -258,8 +258,11 @@ public: static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance); }; - //Fill Multiline + //Fill Multiline void multiline_fill(Polylines& polylines, const FillParams& params, float spacing); + // Joins polylines whose ends are at most max_gap apart, shortest gaps first and without closing a loop, so each such + // group prints as one path. Without can_reverse only the end of one polyline joins the start of another. + void join_close_ends(Polylines &polylines, double max_gap, bool can_reverse); } // namespace Slic3r #endif // slic3r_FillBase_hpp_ diff --git a/src/libslic3r/Fill/FillGyroid.cpp b/src/libslic3r/Fill/FillGyroid.cpp index 06cb55f70e..3ebb2f9633 100644 --- a/src/libslic3r/Fill/FillGyroid.cpp +++ b/src/libslic3r/Fill/FillGyroid.cpp @@ -18,7 +18,7 @@ #include "FillGyroid.hpp" #include "libslic3r/Polygon.hpp" #include "libslic3r/PrintConfig.hpp" -#include "FillTpmsAdaptive.hpp" +#include "AdaptiveInfillField.hpp" namespace Slic3r { @@ -315,8 +315,8 @@ void FillGyroid::_fill_surface_single( ExPolygon expolygon, Polylines &polylines_out) { - if (params.tpms_adaptive == TpmsAdaptiveMode::SteppedShells && this->tpms_radial_field != nullptr) { - fill_tpms_shells(*this->tpms_radial_field, expolygon, this->z - 0.5 * params.layer_height, params, this->spacing, + if (params.adaptive_infill_mode == AdaptiveInfillMode::SteppedShells && this->adaptive_infill_field != nullptr) { + fill_adaptive_infill_shells(*this->adaptive_infill_field, expolygon, this->z - 0.5 * params.layer_height, params, this->spacing, [&](const FillParams &shell_params, const ExPolygon &shell) { this->_fill_surface_single(shell_params, thickness_layers, direction, shell, polylines_out); }); @@ -342,11 +342,11 @@ void FillGyroid::_fill_surface_single( // generate pattern Polylines polylines; - if (params.tpms_adaptive != TpmsAdaptiveMode::Disabled && this->tpms_radial_field != nullptr) { + if (params.adaptive_infill_mode != AdaptiveInfillMode::Disabled && this->adaptive_infill_field != nullptr) { // Radians per mm of the regular pattern at a density. auto frequency = [¶ms, this](double density) { return density * DensityAdjust / (params.multiline * this->spacing); }; - polylines = make_adaptive_tpms({gyroid, frequency(params.density), frequency(params.tpms_interior_density), params.tpms_adaptive_gradient}, - *this->tpms_radial_field, bb, this->z, params.layer_height, this->spacing, infill_angle); + polylines = make_adaptive_tpms({gyroid, frequency(params.density), frequency(params.adaptive_infill_interior_density), params.adaptive_infill_gradient}, + *this->adaptive_infill_field, bb, this->z, params.layer_height, this->spacing, infill_angle); } else if (params.gyroid_optimized) { // Marching-squares path on the gyroid implicit field. Base period matches // the standard parametric path's wavelength: 2*pi * spacing / density_adj. diff --git a/src/libslic3r/Fill/FillTpmsD.cpp b/src/libslic3r/Fill/FillTpmsD.cpp index 04f8222ca5..d1a9fae8fd 100644 --- a/src/libslic3r/Fill/FillTpmsD.cpp +++ b/src/libslic3r/Fill/FillTpmsD.cpp @@ -17,7 +17,7 @@ #include "libslic3r/PrintConfig.hpp" #include "libslic3r/libslic3r.h" #include "FillTpmsD.hpp" -#include "FillTpmsAdaptive.hpp" +#include "AdaptiveInfillField.hpp" namespace Slic3r { @@ -117,8 +117,8 @@ void FillTpmsD::_fill_surface_single( ExPolygon expolygon, Polylines &polylines_out) { - if (params.tpms_adaptive == TpmsAdaptiveMode::SteppedShells && this->tpms_radial_field != nullptr) { - fill_tpms_shells(*this->tpms_radial_field, expolygon, this->z - 0.5 * params.layer_height, params, this->spacing, + if (params.adaptive_infill_mode == AdaptiveInfillMode::SteppedShells && this->adaptive_infill_field != nullptr) { + fill_adaptive_infill_shells(*this->adaptive_infill_field, expolygon, this->z - 0.5 * params.layer_height, params, this->spacing, [&](const FillParams &shell_params, const ExPolygon &shell) { this->_fill_surface_single(shell_params, thickness_layers, direction, shell, polylines_out); }); @@ -130,13 +130,13 @@ void FillTpmsD::_fill_surface_single( expolygon.rotate(-infill_angle); Polylines polylines; - if (params.tpms_adaptive != TpmsAdaptiveMode::Disabled && this->tpms_radial_field != nullptr) { + if (params.adaptive_infill_mode != AdaptiveInfillMode::Disabled && this->adaptive_infill_field != nullptr) { // Radians per mm of the regular pattern at a density. auto frequency = [¶ms, this](double density) { return density * DensityAdjust / (params.multiline * this->spacing); }; BoundingBox bbox = expolygon.contour.bounding_box(); bbox.offset(scale_((params.multiline + 1) * this->spacing)); - polylines = make_adaptive_tpms({schwarz_d, frequency(params.density), frequency(params.tpms_interior_density), params.tpms_adaptive_gradient}, - *this->tpms_radial_field, bbox, this->z, params.layer_height, this->spacing, infill_angle); + polylines = make_adaptive_tpms({schwarz_d, frequency(params.density), frequency(params.adaptive_infill_interior_density), params.adaptive_infill_gradient}, + *this->adaptive_infill_field, bbox, this->z, params.layer_height, this->spacing, infill_angle); } else { BoundingBox bb = expolygon.contour.bounding_box(); // Density adjusted to have a good %of weight. diff --git a/src/libslic3r/Fill/FillTpmsFK.cpp b/src/libslic3r/Fill/FillTpmsFK.cpp index 819ef2998e..6ebc495dd6 100644 --- a/src/libslic3r/Fill/FillTpmsFK.cpp +++ b/src/libslic3r/Fill/FillTpmsFK.cpp @@ -8,7 +8,7 @@ #include "libslic3r/Fill/FillBase.hpp" #include "libslic3r/ExPolygon.hpp" #include "FillTpmsFK.hpp" -#include "FillTpmsAdaptive.hpp" +#include "AdaptiveInfillField.hpp" #include #include #include @@ -132,8 +132,8 @@ void FillTpmsFK::_fill_surface_single(const FillParams& params, ExPolygon expolygon, Polylines& polylines_out) { - if (params.tpms_adaptive == TpmsAdaptiveMode::SteppedShells && this->tpms_radial_field != nullptr) { - fill_tpms_shells(*this->tpms_radial_field, expolygon, this->z - 0.5 * params.layer_height, params, this->spacing, + if (params.adaptive_infill_mode == AdaptiveInfillMode::SteppedShells && this->adaptive_infill_field != nullptr) { + fill_adaptive_infill_shells(*this->adaptive_infill_field, expolygon, this->z - 0.5 * params.layer_height, params, this->spacing, [&](const FillParams &shell_params, const ExPolygon &shell) { this->_fill_surface_single(shell_params, thickness_layers, direction, shell, polylines_out); }); @@ -151,10 +151,10 @@ void FillTpmsFK::_fill_surface_single(const FillParams& params, // Enlarge the bounding box by the multi-line width to avoid artifacts at the edges. bbox.offset(scale_((params.multiline + 1) * spacing)); Polylines polylines; - if (params.tpms_adaptive != TpmsAdaptiveMode::Disabled && this->tpms_radial_field != nullptr) { - polylines = make_adaptive_tpms({fischer_koch, 2. * PI / period(params.density), 2. * PI / period(params.tpms_interior_density), - params.tpms_adaptive_gradient}, - *this->tpms_radial_field, bbox, this->z, params.layer_height, spacing, infill_angle); + if (params.adaptive_infill_mode != AdaptiveInfillMode::Disabled && this->adaptive_infill_field != nullptr) { + polylines = make_adaptive_tpms({fischer_koch, 2. * PI / period(params.density), 2. * PI / period(params.adaptive_infill_interior_density), + params.adaptive_infill_gradient}, + *this->adaptive_infill_field, bbox, this->z, params.layer_height, spacing, infill_angle); } else { marchsq::ScalarField sf = marchsq::ScalarField(bbox, this->z, period(params.density)); // Get simplified lines using coarse tolerance of 0.1mm (this is infill). diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index df17940ece..1c809910e0 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -10120,7 +10120,7 @@ bool to_xml(std::stringstream &stream, const EmbossShape::SvgFile &svg, const Mo assert(file_data != nullptr); if (file_data == nullptr && !svg.path.empty()) file_data = read_from_disk(svg.path); if (file_data == nullptr) { - BOOST_LOG_TRIVIAL(warning) << "Can't write svg file no filedata"; + BOOST_LOG_TRIVIAL(warning) << "Can't write SVG file no filedata"; return false; } const std::string &file_data_str = *file_data; @@ -10136,7 +10136,7 @@ void to_xml(std::stringstream &stream, const EmbossShape &es, const ModelVolume stream << " <" << SHAPE_TAG << " "; if (es.svg_file.has_value()) if (!to_xml(stream, *es.svg_file, volume, archive, export_full_path)) { - BOOST_LOG_TRIVIAL(warning) << "Can't write svg file defiden embossed shape into 3mf"; + BOOST_LOG_TRIVIAL(warning) << "Can't write SVG file defiden embossed shape into 3mf"; } stream << SHAPE_SCALE_ATTR << "=\"" << es.scale << "\" "; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 1500483f6e..88fef3bb35 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -6660,10 +6660,6 @@ LayerResult GCode::process_layer( case CalibMode::Calib_Input_shaping_freq: { if (m_layer_index == 1){ gcode += writer().set_input_shaping('A', print.calib_params().start, 0.f, print.calib_params().shaper_type); - if (m_writer.get_gcode_flavor() == gcfKlipper) { - // Disable minimum cruise ratio to ensure consistent motion for calibration - gcode += "SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0\n"; - } } else { if (print.calib_params().freqStartX == print.calib_params().freqStartY && print.calib_params().freqEndX == print.calib_params().freqEndY) { gcode += writer().set_input_shaping('A', 0.f, this->interpolate_value_across_layers(print.calib_params().freqStartX, print.calib_params().freqEndX), ""); @@ -6676,10 +6672,6 @@ LayerResult GCode::process_layer( } case CalibMode::Calib_Input_shaping_damp: { if (m_layer_index == 1){ - if (m_writer.get_gcode_flavor() == gcfKlipper) { - // Disable minimum cruise ratio to ensure consistent motion for calibration - gcode += "SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=0\n"; - } gcode += writer().set_input_shaping('X', 0.f, print.calib_params().freqStartX, print.calib_params().shaper_type); gcode += writer().set_input_shaping('Y', 0.f, print.calib_params().freqStartY, print.calib_params().shaper_type); } else { diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 6346651448..3512df6ab8 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -378,6 +379,11 @@ void GCodeProcessor::TimeMachine::reset() travel_acceleration = 0.0f; max_travel_acceleration = 0.0f; extrude_factor_override_percentage = 1.0f; + klipper = false; + minimum_cruise_ratio = 0.5f; + requested_accel_to_decel = -1.0f; + klipper_junction_flush = 1.0f; + klipper_queue_priming = true; time = 0.0f; stop_times = std::vector(); curr.reset(); @@ -493,16 +499,87 @@ GCodeProcessor::TimeMachine::AdditionalBuffer GCodeProcessor::TimeMachine::merge return merged; } +// Klipper toolhead.py LookAheadQueue.flush: the pseudo-acceleration pass +// reserves cruising distance across a sequence, not separately in each segment. +size_t GCodeProcessor::TimeMachine::plan_klipper(bool lazy) +{ + klipper_junction_flush = requested_accel_to_decel >= 0.0f ? 0.250f : 0.150f; + klipper_queue_priming = false; + size_t flush_count = blocks.size(); + bool update_flush_count = lazy; + float next_start_v2 = 0.0f; + float next_mcr_start_v2 = 0.0f; + float peak_cruise_v2 = 0.0f; + size_t pending = 0; + for (size_t i = blocks.size(); i-- > 0;) { + TimeBlock& block = blocks[i]; + const float delta_v2 = 2.0f * block.distance * block.acceleration; + const float reachable_start_v2 = next_start_v2 + delta_v2; + const float start_v2 = std::min(sqr(block.max_entry_speed), reachable_start_v2); + const float reachable_mcr_v2 = next_mcr_start_v2 + block.mcr_delta_v2; + const float mcr_start_v2 = std::min(block.max_mcr_entry_speed_sqr, reachable_mcr_v2); + float cruise_v2 = -1.0f; + ++pending; + if (mcr_start_v2 < reachable_mcr_v2) { + if (mcr_start_v2 + block.mcr_delta_v2 > next_mcr_start_v2 || pending > 1) { + // Stop at this block, not past it: the blocks above still have a cruise speed + // that depends on moves not yet seen, so only [0, i) may be committed. + if (update_flush_count && peak_cruise_v2 > 0.0f) { + flush_count = i; + update_flush_count = false; + } + peak_cruise_v2 = std::min(sqr(block.feedrate_profile.cruise), + 0.5f * (mcr_start_v2 + reachable_mcr_v2)); + } + cruise_v2 = std::min({0.5f * (start_v2 + reachable_start_v2), + sqr(block.feedrate_profile.cruise), peak_cruise_v2}); + pending = 0; + } + // Until the forward pass, these fields hold v^2, not speeds; -1 marks + // an unassigned cruise speed. A lazy return leaves them in this state. + block.feedrate_profile.entry = start_v2; + block.feedrate_profile.exit = next_start_v2; + block.trapezoid.cruise_feedrate = cruise_v2; + block.peak_cruise_v2 = peak_cruise_v2; + next_start_v2 = start_v2; + next_mcr_start_v2 = mcr_start_v2; + } + if (update_flush_count) + return 0; + // A run of blocks that cannot accelerate is resolved here, once the peak cruise speed of the + // accelerating block that precedes it is known. Each one takes a running minimum with its own + // entry speed, seeded from that peak rather than from the setter's own clamped cruise speed. + float prev_cruise_v2 = 0.0f; + for (size_t i = 0; i < flush_count; ++i) { + TimeBlock& block = blocks[i]; + float cruise_v2 = block.trapezoid.cruise_feedrate; + if (cruise_v2 < 0.0f) { + cruise_v2 = std::min(prev_cruise_v2, block.feedrate_profile.entry); + prev_cruise_v2 = cruise_v2; + } else + prev_cruise_v2 = block.peak_cruise_v2; + const float start_v2 = std::min(block.feedrate_profile.entry, cruise_v2); + const float end_v2 = std::min(block.feedrate_profile.exit, cruise_v2); + // A zero acceleration would put an infinity in the ramp distances; the Marlin helpers guard + // their divides the same way and fall back to a pure cruise. + const float inv_two_accel = block.acceleration > 0.0f ? 0.5f / block.acceleration : 0.0f; + block.feedrate_profile.entry = std::sqrt(start_v2); + block.feedrate_profile.exit = std::sqrt(end_v2); + block.trapezoid.cruise_feedrate = std::sqrt(cruise_v2); + block.trapezoid.accelerate_until = (cruise_v2 - start_v2) * inv_two_accel; + block.trapezoid.decelerate_after = block.distance - (cruise_v2 - end_v2) * inv_two_accel; + } + return flush_count; +} + void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, size_t keep_last_n_blocks, float additional_time, EMoveType target_move_type, bool is_final) { if (!enabled) return; - // Orca: on the finalization pass, drain extra time that is still buffered (e.g. a - // trailing filament change) even with fewer than two blocks queued -- no later pass - // exists to attribute it on. Every other pass keeps the original >= 2 requirement, - // and an empty buffer keeps today's early-return unchanged (no behavior change). + // Drain buffered delays on the final pass, even with no motion left. + // A trailing filament change has no later move to receive its time. const bool drain_final = is_final && !m_additional_time_buffer.empty(); - if (blocks.size() < 2 && !drain_final) { + if ((klipper ? blocks.empty() : blocks.size() < 2) && !drain_final) { // Not enough blocks to attribute the extra time to yet; buffer it so it is // applied on a later pass instead of being dropped. if (additional_time > 0.0f) @@ -510,7 +587,7 @@ void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, P return; } - assert(keep_last_n_blocks <= blocks.size()); + assert(klipper || keep_last_n_blocks <= blocks.size()); // Merge any previously buffered extra time with this call's extra time. Each // entry is applied, in order, to the first block matching its target move type @@ -520,23 +597,36 @@ void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, P additional_buffer.emplace_back(target_move_type, additional_time); additional_buffer = merge_adjacent_additional_time_blocks(additional_buffer); - // reverse_pass - for (int i = static_cast(blocks.size()) - 1; i > 0; --i) { - planner_reverse_pass_kernel(blocks[i - 1], blocks[i]); + size_t n_blocks_process; + if (klipper) { + n_blocks_process = plan_klipper(keep_last_n_blocks != 0); + keep_last_n_blocks = blocks.size() - n_blocks_process; + } else { + for (int i = static_cast(blocks.size()) - 1; i > 0; --i) + planner_reverse_pass_kernel(blocks[i - 1], blocks[i]); + for (size_t i = 0; i + 1 < blocks.size(); ++i) + planner_forward_pass_kernel(blocks[i], blocks[i + 1]); + recalculate_trapezoids(blocks); + n_blocks_process = blocks.size() - keep_last_n_blocks; } - - // forward_pass - for (size_t i = 0; i + 1 < blocks.size(); ++i) { - planner_forward_pass_kernel(blocks[i], blocks[i + 1]); - } - - recalculate_trapezoids(blocks); - - const size_t n_blocks_process = blocks.size() - keep_last_n_blocks; size_t additional_buffer_idx = 0; for (size_t i = 0; i < n_blocks_process; ++i) { const TimeBlock& block = blocks[i]; - float block_time = block.time(); + double motion_time; + if (klipper && block.trapezoid.cruise_feedrate > 0.0f) { + // Integrate using the planned speeds. Reconstructing the exit speed + // from rounded deceleration distance loses precision near a stop. + const double cruise = block.trapezoid.cruise_feedrate; + motion_time = block.distance / cruise; + if (block.acceleration > 0.0f) { + const double accel_delta = cruise - block.feedrate_profile.entry; + const double decel_delta = cruise - block.feedrate_profile.exit; + motion_time += (sqr(accel_delta) + sqr(decel_delta)) / (2.0 * block.acceleration * cruise); + } + } else { + motion_time = block.time(); + } + double block_time = motion_time; if (additional_buffer_idx < additional_buffer.size()) { const EMoveType buf_move_type = additional_buffer[additional_buffer_idx].first; if (buf_move_type == EMoveType::Noop || buf_move_type == block.move_type) { @@ -545,13 +635,13 @@ void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, P } } - time += double(block_time); + time += block_time; // Orca: accumulate per-SkipType time spent inside SKIPPABLE regions, folded into this single // calculate_time write site. Fires fleet-wide (the shipping time_lapse_gcode template stamps // blocks stTimelapse), but writes only skippable_part_time, which has no g-code-emitting // reader until the pre-heat injector consumes it, so output is byte-identical. if (block.skippable_type != SkipType::stNone) - result.skippable_part_time[block.skippable_type] += block.time(); + result.skippable_part_time[block.skippable_type] += motion_time; result.moves[block.move_id].time[static_cast(mode)] = block_time; gcode_time.cache += block_time; //BBS @@ -689,14 +779,12 @@ void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, P if (keep_last_n_blocks) { blocks.erase(blocks.begin(), blocks.begin() + n_blocks_process); - // Ensure that the new first block's entry speed will be preserved to prevent discontinuity - // between the erased blocks' exit speed and the new first block's entry speed. - // Otherwise, the first block's entry speed could be recalculated on the next pass without - // considering that there are no more blocks before this first block. This could lead - // to discontinuity between the exit speed (of already processed blocks) and the entry - // speed of the first block. - TimeBlock &first_block = blocks.front(); - first_block.max_entry_speed = first_block.feedrate_profile.entry; + // Preserve the boundary speed in the Marlin planner. Klipper only flushes + // moves whose cruise speed is already independent of future moves. + if (!klipper) { + TimeBlock& first_block = blocks.front(); + first_block.max_entry_speed = first_block.feedrate_profile.entry; + } } else { blocks.clear(); } @@ -3872,9 +3960,9 @@ void GCodeProcessor::finalize(bool post_process) update_slice_warnings(); } -float GCodeProcessor::get_time(PrintEstimatedStatistics::ETimeMode mode) const +double GCodeProcessor::get_time(PrintEstimatedStatistics::ETimeMode mode) const { - return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? float(m_time_processor.machines[static_cast(mode)].time) : 0.0f; + return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast(mode)].time : 0.0; } float GCodeProcessor::get_prepare_time(PrintEstimatedStatistics::ETimeMode mode) const @@ -5031,6 +5119,14 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line, const std::o if (line.has_e()) g1_axes[E] = (double)line.e(); std::optional g1_feedrate = std::nullopt; if (line.has_f()) g1_feedrate = (double)line.f(); + if (m_flavor == gcfKlipper) { + // Preserve decimal coordinates for short segments without parsing twice. + for (unsigned char axis = X; axis <= E; ++axis) + if (line.has(static_cast(axis))) + g1_axes[axis] = line.precise_value(static_cast(axis)); + if (line.has_f()) + g1_feedrate = line.precise_value(F); + } process_G1(g1_axes, g1_feedrate); } @@ -5228,7 +5324,7 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes //BBS: limite the cruise according to centripetal acceleration //Only need to handle when both prev and curr segment has movement in x-y plane - if ((prev.exit_direction(0) != 0.0f || prev.exit_direction(1) != 0.0f) && + if (m_flavor != gcfKlipper && (prev.exit_direction(0) != 0.0f || prev.exit_direction(1) != 0.0f) && (curr.enter_direction(0) != 0.0f || curr.enter_direction(1) != 0.0f)) { Vec3f v1 = prev.exit_direction; v1(2, 0) = 0.0f; @@ -5252,6 +5348,15 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes } } + if (m_flavor == gcfKlipper && !is_extrusion_only_move(delta_pos)) { + const float max_velocity = get_axis_max_feedrate(static_cast(i), X, m_machine_config_idx); + if (max_velocity > 0.0f) + curr.feedrate = std::min(curr.feedrate, max_velocity); + } + // Klipper applies E limits to retractions and moves without XY motion, + // not to positive extrusion along a printing path. + const bool limit_extruder = m_flavor != gcfKlipper || delta_pos[E] < 0.0 || + (delta_pos[X] == 0.0 && delta_pos[Y] == 0.0); // calculates block cruise feedrate float min_feedrate_factor = 1.0f; for (unsigned char a = X; a <= E; ++a) { @@ -5260,7 +5365,8 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes curr.axis_feedrate[a] *= machine.extrude_factor_override_percentage; curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]); - if (curr.abs_axis_feedrate[a] != 0.0f) { + if (curr.abs_axis_feedrate[a] != 0.0f && (a != E || limit_extruder) && + (m_flavor != gcfKlipper || a == Z || a == E)) { float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a), m_machine_config_idx); if (axis_max_feedrate != 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]); } @@ -5277,20 +5383,42 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes } // calculates block acceleration - float acceleration = - (type == EMoveType::Travel) ? get_travel_acceleration(static_cast(i)) : - (is_extrusion_only_move(delta_pos) ? - get_retract_acceleration(static_cast(i)) : - get_acceleration(static_cast(i))); + float acceleration; + if (m_flavor == gcfKlipper && is_extrusion_only_move(delta_pos)) { + // Klipper's max_extrude_only_accel. machine_max_acceleration_e is optional and some + // shipped profiles leave it at 0, so keep the non-zero retract fallback. + acceleration = get_axis_max_acceleration(static_cast(i), E, m_machine_config_idx); + if (acceleration <= 0.0f) + acceleration = get_retract_acceleration(static_cast(i)); + } else + acceleration = + (m_flavor == gcfKlipper) ? get_acceleration(static_cast(i)) : + (type == EMoveType::Travel) ? get_travel_acceleration(static_cast(i)) : + (is_extrusion_only_move(delta_pos) ? + get_retract_acceleration(static_cast(i)) : + get_acceleration(static_cast(i))); //BBS for (unsigned char a = X; a <= E; ++a) { + if ((a == E && !limit_extruder) || (m_flavor == gcfKlipper && (a == X || a == Y))) + continue; float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a), m_machine_config_idx); + // An unset (0) limit means "no limit", as in the feedrate loop above. Only the Klipper + // planner divides by the block acceleration, so leave the Marlin path as it was. + if (m_flavor == gcfKlipper && axis_max_acceleration <= 0.0f) + continue; if (acceleration * std::abs(delta_pos[a]) * inv_distance > axis_max_acceleration) acceleration = axis_max_acceleration / (std::abs(delta_pos[a]) * inv_distance); } block.acceleration = acceleration; + if (m_flavor == gcfKlipper) { + block.junction_deviation = get_junction_deviation(static_cast(i), acceleration); + const float cruise_acceleration = machine.requested_accel_to_decel >= 0.0f ? + std::min(machine.acceleration, machine.requested_accel_to_decel) : + machine.acceleration * (1.0f - machine.minimum_cruise_ratio); + block.mcr_delta_v2 = 2.0f * distance * std::min(acceleration, cruise_acceleration); + } static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; const bool has_prev_move = !blocks.empty() && prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD; @@ -5401,6 +5529,12 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes block.feedrate_profile.entry = std::min(vmax_junction, v_allowable); block.max_entry_speed = vmax_junction; + if (m_flavor == gcfKlipper && has_prev_move) { + const TimeBlock& previous = blocks.back(); + block.max_entry_speed = std::min(block.max_entry_speed, + std::sqrt(sqr(previous.max_entry_speed) + 2.0f * previous.distance * previous.acceleration)); + block.max_mcr_entry_speed_sqr = std::min(sqr(block.max_entry_speed), previous.max_mcr_entry_speed_sqr + previous.mcr_delta_v2); + } block.flags.nominal_length = (block.feedrate_profile.cruise <= v_allowable); block.flags.recalculate = true; block.safe_feedrate = curr.safe_feedrate; @@ -5412,9 +5546,12 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes prev = curr; blocks.push_back(block); + if (m_flavor == gcfKlipper && blocks.size() > 1) + machine.klipper_junction_flush -= distance / curr.feedrate; } - if (m_time_processor.machines[0].blocks.size() > TimeProcessor::Planner::refresh_threshold) + if (m_flavor == gcfKlipper ? m_time_processor.machines[0].klipper_junction_flush <= 0.0f : + m_time_processor.machines[0].blocks.size() > TimeProcessor::Planner::refresh_threshold) calculate_time(m_result, TimeProcessor::Planner::queue_size); const Vec3f plate_offset = {(float) m_x_offset, (float) m_y_offset, 0.0f}; @@ -6341,6 +6478,8 @@ void GCodeProcessor::process_M108(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M109(const GCodeReader::GCodeLine& line) { + if (m_flavor == gcfKlipper) + simulate_st_synchronize(); int filament_id = get_filament_id(); float new_temp; if (line.has_value('R', new_temp)) { @@ -6403,6 +6542,8 @@ void GCodeProcessor::process_M140(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M190(const GCodeReader::GCodeLine& line) { + if (m_flavor == gcfKlipper) + simulate_st_synchronize(); float new_temp; if (line.has_value('S', new_temp)) m_highest_bed_temp = m_highest_bed_temp < (int)new_temp ? (int)new_temp : m_highest_bed_temp; @@ -6480,6 +6621,21 @@ void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_M204(const GCodeReader::GCodeLine& line) { float value; + if (m_flavor == gcfKlipper) { + if (!line.has_value('S', value)) { + float travel; + if (!line.has_value('P', value) || !line.has_value('T', travel)) + return; + value = std::min(value, travel); + } + // Klipper replaces its single live max_accel for print and travel; the profile-clamping + // setters would diverge from the firmware when custom G-code raises the limit. + if (value > 0.0f) { + for (auto& machine : m_time_processor.machines) + machine.acceleration = machine.travel_acceleration = value; + } + return; + } for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal || m_time_processor.machine_envelope_processing_enabled) { @@ -6541,50 +6697,50 @@ void GCodeProcessor::process_M205(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_SET_VELOCITY_LIMIT(const GCodeReader::GCodeLine& line) { - // handle SQUARE_CORNER_VELOCITY - static const std::regex square_corner_velocity_pattern("\\sSQUARE_CORNER_VELOCITY\\s*=\\s*([0-9]*\\.*[0-9]*)"); - std::smatch matches; - if (std::regex_search(line.raw(), matches, square_corner_velocity_pattern) && matches.size() == 2) { - float _jerk = 0; - try - { - _jerk = std::stof(matches[1]); + static const std::regex parameter_pattern( + R"(\s(VELOCITY|ACCEL|ACCEL_TO_DECEL|SQUARE_CORNER_VELOCITY|MINIMUM_CRUISE_RATIO)\s*=\s*([+]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?)(?=\s|;|$))", + std::regex::icase); + const std::string command = line.raw().substr(0, line.raw().find(';')); + std::vector> parameters; + for (std::sregex_iterator it(command.begin(), command.end(), parameter_pattern), end; it != end; ++it) { + float value; + try { + value = std::stof((*it)[2].str()); + } catch (const std::exception&) { + continue; } - catch (...){} - for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { - set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, _jerk); - set_option_value(m_time_processor.machine_limits.machine_max_jerk_y, i, _jerk); + if (std::isfinite(value)) + parameters.emplace_back(boost::to_upper_copy((*it)[1].str()), value); + } + // Klipper 0.13 converts ACCEL_TO_DECEL only when the line has no MINIMUM_CRUISE_RATIO, and later + // releases ignore it, so a line carrying both (as Orca writes) is planned with the cruise ratio. + const bool has_cruise_ratio = std::any_of(parameters.begin(), parameters.end(), + [](const auto& parameter) { return parameter.first == "MINIMUM_CRUISE_RATIO" && parameter.second >= 0.0f && parameter.second < 1.0f; }); + for (const auto& [name, value] : parameters) { + for (size_t i = 0; i < m_time_processor.machines.size(); ++i) { + TimeMachine& machine = m_time_processor.machines[i]; + // Klipper replaces its single live max_accel for print and travel; the profile-clamping + // setters would diverge from the firmware when custom G-code raises the limit. + if (name == "ACCEL" && value > 0.0f) + machine.acceleration = machine.travel_acceleration = value; + else if (name == "MINIMUM_CRUISE_RATIO" && value >= 0.0f && value < 1.0f) { + if (machine.klipper_queue_priming && machine.requested_accel_to_decel >= 0.0f) + machine.klipper_junction_flush -= 1.0f; + machine.minimum_cruise_ratio = value; + machine.requested_accel_to_decel = -1.0f; + } else if (name == "ACCEL_TO_DECEL" && value > 0.0f && !has_cruise_ratio) { + if (machine.klipper_queue_priming && machine.requested_accel_to_decel < 0.0f) + machine.klipper_junction_flush += 1.0f; + machine.requested_accel_to_decel = value; + } else if (name == "SQUARE_CORNER_VELOCITY" && value >= 0.0f) { + set_option_value(m_time_processor.machine_limits.machine_max_jerk_x, i, value); + set_option_value(m_time_processor.machine_limits.machine_max_jerk_y, i, value); + } else if (name == "VELOCITY" && value > 0.0f) { + set_option_value(m_time_processor.machine_limits.machine_max_speed_x, i, value); + set_option_value(m_time_processor.machine_limits.machine_max_speed_y, i, value); + } } } - - static const std::regex accel_pattern("\\sACCEL\\s*=\\s*([0-9]*\\.*[0-9]*)"); - if (std::regex_search(line.raw(), matches, accel_pattern) && matches.size() == 2) { - float _accl = 0; - try - { - _accl = std::stof(matches[1]); - } - catch (...) {} - for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { - set_acceleration(static_cast(i), _accl); - set_travel_acceleration(static_cast(i), _accl); - } - } - - static const std::regex velocity_pattern("\\sVELOCITY\\s*=\\s*([0-9]*\\.*[0-9]*)"); - if (std::regex_search(line.raw(), matches, velocity_pattern) && matches.size() == 2) { - float _speed = 0; - try - { - _speed = std::stof(matches[1]); - } - catch (...) {} - for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { - set_option_value(m_time_processor.machine_limits.machine_max_speed_x, i, _speed); - set_option_value(m_time_processor.machine_limits.machine_max_speed_y, i, _speed); - } - } - } void GCodeProcessor::process_M221(const GCodeReader::GCodeLine& line) @@ -6621,14 +6777,15 @@ void GCodeProcessor::process_M400(const GCodeReader::GCodeLine& line) { float value_s = 0.0; float value_p = 0.0; - if (line.has_value('S', value_s) || line.has_value('P', value_p)) { - value_s += value_p * 0.001; - // Skip post-print end-gcode dwells so they don't inflate the M73 estimate (see - // m_skip_end_gcode_delays). Only omits dwell time — no state is updated here. - if (m_skip_end_gcode_delays) - return; - simulate_st_synchronize(value_s); - } + const bool has_delay = line.has_value('S', value_s) || line.has_value('P', value_p); + if (m_flavor != gcfKlipper && !has_delay) + return; + value_s += value_p * 0.001; + // Skip post-print end-gcode dwells so they don't inflate the M73 estimate (see + // m_skip_end_gcode_delays). Only omits dwell time — no state is updated here. + if (m_skip_end_gcode_delays && has_delay) + return; + simulate_st_synchronize(value_s); } void GCodeProcessor::process_M401(const GCodeReader::GCodeLine& line) @@ -7460,12 +7617,12 @@ float GCodeProcessor::get_junction_deviation(PrintEstimatedStatistics::ETimeMode { const size_t id = static_cast(mode); - // Klipper has no classic jerk: jd = scv^2 * (sqrt(2) - 1) / max_accel - // (toolhead.py::_calc_junction_deviation). Passing the block acceleration back in makes it cancel - // in calc_vmax_junction_deviation(), leaving the identity v == scv at a 90 degree corner. + // Klipper derives junction deviation from the live toolhead acceleration, + // before a move is constrained by Z or extruder limits. if (m_flavor == gcfKlipper) { // machine_max_jerk_x holds the square corner velocity; process_SET_VELOCITY_LIMIT() writes it. const float scv = get_option_value(m_time_processor.machine_limits.machine_max_jerk_x, id); + acceleration = m_time_processor.machines[id].acceleration; if (scv <= 0.0f || acceleration <= 0.0f) return 0.0f; return sqr(scv) * (std::sqrt(2.0f) - 1.0f) / acceleration; @@ -7497,18 +7654,45 @@ float GCodeProcessor::calc_vmax_junction_deviation(const TimeBlock& block, const const TimeMachine::State& curr, bool has_prev_move, PrintEstimatedStatistics::ETimeMode mode) const { + if (m_flavor == gcfKlipper) { + if (!has_prev_move || curr.enter_direction.isZero() || prev.exit_direction.isZero()) + return 0.0f; + const TimeBlock& previous = m_time_processor.machines[static_cast(mode)].blocks.back(); + double limit = std::min(sqr(double(block.feedrate_profile.cruise)), sqr(double(prev.feedrate))); + const double extrude_ratio_change = std::abs(curr.axis_feedrate[E] / curr.feedrate - + prev.axis_feedrate[E] / prev.feedrate); + // Klipper's instantaneous_corner_velocity defaults to 1 mm/s. + // It is independent of machine_max_jerk_e; custom firmware values + // cannot be inferred from the slicer's jerk setting. + if (extrude_ratio_change > 0.0f) + limit = std::min(limit, sqr(1.0 / extrude_ratio_change)); + // Recover directions from the double-precision axis velocities: float + // unit vectors lose the angle between nearly collinear short segments. + const Vec3d prev_direction = Vec3d(prev.axis_feedrate[X], prev.axis_feedrate[Y], prev.axis_feedrate[Z]).normalized(); + const Vec3d curr_direction = Vec3d(curr.axis_feedrate[X], curr.axis_feedrate[Y], curr.axis_feedrate[Z]).normalized(); + const double cosine = std::clamp(-prev_direction.dot(curr_direction), -1.0, 1.0); + const double sin_half = std::sqrt(0.5 * (1.0 - cosine)); + const double cos_half = std::sqrt(0.5 * (1.0 + cosine)); + if (sin_half < 1.0 && cos_half > 0.0) { + const double radius = sin_half / (1.0 - sin_half); + const double half_tan = 0.5 * sin_half / cos_half; + limit = std::min({limit, + radius * block.junction_deviation * block.acceleration, + radius * previous.junction_deviation * previous.acceleration, + half_tan * block.distance * block.acceleration, + half_tan * previous.distance * previous.acceleration}); + } + return std::sqrt(limit); + } const float junction_deviation = get_junction_deviation(mode, block.acceleration); if (junction_deviation <= 0.0f) return -1.0f; // classic jerk machine, the caller keeps its own computation if (!has_prev_move) return 0.0f; // starts from rest, the planner raises this on the reverse pass - // -1 for a straight continuation, +1 for a full reversal. Half angle identity, no acos()/sin(). - // Both vectors are unit length over XYZE, so this really is a cosine: scaling by 1 / distance - // instead, as PrusaSlicer does, leaves an E term that makes extruding corners look straighter - // than they are. Marlin normalizes over XYZE for any extruding move (planner.cpp, esteps > 0) - // and Klipper keeps E out of the cosine entirely (toolhead.py::Move.calc_junction); both agree - // that the corner is planned by its geometry, and normalizing matches them to within 1e-5. + // Unit vectors over XYZE keep this a cosine. Scaling by 1 / XYZ distance + // leaves an E term that makes extruding corners appear straighter. + // Marlin normalizes over XYZE; the Klipper branch above uses XYZ only. float junction_cos_theta = (-prev.jd_unit_vec).dot(curr.jd_unit_vec); if (junction_cos_theta > 0.999999f) return 0.0f; // the path doubles back, the machine has to stop @@ -7524,8 +7708,8 @@ float GCodeProcessor::calc_vmax_junction_deviation(const TimeBlock& block, const float vmax_junction_sqr = (junction_acceleration * junction_deviation * sin_theta_d2) / (1.0f - sin_theta_d2); // Marlin's JD_HANDLE_SMALL_SEGMENTS: a short move through a shallow corner is treated as an arc and - // capped by the centripetal acceleration it needs. Klipper has no equivalent. - if (m_flavor != gcfKlipper && block.distance < 1.0f && junction_cos_theta < -0.7071067812f) { + // capped by the centripetal acceleration it needs. + if (block.distance < 1.0f && junction_cos_theta < -0.7071067812f) { // Fast acos(-t), max. error +-0.033rad. MinMax polynomial by W. Randolph Franklin: // https://wrf.ecse.rpi.edu/Research/Short_Notes/arcsin/onlyelem.html const float neg = junction_cos_theta < 0.0f ? -1.0f : 1.0f; @@ -7700,6 +7884,7 @@ void GCodeProcessor::calculate_time(GCodeProcessorResult& result, size_t keep_la std::vector actual_speed_moves; for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { TimeMachine& machine = m_time_processor.machines[i]; + machine.klipper = m_flavor == gcfKlipper; machine.calculate_time(m_result, static_cast(i), keep_last_n_blocks, additional_time, target_move_type, is_final); if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal) actual_speed_moves = std::move(machine.actual_speed_moves); @@ -7778,6 +7963,14 @@ void GCodeProcessor::calculate_time(GCodeProcessorResult& result, size_t keep_la void GCodeProcessor::simulate_st_synchronize(float additional_time, EMoveType target_move_type) { calculate_time(m_result, 0, additional_time, target_move_type); + if (m_flavor == gcfKlipper) { + // ToolHead overrides the normal look-ahead window with BUFFER_TIME_HIGH + // at startup and after synchronization: 2 s on legacy, 1 s on modern Klipper. + for (TimeMachine& machine : m_time_processor.machines) { + machine.klipper_junction_flush = machine.requested_accel_to_decel >= 0.0f ? 2.0f : 1.0f; + machine.klipper_queue_priming = true; + } + } } void GCodeProcessor::update_estimated_times_stats() @@ -7812,7 +8005,7 @@ double GCodeProcessor::extract_absolute_position_on_axis(Axis axis, const GCodeR is_relative |= (m_e_local_positioning_type == EPositioningType::Relative); const double lengthsScaleFactor = (m_units == EUnits::Inches) ? double(INCHES_TO_MM) : 1.0; - double ret = line.value(Slic3r::Axis(axis)) * lengthsScaleFactor; + double ret = line.precise_value(Slic3r::Axis(axis)) * lengthsScaleFactor; // if (axis == E && m_use_volumetric_e) // ret /= area_filament_cross_section; return is_relative ? m_start_position[axis] + ret : m_origin[axis] + ret; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 72fb84bad0..b1fc911104 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -91,12 +91,12 @@ inline constexpr float DEFAULT_FILAMENT_DENSITY = 1.245f; struct Mode { - float time; + double time; float prepare_time; std::vector>> custom_gcode_times; void reset() { - time = 0.0f; + time = 0.0; prepare_time = 0.0f; custom_gcode_times.clear(); custom_gcode_times.shrink_to_fit(); @@ -703,6 +703,12 @@ inline constexpr float DEFAULT_FILAMENT_DENSITY = 1.245f; float acceleration{ 0.0f }; // mm/s^2 float max_entry_speed{ 0.0f }; // mm/s float safe_feedrate{ 0.0f }; // mm/s + float junction_deviation{ 0.0f }; + float max_mcr_entry_speed_sqr{ 0.0f }; + float mcr_delta_v2{ 0.0f }; + // Peak cruise speed squared in effect when this block was planned. Only set on a block + // that can accelerate; the delayed blocks after it are seeded from its value. + float peak_cruise_v2{ 0.0f }; Flags flags; FeedrateProfile feedrate_profile; Trapezoid trapezoid; @@ -782,6 +788,11 @@ inline constexpr float DEFAULT_FILAMENT_DENSITY = 1.245f; // hard limit for the travel acceleration, to which the firmware will clamp. float max_travel_acceleration; // mm/s^2 float extrude_factor_override_percentage; + bool klipper{ false }; + float minimum_cruise_ratio{ 0.5f }; + float requested_accel_to_decel{ -1.0f }; + float klipper_junction_flush{ 1.0f }; + bool klipper_queue_priming{ true }; // We accumulate total print time in doubles to reduce the loss of precision // while adding big floating numbers with small float numbers. double time; // s @@ -818,6 +829,8 @@ inline constexpr float DEFAULT_FILAMENT_DENSITY = 1.245f; // Merge adjacent buffer entries that target the same move type. static AdditionalBuffer merge_adjacent_additional_time_blocks(const AdditionalBuffer& buffer); + size_t plan_klipper(bool lazy); + // additional_time is attributed to the first block matching target_move_type // (EMoveType::Noop matches any block, i.e. the first processed block). void calculate_time(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, size_t keep_last_n_blocks = 0, float additional_time = 0.0f, EMoveType target_move_type = EMoveType::Noop, bool is_final = false); @@ -1383,7 +1396,7 @@ inline constexpr float DEFAULT_FILAMENT_DENSITY = 1.245f; void process_buffer(const std::string& buffer); void finalize(bool post_process); - float get_time(PrintEstimatedStatistics::ETimeMode mode) const; + double get_time(PrintEstimatedStatistics::ETimeMode mode) const; float get_prepare_time(PrintEstimatedStatistics::ETimeMode mode) const; std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const; std::vector>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const; diff --git a/src/libslic3r/GCode/OrderingStrategies.cpp b/src/libslic3r/GCode/OrderingStrategies.cpp index 43bf9ecf87..98b8dfa37c 100644 --- a/src/libslic3r/GCode/OrderingStrategies.cpp +++ b/src/libslic3r/GCode/OrderingStrategies.cpp @@ -8,6 +8,7 @@ #include "libslic3r/PrintConfig.hpp" #include +#include #include #include #include @@ -153,6 +154,41 @@ bool tsp_remove_crossings(std::vector& path, const Points& centers) return improved; } +std::vector tsp_exact_cycle(const Points& centers) +{ + const size_t n = centers.size(); + std::vector path(n); + std::iota(path.begin(), path.end(), 0); + if (n <= 3) return path; + // State mask * m + j: the points 1..m of mask visited after point 0, the last one j + 1. + const size_t m = n - 1; + assert(m <= 16); + std::vector cost((size_t(1) << m) * m, std::numeric_limits::max()); + std::vector from(cost.size(), size_t(-1)); + auto dist = [¢ers](size_t a, size_t b) { return (centers[a].cast() - centers[b].cast()).norm(); }; + for (size_t j = 0; j < m; ++j) + cost[(size_t(1) << j) * m + j] = dist(0, j + 1); + for (size_t mask = 1; mask < (size_t(1) << m); ++mask) + for (size_t j = 0; j < m; ++j) + if (const double c = cost[mask * m + j]; c < std::numeric_limits::max()) + for (size_t k = 0; k < m; ++k) + if (!(mask >> k & 1)) { + const size_t next = (mask | size_t(1) << k) * m + k; + if (const double nc = c + dist(j + 1, k + 1); nc < cost[next]) { + cost[next] = nc; + from[next] = mask * m + j; + } + } + const size_t full = (size_t(1) << m) - 1; + size_t best = full * m; + for (size_t j = 1; j < m; ++j) + if (cost[full * m + j] + dist(j + 1, 0) < cost[best] + dist(best % m + 1, 0)) + best = full * m + j; + for (size_t s = best, k = n; k-- > 1; s = from[s]) + path[k] = s % m + 1; + return path; +} + void tsp_rotate_minimize_closing(std::vector& path, const Points& centers) { size_t pn = path.size(); diff --git a/src/libslic3r/GCode/OrderingStrategies.hpp b/src/libslic3r/GCode/OrderingStrategies.hpp index a42a338a52..95a6e77bcf 100644 --- a/src/libslic3r/GCode/OrderingStrategies.hpp +++ b/src/libslic3r/GCode/OrderingStrategies.hpp @@ -29,6 +29,9 @@ bool tsp_2opt_improve(std::vector& path, const Points& centers, int max_ // Returns true if any crossing was removed. bool tsp_remove_crossings(std::vector& path, const Points& centers); +// The shortest cycle through the points, starting at point 0, by dynamic programming over subsets; for a few points only. +std::vector tsp_exact_cycle(const Points& centers); + // Rotate the cycle so the closing edge (last -> first) is minimized. void tsp_rotate_minimize_closing(std::vector& path, const Points& centers); diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index b2ddc75a34..e081717ecf 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -26,6 +26,7 @@ #include "ClipperUtils.hpp" #include "libslic3r/Line.hpp" #include "LocalesUtils.hpp" +#include "libslic3r/GCodeWriter.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/Polygon.hpp" #include "libslic3r/Point.hpp" @@ -1528,8 +1529,10 @@ private: gcode << "M204 P" << acceleration; } else if (m_gcode_flavor == gcfKlipper && m_accel_to_decel_enable) { - gcode << "SET_VELOCITY_LIMIT ACCEL_TO_DECEL=" << acceleration * m_accel_to_decel_factor / 100; - gcode << "\nM204 S" << acceleration; + // One line, so Klipper derives the limit from this acceleration rather than the previous one. + std::string limits = "SET_VELOCITY_LIMIT ACCEL=" + std::to_string(acceleration); + GCodeWriter::append_klipper_accel_to_decel(limits, acceleration, m_accel_to_decel_factor); + gcode << limits; } else { // M204: Set default acceleration diff --git a/src/libslic3r/GCodeReader.cpp b/src/libslic3r/GCodeReader.cpp index eff557d817..1b545f86b5 100644 --- a/src/libslic3r/GCodeReader.cpp +++ b/src/libslic3r/GCodeReader.cpp @@ -95,7 +95,7 @@ const char* GCodeReader::parse_line_internal(const char *ptr, const char *end, G if (pend != c && is_end_of_word(*pend)) { // The axis value has been parsed correctly. if (axis != UNKNOWN_AXIS) - gline.m_axis[int(axis)] = float(v); + gline.m_axis[int(axis)] = v; gline.m_mask |= 1 << int(axis); c = pend; } else diff --git a/src/libslic3r/GCodeReader.hpp b/src/libslic3r/GCodeReader.hpp index e65dff193c..97699a99e1 100644 --- a/src/libslic3r/GCodeReader.hpp +++ b/src/libslic3r/GCodeReader.hpp @@ -35,7 +35,8 @@ public: std::string_view axis_pos(char axis) const; void clear() { m_raw.clear(); } bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; } - float value(Axis axis) const { return m_axis[axis]; } + float value(Axis axis) const { return float(m_axis[axis]); } + double precise_value(Axis axis) const { return m_axis[axis]; } bool has(char axis) const; bool has_value(char axis, float &value) const; // Parse value of an axis from raw string starting at axis_pos. @@ -72,15 +73,15 @@ public: bool has_p() const { return this->has(P); } bool has_unknown_axis() const { return this->has(UNKNOWN_AXIS); } - float x() const { return m_axis[X]; } - float y() const { return m_axis[Y]; } - float z() const { return m_axis[Z]; } - float e() const { return m_axis[E]; } - float f() const { return m_axis[F]; } + float x() const { return float(m_axis[X]); } + float y() const { return float(m_axis[Y]); } + float z() const { return float(m_axis[Z]); } + float e() const { return float(m_axis[E]); } + float f() const { return float(m_axis[F]); } // BBS: add I J P axis - float i() const { return m_axis[I]; } - float j() const { return m_axis[J]; } - float p() const { return m_axis[P]; } + float i() const { return float(m_axis[I]); } + float j() const { return float(m_axis[J]); } + float p() const { return float(m_axis[P]); } static bool cmd_is(const std::string &gcode_line, const char *cmd_test) { const char *cmd = GCodeReader::skip_whitespaces(gcode_line.c_str()); @@ -100,7 +101,7 @@ public: } private: std::string m_raw; - float m_axis[NUM_AXES]; + double m_axis[NUM_AXES]; uint32_t m_mask; friend class GCodeReader; }; diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index 62382f8214..805e6e2f52 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -453,12 +453,11 @@ std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned i gcode += separate_travel ? "M204 T" : "M204 P"; gcode += value; } else if (FLAVOR_IS(gcfKlipper)) { - gcode.reserve(96); + gcode.reserve(128); gcode += "SET_VELOCITY_LIMIT ACCEL="; gcode += value; if (this->config.accel_to_decel_enable) { - gcode += " ACCEL_TO_DECEL="; - gcode += float_to_string_decimal_point(acceleration * this->config.accel_to_decel_factor / 100); + append_klipper_accel_to_decel(gcode, acceleration, this->config.accel_to_decel_factor.value); if (GCodeWriter::full_gcode_comment) gcode += " ; adjust ACCEL_TO_DECEL"; } @@ -473,6 +472,14 @@ std::string GCodeWriter::set_acceleration_internal(Acceleration type, unsigned i return gcode; } +void GCodeWriter::append_klipper_accel_to_decel(std::string &gcode, unsigned int acceleration, double accel_to_decel_factor) +{ + gcode += " ACCEL_TO_DECEL="; + gcode += float_to_string_decimal_point(acceleration * accel_to_decel_factor / 100); + gcode += " MINIMUM_CRUISE_RATIO="; + gcode += float_to_string_decimal_point(1. - accel_to_decel_factor / 100); +} + std::string GCodeWriter::set_jerk_xy(double jerk) { if (jerk < 0.01 || is_approx(jerk, m_last_jerk)) @@ -548,15 +555,13 @@ std::string GCodeWriter::set_accel_and_jerk(unsigned int acceleration, double je return std::string(); std::string gcode; - gcode.reserve(96); + gcode.reserve(128); gcode += "SET_VELOCITY_LIMIT"; if (set_acceleration) { gcode += " ACCEL="; gcode += std::to_string(acceleration); - if (this->config.accel_to_decel_enable) { - gcode += " ACCEL_TO_DECEL="; - gcode += float_to_string_decimal_point(acceleration * this->config.accel_to_decel_factor / 100); - } + if (this->config.accel_to_decel_enable) + append_klipper_accel_to_decel(gcode, acceleration, this->config.accel_to_decel_factor.value); m_last_acceleration = acceleration; } if (set_jerk) { diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index 3c90a4e9e1..fcbd68b282 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -71,6 +71,10 @@ public: std::string set_jerk_xy(double jerk); // Orca: set acceleration and jerk in one command for Klipper std::string set_accel_and_jerk(unsigned int acceleration, double jerk); + // Orca: Klipper's accel_to_decel limit for `acceleration`, sent as the legacy ACCEL_TO_DECEL and as the + // equivalent MINIMUM_CRUISE_RATIO = 1 - ACCEL_TO_DECEL / ACCEL that replaced it. Klipper before 0.13 and + // vendor forks read only the first, current Klipper only the second, and 0.13 prefers the second. + static void append_klipper_accel_to_decel(std::string &gcode, unsigned int acceleration, double accel_to_decel_factor); std::string set_junction_deviation(double junction_deviation); std::string set_pressure_advance(double pa, int tool = -1) const; std::string set_input_shaping(char axis, float damp, float freq, std::string type) const; diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 20eff0446f..8e58a5e671 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -443,8 +443,8 @@ coordf_t Layer::get_sparse_infill_max_void_area() if (density == 0.) return -1; // Orca: the adaptive TPMS infill is as sparse as its interior density. - if (density < 100.f && config.tpms_adaptive != TpmsAdaptiveMode::Disabled && is_tpms_adaptive_pattern(pattern)) - density = std::min(density, std::max(1.f, float(config.tpms_interior_density))); + if (density < 100.f && config.adaptive_infill_mode != AdaptiveInfillMode::Disabled && is_adaptive_infill_pattern(pattern)) + density = std::min(density, std::max(1.f, float(config.adaptive_infill_interior_density))); //BBS: rough estimation and need to be optimized double spacing = flow.scaled_spacing() * (100 - density) / density; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 4ae928cc95..81b78ec092 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -797,7 +797,7 @@ bool Preset::save(DynamicPrintConfig* parent_config) { ConfigOption *opt_src = config.option(option); ConfigOption *opt_dst = temp_config.option(option, true); - if (opt_dst->is_scalar() || !(opt_dst->nullable())) + if (opt_dst->is_scalar() || !(opt_dst->nullable()) || is_filament_extruder_override_key(option)) opt_dst->set(opt_src); else { ConfigOptionVectorBase* opt_vec_src = static_cast(opt_src); @@ -1183,9 +1183,9 @@ static std::vector s_Preset_print_options{ "is_infill_first", "sparse_infill_density", "fill_multiline", - "tpms_adaptive", - "tpms_interior_density", - "tpms_adaptive_gradient", + "adaptive_infill_mode", + "adaptive_infill_interior_density", + "adaptive_infill_gradient", "gyroid_optimized", "sparse_infill_pattern", "sparse_infill_smooth_factor", @@ -1421,6 +1421,7 @@ static std::vector s_Preset_print_options{ "initial_layer_travel_acceleration", "initial_layer_travel_jerk", "exclude_object", + "exclude_object_tolerance", "slow_down_layers", "infill_anchor", "infill_anchor_max", @@ -2131,7 +2132,7 @@ Preset* PresetCollection::get_preset_differed_for_save(Preset& preset) { ConfigOption *opt_src = preset.config.option(option); ConfigOption *opt_dst = temp_config.option(option, true); - if (opt_dst->is_scalar() || !(opt_dst->nullable())) + if (opt_dst->is_scalar() || !(opt_dst->nullable()) || is_filament_extruder_override_key(option)) opt_dst->set(opt_src); else { ConfigOptionVectorBase* opt_vec_src = static_cast(opt_src); @@ -2198,9 +2199,12 @@ int PresetCollection::get_differed_values_to_update(Preset& preset, std::map 100%), silently // resurrecting an override the user turned off. See GitHub issue on Retract Before Wipe. if (m_type == Preset::TYPE_FILAMENT) { - for (const std::string& opt_key : filament_extruder_override_keys) { - if (key_values.count(opt_key)) - continue; // already carried by the diff + for (const std::string& opt_key : preset.config.keys()) { + if (!is_filament_extruder_override_key(opt_key) || key_values.count(opt_key)) + continue; // not an override, or already carried by the diff + const ConfigOptionDef *def = print_config_def.get(opt_key); + if (def == nullptr || !def->default_value || def->default_value->is_nil()) + continue; // the option's default is nil too, so an absent key cannot come back as a value const auto* opt_vec = dynamic_cast(preset.config.option(opt_key)); if (opt_vec == nullptr) continue; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 93a71dcd8d..e9f741b890 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -309,6 +309,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "gcode_comments", "gcode_label_objects", "exclude_object", + "exclude_object_tolerance", "support_material_interface_fan_speed", "internal_bridge_fan_speed", // ORCA: Add support for separate internal bridge fan speed control "ironing_fan_speed", @@ -6929,7 +6930,7 @@ BoundingBoxf3 PrintInstance::get_bounding_box() const { Polygon PrintInstance::get_convex_hull_2d() { Polygon poly = print_object->model_object()->convex_hull_2d(model_instance->get_matrix()); - poly.douglas_peucker(scale_(0.1)); + poly.douglas_peucker(scale_(print_object->print()->config().exclude_object_tolerance.value)); return poly; } diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 11de1d80e4..b36349c587 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -12,7 +12,7 @@ #include "PrintBase.hpp" #include "Fill/FillAdaptive.hpp" #include "Fill/FillLightning.hpp" -#include "Fill/FillTpmsAdaptive.hpp" +#include "Fill/AdaptiveInfillField.hpp" #include "BoundingBox.hpp" #include "ExtrusionEntityCollection.hpp" @@ -407,7 +407,7 @@ public: double max_z() const { return m_max_z; } // Centering offset of the sliced mesh from the scaled and rotated mesh of the model. const Point& center_offset() const { return m_center_offset; } - const TpmsRadialField* tpms_radial_field(TpmsAdaptiveMode mode) const { return m_tpms_radial_fields[size_t(mode)].get(); } + const AdaptiveInfillField* adaptive_infill_field(AdaptiveInfillMode mode) const { return m_adaptive_infill_fields[size_t(mode)].get(); } // BBS void generate_support_preview(); @@ -655,7 +655,7 @@ private: FillAdaptive::RegionOctrees prepare_adaptive_infill_data( const std::vector>& surfaces_w_layer) const; FillLightning::GeneratorPtr prepare_lightning_infill_data(); - TpmsRadialFields prepare_tpms_radial_fields() const; + AdaptiveInfillFields prepare_adaptive_infill_fields() const; // BBS SupportNecessaryType is_support_necessary(); @@ -706,7 +706,7 @@ private: FillAdaptive::RegionOctrees m_adaptive_fill_octrees; std::vector m_separated_body_bboxes; FillLightning::GeneratorPtr m_lightning_generator; - TpmsRadialFields m_tpms_radial_fields; + AdaptiveInfillFields m_adaptive_infill_fields; std::vector < VolumeSlices > firstLayerObjSliceByVolume; std::vector firstLayerObjSliceByGroups; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index bab1d1b586..212d8d8cb5 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -119,12 +119,18 @@ const std::vector filament_extruder_override_keys = { }; // Some filament override parameters are generated from filament_extruder_override_keys, -// while filament_retract_length_nc is defined separately. Keep the generator list -// unchanged and use this helper for behavior checks that need the full override set. +// while filament_retract_length_nc and the ironing overrides are defined separately. +// Keep the generator list unchanged and use this helper for behavior checks that need +// the full override set. A nil in one of these keys means the override is disabled, so +// child presets store and load it verbatim instead of treating nil as "inherit". bool is_filament_extruder_override_key(const std::string &opt_key) { return std::find(filament_extruder_override_keys.begin(), filament_extruder_override_keys.end(), opt_key) != filament_extruder_override_keys.end() || - opt_key == "filament_retract_length_nc"; + opt_key == "filament_retract_length_nc" || + opt_key == "filament_ironing_flow" || + opt_key == "filament_ironing_spacing" || + opt_key == "filament_ironing_inset" || + opt_key == "filament_ironing_speed"; } size_t get_extruder_index(const GCodeConfig& config, unsigned int filament_id) @@ -366,24 +372,24 @@ static t_config_enum_values s_keys_map_SurfaceFillOrder{ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SurfaceFillOrder) //Orca -static t_config_enum_values s_keys_map_TpmsAdaptiveMode{ - { "disabled", int(TpmsAdaptiveMode::Disabled) }, - { "distance_warp", int(TpmsAdaptiveMode::DistanceWarp) }, - { "smooth_blend", int(TpmsAdaptiveMode::SmoothBlend) }, - { "stepped_shells", int(TpmsAdaptiveMode::SteppedShells) }, - { "lobes", int(TpmsAdaptiveMode::Lobes) }, - { "normal_z", int(TpmsAdaptiveMode::NormalZ) }, - { "normal_y", int(TpmsAdaptiveMode::NormalY) }, - { "normal_x", int(TpmsAdaptiveMode::NormalX) }, +static t_config_enum_values s_keys_map_AdaptiveInfillMode{ + { "disabled", int(AdaptiveInfillMode::Disabled) }, + { "distance_warp", int(AdaptiveInfillMode::DistanceWarp) }, + { "smooth_blend", int(AdaptiveInfillMode::SmoothBlend) }, + { "stepped_shells", int(AdaptiveInfillMode::SteppedShells) }, + { "lobes", int(AdaptiveInfillMode::Lobes) }, + { "normal_z", int(AdaptiveInfillMode::NormalZ) }, + { "normal_y", int(AdaptiveInfillMode::NormalY) }, + { "normal_x", int(AdaptiveInfillMode::NormalX) }, }; -CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TpmsAdaptiveMode) +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(AdaptiveInfillMode) -static t_config_enum_values s_keys_map_TpmsAdaptiveGradient{ - { "linear", int(TpmsAdaptiveGradient::Linear) }, - { "quadratic", int(TpmsAdaptiveGradient::Quadratic) }, - { "exponential", int(TpmsAdaptiveGradient::Exponential) }, +static t_config_enum_values s_keys_map_AdaptiveInfillGradient{ + { "linear", int(AdaptiveInfillGradient::Linear) }, + { "quadratic", int(AdaptiveInfillGradient::Quadratic) }, + { "exponential", int(AdaptiveInfillGradient::Exponential) }, }; -CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TpmsAdaptiveGradient) +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(AdaptiveInfillGradient) //BBS static t_config_enum_values s_keys_map_PrintSequence { @@ -3660,7 +3666,7 @@ void PrintConfigDef::init_fff_params() def->max = 10; // Maximum number of lines for infill pattern def->set_default_value(new ConfigOptionInt(1)); - def = this->add("tpms_adaptive", coEnum); + def = this->add("adaptive_infill_mode", coEnum); def->label = L("Adaptive density (experimental)"); def->category = L("Strength"); def->tooltip = L("Grades the Gyroid and TPMS infill inside the object: its cells grow from the surface of the " @@ -3678,7 +3684,7 @@ void PrintConfigDef::init_fff_params() "joined to the rest by a narrower neck, is graded towards its own center.\n" " - Normal Z, Y or X: follows the sections of the object normal to that axis, so the density " "does not change along it."); - def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("disabled"); def->enum_values.push_back("distance_warp"); def->enum_values.push_back("smooth_blend"); @@ -3696,9 +3702,9 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Normal Y")); def->enum_labels.push_back(L("Normal X")); def->mode = comAdvanced; - def->set_default_value(new ConfigOptionEnum(TpmsAdaptiveMode::Disabled)); + def->set_default_value(new ConfigOptionEnum(AdaptiveInfillMode::Disabled)); - def = this->add("tpms_interior_density", coPercent); + def = this->add("adaptive_infill_interior_density", coPercent); def->label = L("Interior density"); def->category = L("Strength"); def->tooltip = L("Density of the adaptive infill at the center of the object."); @@ -3708,7 +3714,7 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercent(5)); - def = this->add("tpms_adaptive_gradient", coEnum); + def = this->add("adaptive_infill_gradient", coEnum); def->label = L("Adaptive gradient"); def->category = L("Strength"); def->tooltip = L("How the density changes from the surface to the center of the object.\n" @@ -3717,7 +3723,7 @@ void PrintConfigDef::init_fff_params() "changes faster towards the center.\n" "Exponential: the density changes quickly just below the surface and levels off towards " "the center."); - def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back("linear"); def->enum_values.push_back("quadratic"); def->enum_values.push_back("exponential"); @@ -3725,7 +3731,7 @@ void PrintConfigDef::init_fff_params() def->enum_labels.push_back(L("Quadratic")); def->enum_labels.push_back(L("Exponential")); def->mode = comAdvanced; - def->set_default_value(new ConfigOptionEnum(TpmsAdaptiveGradient::Linear)); + def->set_default_value(new ConfigOptionEnum(AdaptiveInfillGradient::Linear)); // Z-buckling bias optimization (experimental). Tightens the gyroid wave along the Z // (vertical) axis at low infill density to shorten the effective column length under @@ -4629,6 +4635,17 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("exclude_object_tolerance", coFloat); + def->label = L("Outline tolerance"); + def->tooltip = L("Maximum deviation of the object outline written to EXCLUDE_OBJECT_DEFINE from the " + "original outline. Larger values give fewer points, which helps firmware that stalls " + "while parsing G-code with many objects. 0 keeps every point."); + def->sidetext = L("mm"); + def->min = 0; + def->max = 5; + def->mode = comExpert; + def->set_default_value(new ConfigOptionFloat(0.1)); + def = this->add("gcode_comments", coBool); def->label = L("Verbose G-code"); def->tooltip = L("Enable this to get a commented G-code file, with each line explained by a descriptive text. " @@ -9654,6 +9671,12 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va opt_key = "change_filament_gcode"; } else if (opt_key == "bridge_fan_speed") { opt_key = "overhang_fan_speed"; + } else if (opt_key == "tpms_adaptive") { + opt_key = "adaptive_infill_mode"; + } else if (opt_key == "tpms_interior_density") { + opt_key = "adaptive_infill_interior_density"; + } else if (opt_key == "tpms_adaptive_gradient") { + opt_key = "adaptive_infill_gradient"; } else if (opt_key == "infill_extruder" || opt_key == "sparse_infill_filament") { // ORCA: legacy feature-filament selector. Pre-2.4.0-dev these keys were 1-based and the // default value "1" meant "the first/active filament". The current scheme uses a dedicated @@ -12255,7 +12278,8 @@ void DynamicPrintConfig::update_diff_values_to_child_config(DynamicPrintConfig& opt_src->set(opt_target); } else - opt_vec_src->set_only_diff(opt_vec_dest, variant_index, stride); + // An override's nil means "disabled" and is the child's value; every other nil column inherits. + opt_vec_src->set_only_diff(opt_vec_dest, variant_index, stride, is_filament_extruder_override_key(opt)); } } } @@ -13476,12 +13500,30 @@ static std::map s_CustomGcodeSpecificP // Machine G-code {"file_start_gcode", {}}, {"machine_start_gcode", {}}, - {"machine_end_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id"}}, + {"machine_end_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id", + "current_filament_id", "current_extruder_id", "current_nozzle_id", + "nozzle_diameter_at_nozzle_id", "nozzle_volume_types"}}, {"before_layer_change_gcode", {"layer_num", "layer_z", "max_layer_z"}}, - {"layer_change_gcode", {"layer_num", "layer_z", "max_layer_z"}}, - {"timelapse_gcode", {"layer_num", "layer_z", "max_layer_z"}}, - {"change_filament_gcode", {"layer_num", "layer_z", "max_layer_z", "next_extruder", "previous_extruder", "fan_speed", + {"layer_change_gcode", {"layer_num", "layer_z", "max_layer_z", "most_used_physical_extruder_id", + "current_filament_id", "current_nozzle_id", "curr_y_acceleration_limit", + "curr_accumulated_mass", "curr_layer_mass"}}, + {"timelapse_gcode", {"layer_num", "layer_z", "max_layer_z", "most_used_physical_extruder_id", + "curr_physical_extruder_id", "timelapse_pos_x", "timelapse_pos_y", + "has_timelapse_safe_pos", "timelapse_inline_photo", + "farthest_point_timelapse_enabled", "clear_to_x0"}}, + {"wrapping_detection_gcode", {"layer_num", "layer_z", "max_layer_z", "most_used_physical_extruder_id", + "curr_physical_extruder_id"}}, + {"change_filament_gcode", {"layer_num", "layer_z", "max_layer_z", "next_extruder", "previous_extruder", + "current_hotend", "next_hotend", "current_nozzle_id", "next_nozzle_id", + "current_filament_id", "next_filament_id", "old_extruder_variant", "new_extruder_variant", + "nozzle_diameter_at_nozzle_id", "nozzle_volume_types", "filament_retract_length_nc", + "new_extruder_retracted_length", "outer_wall_volumetric_speed", "fan_speed", "first_flush_volume", "flush_length_1", "flush_length_2", "flush_length_3", "flush_length_4", + "flush_length", "flush_volumetric_speeds", "flush_temperatures", "filament_cooling_before_tower", + "wipe_avoid_perimeter", "wipe_avoid_pos_x", "is_prime_tower_interface", + "filament_tower_interface_purge_volume", "filament_tower_interface_print_temp", + "wipe_tower_center_pos_x", "wipe_tower_center_pos_y", "wipe_tower_center_pos_valid", + "temperature", "nozzle_temperature", "first_layer_temperature", "nozzle_temperature_initial_layer", "new_filament_e_feedrate", "new_filament_temp", "new_retract_length", "new_retract_length_toolchange", "old_filament_e_feedrate", "old_filament_temp", "old_retract_length", "old_retract_length_toolchange", "relative_e_axis", "second_flush_volume", "toolchange_count", "toolchange_z", @@ -13494,8 +13536,18 @@ static std::map s_CustomGcodeSpecificP {"machine_pause_gcode", {}}, {"template_custom_gcode", {}}, // Filament G-code - {"filament_start_gcode", {"filament_extruder_id"}}, - {"filament_end_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id"}}, + {"filament_start_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id", + "current_filament_id", "current_extruder_id", "current_nozzle_id", + "nozzle_diameter_at_nozzle_id", "nozzle_volume_types", + "retraction_distance_when_cut", "long_retraction_when_cut", + "temperature", "nozzle_temperature", "first_layer_temperature", + "nozzle_temperature_initial_layer"}}, + {"filament_end_gcode", {"layer_num", "layer_z", "max_layer_z", "filament_extruder_id", + "current_filament_id", "current_extruder_id", "current_nozzle_id", + "nozzle_diameter_at_nozzle_id", "nozzle_volume_types", + "retraction_distance_when_cut", "long_retraction_when_cut", + "temperature", "nozzle_temperature", "first_layer_temperature", + "nozzle_temperature_initial_layer"}}, }; const std::map& custom_gcode_specific_placeholders() @@ -13524,11 +13576,44 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef() def->label = L("Filament extruder ID"); def->tooltip = L("The current extruder ID. The same as current_extruder."); + new_def("current_filament_id", coInt, L("Current filament ID"), L("Index of the currently active filament. The index is zero-based (first filament has index 0).")); + new_def("current_extruder_id", coInt, L("Current extruder ID"), L("Index of the currently active physical extruder. The index is zero-based (first extruder has index 0).")); + new_def("current_nozzle_id", coInt, L("Current nozzle ID"), L("Index of the currently active nozzle. The index is zero-based (first nozzle has index 0).")); + new_def("nozzle_diameter_at_nozzle_id", coFloats, L("Nozzle diameters"), L("Nozzle diameters indexed by nozzle ID.")); + new_def("nozzle_volume_types", coStrings, L("Nozzle volume types"), L("Nozzle volume variants indexed by nozzle ID.")); + new_def("retraction_distance_when_cut", coFloat, L("Retraction distance when cut"), L("Retraction distance used when cutting filament.")); + new_def("long_retraction_when_cut", coBool, L("Long retraction when cut"), L("Whether long retraction is used when cutting filament.")); + +// layer_change_gcode + new_def("most_used_physical_extruder_id", coInt, L("Most-used physical extruder ID"), L("Index of the physical extruder used most often on the current layer. The index is zero-based (first extruder has index 0).")); + new_def("curr_y_acceleration_limit", coFloat, L("Current Y acceleration limit"), L("Current Y-axis acceleration limit after the bed-mass adjustment.")); + new_def("curr_accumulated_mass", coFloat, L("Current accumulated mass"), L("Accumulated printed mass at the current layer.")); + new_def("curr_layer_mass", coFloat, L("Current layer mass"), L("Printed mass of the previous layer.")); + +// timelapse_gcode + new_def("curr_physical_extruder_id", coInt, L("Current physical extruder ID"), L("Index of the physical extruder active for the current layer. The index is zero-based (first extruder has index 0).")); + new_def("timelapse_pos_x", coInt, L("Timelapse position X"), L("Selected X position for timelapse capture.")); + new_def("timelapse_pos_y", coInt, L("Timelapse position Y"), L("Selected Y position for timelapse capture.")); + new_def("has_timelapse_safe_pos", coBool, L("Has timelapse safe position"), L("Whether a safe timelapse position was found.")); + new_def("timelapse_inline_photo", coBool, L("Timelapse inline photo"), L("Whether the timelapse photo is captured at the inline position.")); + new_def("farthest_point_timelapse_enabled", coBool, L("Farthest-point timelapse enabled"), L("Whether farthest-point timelapse positioning is active.")); + new_def("clear_to_x0", coBool, L("Clear to X0"), L("Whether the timelapse move is clear to X0.")); + // change_filament_gcode new_def("previous_extruder", coInt, L("Previous extruder"), L("Index of the extruder that is being unloaded. The index is zero based (first extruder has index 0).")); new_def("next_extruder", coInt, L("Next extruder"), L("Index of the extruder that is being loaded. The index is zero based (first extruder has index 0).")); + new_def("current_hotend", coInt, L("Current hotend"), L("Zero-based extruder index of the outgoing filament. On Bambu printers it is -1, or the nozzle ID when a filament moves between nozzles across layers.")); + new_def("next_hotend", coInt, L("Next hotend"), L("Zero-based extruder index of the incoming filament. On Bambu printers it is -1, or the nozzle ID when a filament moves between nozzles across layers.")); + new_def("next_nozzle_id", coInt, L("Next nozzle ID"), L("Index of the nozzle associated with the incoming filament. The index is zero-based (first nozzle has index 0).")); + new_def("next_filament_id", coInt, L("Next filament ID"), L("Index of the incoming filament. The index is zero-based (first filament has index 0).")); + new_def("old_extruder_variant", coString, L("Old extruder variant"), L("Nozzle-volume variant of the outgoing extruder.")); + new_def("new_extruder_variant", coString, L("New extruder variant"), L("Nozzle-volume variant of the incoming extruder.")); + new_def("filament_retract_length_nc", coFloat, L("Filament nozzle-change retract length"), L("Nozzle-change retraction length of the outgoing filament.")); + new_def("new_extruder_retracted_length", coFloat, L("New extruder retracted length"), L("Currently parked retraction length of the incoming extruder.")); + new_def("outer_wall_volumetric_speed", coFloat, L("Outer wall volumetric speed"), L("Volumetric speed used for the outer wall.")); new_def("relative_e_axis", coBool, L("Relative e-axis"), L("Indicates if relative positioning is being used.")); new_def("toolchange_count", coInt, L("Toolchange count"), L("The number of toolchanges throughout the print.")); + new_def("toolchange_z", coFloat, L("Toolchange Z"), L("The Z position during the toolchange.")); new_def("fan_speed", coNone, "", ""); //Option is no longer used and is zeroed by placeholder parser for compatability new_def("old_retract_length", coFloat, L("Old retract length"), L("The retraction length of the previous filament.")); new_def("new_retract_length", coFloat, L("New retract length"), L("The retraction length of the new filament.")); @@ -13553,6 +13638,22 @@ CustomGcodeSpecificConfigDef::CustomGcodeSpecificConfigDef() new_def("flush_length_2", coFloat, L("Flush Length 2"), L("The second flush length.")); new_def("flush_length_3", coFloat, L("Flush Length 3"), L("The third flush length.")); new_def("flush_length_4", coFloat, L("Flush Length 4"), L("The fourth flush length.")); + new_def("flush_length", coFloat, L("Flush length"), L("Total flush length.")); + new_def("flush_volumetric_speeds", coFloats, L("Flush volumetric speeds"), L("Flush volumetric speeds for each filament.")); + new_def("flush_temperatures", coInts, L("Flush temperatures"), L("Flush temperatures for each filament.")); + new_def("filament_cooling_before_tower", coFloats, L("Filament cooling before tower"), L("Temperature drop before entering filament tower")); + new_def("wipe_avoid_perimeter", coBool, L("Avoid wipe perimeter"), L("Whether travel should avoid the wipe perimeter.")); + new_def("wipe_avoid_pos_x", coFloat, L("Wipe avoidance X"), L("X position used to avoid the wipe area.")); + new_def("is_prime_tower_interface", coBool, L("Prime tower interface"), L("Whether the current purge is for a prime-tower interface.")); + new_def("filament_tower_interface_purge_volume", coFloat, L("Interface layer purge length"), L("Purge length for prime tower interface layer (where different materials meet).")); + new_def("filament_tower_interface_print_temp", coInt, L("Filament tower interface print temperature"), L("Print temperature used for the filament tower interface.")); + new_def("wipe_tower_center_pos_x", coFloat, L("Wipe tower center X"), L("X coordinate of the nozzle's wipe-tower wait position, 2 mm outside the tower edge.")); + new_def("wipe_tower_center_pos_y", coFloat, L("Wipe tower center Y"), L("Y coordinate of the nozzle's wipe-tower wait position.")); + new_def("wipe_tower_center_pos_valid", coBool, L("Wipe tower center position valid"), L("Whether the print has a wipe tower.")); + new_def("temperature", coInts, L("Temperature"), L("Nozzle temperatures indexed by filament.")); + new_def("nozzle_temperature", coInts, L("Nozzle temperature"), L("Nozzle temperatures indexed by filament.")); + new_def("first_layer_temperature", coInts, L("First layer temperature"), L("First-layer nozzle temperatures indexed by filament.")); + new_def("nozzle_temperature_initial_layer", coInts, L("Nozzle temperature initial layer"), L("First-layer nozzle temperatures indexed by filament.")); // change_extrusion_role_gcode // The whole tooltip is one literal so that the GUI can look it up in the catalog. diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 8b724a7058..55e82656f0 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -172,8 +172,8 @@ inline bool is_separable_infill_pattern(InfillPattern pattern) // Orca: Infill patterns laid out by an octree, which each connected body always gets of its own. inline bool is_octree_infill_pattern(InfillPattern pattern) { return pattern == ipAdaptiveCubic || pattern == ipSupportCubic; } -// Orca: Infill patterns graded by the "tpms_adaptive" option. -inline bool is_tpms_adaptive_pattern(InfillPattern pattern) { return pattern == ipGyroid || pattern == ipTpmsD || pattern == ipTpmsFK; } +// Orca: Infill patterns graded by the "adaptive_infill_mode" option. +inline bool is_adaptive_infill_pattern(InfillPattern pattern) { return pattern == ipGyroid || pattern == ipTpmsD || pattern == ipTpmsFK; } // Orca: Infill patterns that round their corners by the "sparse_infill_smooth_factor" option. // Grid, Triangles and Tri-hexagon only do so in their trapezoidal form, which is generated with more @@ -279,8 +279,8 @@ enum class SurfaceFillOrder { Count, }; -// Orca: what the adaptive TPMS density follows: the 3D shape of the object, or its 2D sections normal to an axis. -enum class TpmsAdaptiveMode { +// Orca: what the adaptive infill density follows: the 3D shape of the object, or its 2D sections normal to an axis. +enum class AdaptiveInfillMode { Disabled, DistanceWarp, SmoothBlend, @@ -292,8 +292,8 @@ enum class TpmsAdaptiveMode { Count, }; -// Orca: how the adaptive TPMS density changes from the object surface to its deepest point. -enum class TpmsAdaptiveGradient { +// Orca: how the adaptive infill density changes from the object surface to its deepest point. +enum class AdaptiveInfillGradient { Linear, Quadratic, Exponential, @@ -816,8 +816,8 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ToolChangeOrderingType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PowerLossRecoveryMode) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SurfaceFillOrder) -CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(TpmsAdaptiveMode) -CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(TpmsAdaptiveGradient) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AdaptiveInfillMode) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AdaptiveInfillGradient) #undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS @@ -1501,9 +1501,9 @@ PRINT_CONFIG_CLASS_DEFINE( // Orca: ((ConfigOptionFloatOrPercent, infill_combination_max_layer_height)) ((ConfigOptionInt, fill_multiline)) - ((ConfigOptionEnum, tpms_adaptive)) - ((ConfigOptionPercent, tpms_interior_density)) - ((ConfigOptionEnum, tpms_adaptive_gradient)) + ((ConfigOptionEnum, adaptive_infill_mode)) + ((ConfigOptionPercent, adaptive_infill_interior_density)) + ((ConfigOptionEnum, adaptive_infill_gradient)) ((ConfigOptionBool, gyroid_optimized)) // Ironing options ((ConfigOptionEnum, ironing_type)) @@ -2130,6 +2130,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionPercents, filament_shrinkage_compensation_z)) ((ConfigOptionBool, gcode_label_objects)) ((ConfigOptionBool, exclude_object)) + ((ConfigOptionFloat, exclude_object_tolerance)) ((ConfigOptionFloats, grab_length)) ((ConfigOptionBool, gcode_comments)) ((ConfigOptionInt, slow_down_layers)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 7e9b21ccdf..150e987bcb 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -33,7 +33,7 @@ #include "Fill/FillAdaptive.hpp" #include "Fill/Fill.hpp" #include "Fill/FillLightning.hpp" -#include "Fill/FillTpmsAdaptive.hpp" +#include "Fill/AdaptiveInfillField.hpp" #include "format.hpp" #include "AABBTreeIndirect.hpp" #include "AABBTreeLines.hpp" @@ -1252,19 +1252,19 @@ FillLightning::GeneratorPtr PrintObject::prepare_lightning_infill_data() return has_lightning_infill ? FillLightning::build_generator(std::as_const(*this), [this]() -> void { this->throw_if_canceled(); }) : FillLightning::GeneratorPtr(); } -TpmsRadialFields PrintObject::prepare_tpms_radial_fields() const +AdaptiveInfillFields PrintObject::prepare_adaptive_infill_fields() const { - TpmsRadialFields fields; - std::array modes{}; + AdaptiveInfillFields fields; + std::array modes{}; for (size_t region_id = 0; region_id < this->num_printing_regions(); ++region_id) if (const PrintRegionConfig &config = this->printing_region(region_id).config(); - config.sparse_infill_density > 0 && config.sparse_infill_density < 100 && is_tpms_adaptive_pattern(config.sparse_infill_pattern)) - modes[size_t(config.tpms_adaptive.value)] = true; - modes[size_t(TpmsAdaptiveMode::Disabled)] = false; + config.sparse_infill_density > 0 && config.sparse_infill_density < 100 && is_adaptive_infill_pattern(config.sparse_infill_pattern)) + modes[size_t(config.adaptive_infill_mode.value)] = true; + modes[size_t(AdaptiveInfillMode::Disabled)] = false; if (std::find(modes.begin(), modes.end(), true) == modes.end() || m_layers.empty()) return fields; - std::vector slices; + std::vector slices; slices.reserve(m_layers.size()); BoundingBox bbox; for (const Layer *layer : m_layers) { @@ -1277,7 +1277,7 @@ TpmsRadialFields PrintObject::prepare_tpms_radial_fields() const if (!modes[mode]) continue; // Without a field, the infill falls back to the regular pattern. - auto field = std::make_unique(slices, bbox, TpmsAdaptiveMode(mode), [this]() { m_print->throw_if_canceled(); }); + auto field = std::make_unique(slices, bbox, AdaptiveInfillMode(mode), [this]() { m_print->throw_if_canceled(); }); if (!field->empty()) fields[mode] = std::move(field); } @@ -1685,9 +1685,9 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "infill_overhang_angle") { steps.emplace_back(posInfill); } else if (opt_key == "sparse_infill_pattern" - || opt_key == "tpms_adaptive" - || opt_key == "tpms_interior_density" - || opt_key == "tpms_adaptive_gradient" + || opt_key == "adaptive_infill_mode" + || opt_key == "adaptive_infill_interior_density" + || opt_key == "adaptive_infill_gradient" // Orca: Body centering now also determines bridge anchors during preparation. // Invalidating preparation also invalidates infill, including top/bottom surfaces. || opt_key == "center_of_surface_pattern" @@ -3195,7 +3195,7 @@ void PrintObject::bridge_over_infill() } this->m_adaptive_fill_octrees = this->prepare_adaptive_infill_data(surfaces_w_layer); - this->m_tpms_radial_fields = this->prepare_tpms_radial_fields(); + this->m_adaptive_infill_fields = this->prepare_adaptive_infill_fields(); std::vector layers_to_generate_infill; for (const auto &pair : surfaces_by_layer) { diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index bbea1a6900..31e02f35bc 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -26,8 +26,10 @@ #include "Print.hpp" #include "GCode/OrderingStrategies.hpp" +#include #include #include +#include #include "MultiMaterialSegmentation.hpp" namespace Slic3r { @@ -96,6 +98,46 @@ std::vector> chain_segments_closest_point(std::vector> chain_segments_exact(const std::vector &end_points, const std::vector &could_reverse, const Vec2d *start) +{ + const size_t n = could_reverse.size(); + assert(n >= 1 && n <= 12 && end_points.size() == 2 * n); + // State (mask * n + j) * 2 + o: the segments of mask visited, the last one j, flipped when o. + const size_t num_states = (size_t(1) << n) * n * 2; + std::vector cost(num_states, std::numeric_limits::max()); + std::vector from(num_states, size_t(-1)); + auto entry = [&end_points](size_t j, size_t o) -> const Vec2d & { return end_points[2 * j + o]; }; + auto exit = [&end_points](size_t j, size_t o) -> const Vec2d & { return end_points[2 * j + 1 - o]; }; + for (size_t j = 0; j < n; ++ j) + for (size_t o = 0; o <= size_t(could_reverse[j] != 0); ++ o) + cost[((size_t(1) << j) * n + j) * 2 + o] = start == nullptr ? 0. : (entry(j, o) - *start).norm(); + for (size_t mask = 1; mask < (size_t(1) << n); ++ mask) + for (size_t s = mask * n * 2; s < (mask + 1) * n * 2; ++ s) + if (cost[s] < std::numeric_limits::max()) + for (size_t k = 0; k < n; ++ k) + if (! (mask >> k & 1)) + for (size_t o = 0; o <= size_t(could_reverse[k] != 0); ++ o) { + const size_t next = (((mask | size_t(1) << k) * n) + k) * 2 + o; + const double c = cost[s] + (entry(k, o) - exit(s / 2 % n, s & 1)).norm(); + if (c < cost[next]) { + cost[next] = c; + from[next] = s; + } + } + const size_t full = (size_t(1) << n) - 1; + size_t best = full * n * 2; + for (size_t s = best; s < num_states; ++ s) + if (cost[s] < cost[best]) + best = s; + std::vector> out(n); + for (size_t s = best, k = n; k -- > 0; s = from[s]) + out[k] = { s / 2 % n, (s & 1) != 0 }; + return out; +} + // Chain perimeters (always closed) and thin fills (closed or open) using a greedy algorithm. // Solving a Traveling Salesman Problem (TSP) with the modification, that the sites are not always points, but points and segments. // Solving using a greedy algorithm, where a shortest edge is added to the solution if it does not produce a bifurcation or a cycle. @@ -104,6 +146,7 @@ std::vector> chain_segments_closest_point(std::vector std::vector> chain_segments_greedy_constrained_reversals_(SegmentEndPointFunc end_point_func, CouldReverseFunc could_reverse_func, size_t num_segments, const PointType *start_near) { @@ -118,6 +161,19 @@ std::vector> chain_segments_greedy_constrained_reversals out.emplace_back(0, could_reverse_func(0) && start_near != nullptr && (end_point_func(0, false) - *start_near).template cast().squaredNorm() < (end_point_func(0, true) - *start_near).template cast().squaredNorm()); } + else if (num_segments <= 4) + { + // Orca: so few segments are cheap to chain exactly. The first one is then not always the one nearest start_near. + std::vector end_points(2 * num_segments); + std::vector could_reverse(num_segments); + for (size_t i = 0; i < num_segments; ++ i) { + end_points[2 * i] = end_point_func(i, true).template cast(); + end_points[2 * i + 1] = end_point_func(i, false).template cast(); + could_reverse[i] = could_reverse_func(i); + } + const Vec2d start = start_near != nullptr ? Vec2d(start_near->template cast()) : Vec2d::Zero(); + out = chain_segments_exact(end_points, could_reverse, start_near != nullptr ? &start : nullptr); + } else { // End points of segments for the KD tree closest point search. @@ -1039,12 +1095,370 @@ std::vector> chain_segments_greedy2(SegmentEndPointFunc return chain_segments_greedy_constrained_reversals2_(end_point_func, could_reverse_func, num_segments, start_near); } +// The K points nearest to a query, nearest first, ties by index, from a uniform grid of about two points per cell. +template +class NearestPoints +{ +public: + static constexpr size_t npos = size_t(-1); + + explicit NearestPoints(const std::vector &points) : m_points(points) + { + BoundingBoxf bbox; + for (const Vec2d &p : points) + bbox.merge(p); + const Vec2d size = bbox.size(); + const double count = double(std::max(points.size(), 1)); + m_cell = std::max(std::sqrt(2. * size.x() * size.y() / count), std::max(size.x(), size.y()) / count); + if (m_cell <= 0.) + m_cell = 1.; + m_origin = bbox.min; + m_cols = int(size.x() / m_cell) + 1; + m_rows = int(size.y() / m_cell) + 1; + m_first.assign(size_t(m_cols) * m_rows + 1, 0); + for (const Vec2d &p : points) + ++ m_first[cell(p) + 1]; + for (size_t c = 1; c < m_first.size(); ++ c) + m_first[c] += m_first[c - 1]; + m_index.resize(points.size()); + std::vector next(m_first.begin(), m_first.end() - 1); + for (size_t i = 0; i < points.size(); ++ i) + m_index[next[cell(points[i])] ++] = i; + } + + // Indices of the nearest points that filter accepts, npos past the last one. + template + std::array query(const Vec2d &q, Filter filter) const + { + std::array, K> best; + size_t found = 0; + const int cx = int(std::clamp(std::floor((q.x() - m_origin.x()) / m_cell), 0., double(m_cols - 1))); + const int cy = int(std::clamp(std::floor((q.y() - m_origin.y()) / m_cell), 0., double(m_rows - 1))); + auto visit = [&](int x, int y) { + if (x < 0 || y < 0 || x >= m_cols || y >= m_rows) + return; + const size_t c = size_t(y) * m_cols + x; + for (size_t k = m_first[c]; k < m_first[c + 1]; ++ k) { + const size_t i = m_index[k]; + if (! filter(i)) + continue; + const std::pair candidate((m_points[i] - q).squaredNorm(), i); + if (found == K && ! (candidate < best[K - 1])) + continue; + auto it = std::upper_bound(best.begin(), best.begin() + found, candidate); + std::move_backward(it, best.begin() + std::min(found, K - 1), best.begin() + std::min(found + 1, K)); + *it = candidate; + found = std::min(found + 1, K); + } + }; + // Points beyond ring r are at least r cells away. + for (int r = 0; r <= std::max(m_cols, m_rows); ++ r) { + if (r == 0) + visit(cx, cy); + for (int d = -r; d <= r && r > 0; ++ d) { + visit(cx + d, cy - r); + visit(cx + d, cy + r); + if (d != -r && d != r) { + visit(cx - r, cy + d); + visit(cx + r, cy + d); + } + } + if (found == K && best[K - 1].first <= sqr(r * m_cell)) + break; + } + std::array out; + out.fill(npos); + for (size_t k = 0; k < found; ++ k) + out[k] = best[k].second; + return out; + } + +private: + size_t cell(const Vec2d &p) const + { + const int x = std::clamp(int((p.x() - m_origin.x()) / m_cell), 0, m_cols - 1); + const int y = std::clamp(int((p.y() - m_origin.y()) / m_cell), 0, m_rows - 1); + return size_t(y) * m_cols + x; + } + + const std::vector &m_points; + Vec2d m_origin; + double m_cell; + int m_cols; + int m_rows; + std::vector m_first; + std::vector m_index; +}; + +// Shortens the travel of a chain with 2-opt moves (reversing a run of segments) and or-opt moves (moving a run of up to +// three segments elsewhere, or a longer one to the front, flipped or not). end_points holds the first and the last point +// of each segment. The chain starts at start_near when given, and its end is free. A move that would flip a segment that +// cannot reverse is skipped. Moves only create links between nearest neighbor end points, and after a move only the +// segments next to a changed link are examined again, until a sweep of all segments finds no move. This keeps the search +// close to linear. +static void improve_chain_by_local_search(std::vector> &chain, const std::vector &end_points, + const std::vector &could_reverse, const Vec2d *start_near) +{ + const size_t n = chain.size(); + if (n < 2) + return; + assert(end_points.size() == 2 * n && could_reverse.size() == n); + + std::vector order(n), pos(n), fixed_before(n + 1, 0); + std::vector flipped(n); + for (size_t k = 0; k < n; ++ k) { + order[k] = chain[k].first; + flipped[order[k]] = chain[k].second; + } + // Updates positions lo..hi after a move, which keeps the number of segments that cannot reverse past hi. + auto refresh = [&](size_t lo, size_t hi) { + for (size_t k = lo; k <= hi; ++ k) { + pos[order[k]] = k; + fixed_before[k + 1] = fixed_before[k] + ! could_reverse[order[k]]; + } + }; + refresh(0, n - 1); + auto entry_idx = [&](size_t k) { return 2 * order[k] + flipped[order[k]]; }; + auto exit_idx = [&](size_t k) { return 2 * order[k] + 1 - flipped[order[k]]; }; + auto entry = [&](size_t k) -> const Vec2d& { return end_points[entry_idx(k)]; }; + auto exit = [&](size_t k) -> const Vec2d& { return end_points[exit_idx(k)]; }; + auto is_exit = [&](size_t e) { return char(e & 1) != flipped[e >> 1]; }; + auto reversible = [&](size_t i, size_t j) { return fixed_before[j + 1] == fixed_before[i]; }; + auto dist = [](const Vec2d *a, const Vec2d *b) { return a == nullptr || b == nullptr ? 0. : (*a - *b).norm(); }; + // Travel end points around position k, null where the chain is open. + auto prev_exit = [&](size_t k) -> const Vec2d* { return k > 0 ? &exit(k - 1) : start_near; }; + auto next_entry = [&](size_t k) -> const Vec2d* { return k + 1 < n ? &entry(k + 1) : nullptr; }; + + // The 32 nearest end points are the candidates, which covers every move on short chains; 8 missed much of the gain. + static constexpr size_t K = 32; + static constexpr size_t npos = NearestPoints::npos; + const NearestPoints nearest(end_points); + std::vector> neighbors(end_points.size()); + for (size_t e = 0; e < end_points.size(); ++ e) + neighbors[e] = nearest.query(end_points[e], [e](size_t idx) { return (idx >> 1) != (e >> 1); }); + std::array start_neighbors; + start_neighbors.fill(npos); + if (start_near != nullptr) + start_neighbors = nearest.query(*start_near, [](size_t) { return true; }); + + // Segments to examine, by id, each queued once. + std::deque queue; + std::vector queued(n, 0); + auto enqueue = [&](size_t k) { + if (k < n && ! queued[order[k]]) { + queued[order[k]] = 1; + queue.push_back(order[k]); + } + }; + + const double min_gain = SCALED_EPSILON; + // Reverses positions i..j if that shortens the chain. + auto try_2opt = [&](size_t i, size_t j) { + if (! reversible(i, j)) + return false; + const Vec2d *a = prev_exit(i), *b = next_entry(j); + if (dist(a, &exit(j)) + dist(&entry(i), b) > dist(a, &entry(i)) + dist(&exit(j), b) - min_gain) + return false; + std::reverse(order.begin() + i, order.begin() + j + 1); + for (size_t k = i; k <= j; ++ k) + flipped[order[k]] ^= 1; + refresh(i, j); + for (size_t k : { i - 1, i, j, j + 1 }) + enqueue(k); + return true; + }; + // Moves positions i..last after position gap (size_t(-1) for the front) if that shortens the chain. + auto try_oropt = [&](size_t i, size_t last, size_t gap) { + if (gap + 1 == i || (gap >= i && gap <= last)) + return false; + const Vec2d *a = gap == size_t(-1) ? start_near : &exit(gap); + const Vec2d *b = gap + 1 < n ? &entry(gap + 1) : nullptr; + const double removal_gain = dist(prev_exit(i), &entry(i)) + dist(&exit(last), next_entry(last)) - dist(prev_exit(i), next_entry(last)); + const double base = dist(a, b); + const double cost_kept = dist(a, &entry(i)) + dist(&exit(last), b) - base; + const double cost_flipped = reversible(i, last) ? dist(a, &exit(last)) + dist(&entry(i), b) - base : std::numeric_limits::max(); + if (std::min(cost_kept, cost_flipped) > removal_gain - min_gain) + return false; + const size_t len = last - i + 1; + // The run lands on first..first+len-1; lo..hi spans every position that changed. + const bool forward = gap > last && gap != size_t(-1); + const size_t first = forward ? gap + 1 - len : gap + 1; + const size_t lo = forward ? i : first; + const size_t hi = forward ? gap : last; + if (forward) + std::rotate(order.begin() + i, order.begin() + last + 1, order.begin() + gap + 1); + else + std::rotate(order.begin() + first, order.begin() + i, order.begin() + last + 1); + if (cost_flipped < cost_kept) { + std::reverse(order.begin() + first, order.begin() + first + len); + for (size_t k = first; k < first + len; ++ k) + flipped[order[k]] ^= 1; + } + refresh(lo, hi); + // The links around the run's new place, and the link closing its old place. + for (size_t k : { first - 1, first, first + len - 1, first + len, forward ? i - 1 : last, forward ? i : last + 1 }) + enqueue(k); + return true; + }; + // The gap before position k of the chain with positions i..last taken out. + auto gap_before = [](size_t k, size_t i, size_t last) { return k == last + 1 ? i - 1 : k - 1; }; + + // Applies the first move found that breaks a link next to position p. + // Candidates are tried nearest first, while closer than the link the move would replace at that end point. + auto closer = [&](const Vec2d &at, size_t q, double limit) { return q != npos && (end_points[q] - at).norm() < limit; }; + auto improve_at = [&](size_t p) { + // 2-opt breaking the link into p, as the first or the last link of the reversed run. + if (const Vec2d *a = prev_exit(p); a != nullptr) { + const double old_link = dist(a, &entry(p)); + for (size_t q : p > 0 ? neighbors[exit_idx(p - 1)] : start_neighbors) { + if (! closer(*a, q, old_link)) + break; + if (is_exit(q) && pos[q >> 1] >= p && try_2opt(p, pos[q >> 1])) + return true; + } + if (p > 0) + for (size_t q : neighbors[entry_idx(p)]) { + if (! closer(entry(p), q, old_link)) + break; + if (! is_exit(q) && pos[q >> 1] < p && try_2opt(pos[q >> 1], p - 1)) + return true; + } + } + // 2-opt breaking the link out of p. + if (p + 1 < n) { + const double old_link = dist(&exit(p), &entry(p + 1)); + for (size_t q : neighbors[exit_idx(p)]) { + if (! closer(exit(p), q, old_link)) + break; + if (is_exit(q) && pos[q >> 1] > p && try_2opt(p + 1, pos[q >> 1])) + return true; + } + for (size_t q : neighbors[entry_idx(p + 1)]) { + if (! closer(entry(p + 1), q, old_link)) + break; + if (! is_exit(q) && pos[q >> 1] <= p && try_2opt(pos[q >> 1], p)) + return true; + } + } + // A run of any length that starts or ends next to the start point moves to the front. + if (p == 0) + for (size_t q : start_neighbors) { + if (q == npos) + break; + const size_t m = pos[q >> 1]; + if (m == 0) + continue; + // Runs m..k enter next to the start, runs k..m leave there and go flipped. + const bool exit_near = is_exit(q); + for (size_t k = exit_near ? 1 : m; k < (exit_near ? m + 1 : n); ++ k) + if (try_oropt(exit_near ? k : m, exit_near ? m : k, size_t(-1))) + return true; + } + // Or-opt of the runs starting at p: next to an exit a run goes after that segment, next to an entry before it. + for (size_t last = p; last < std::min(p + 3, n); ++ last) { + if (try_oropt(p, last, size_t(-1))) + return true; + const double removal_gain = dist(prev_exit(p), &entry(p)) + dist(&exit(last), next_entry(last)) - dist(prev_exit(p), next_entry(last)); + for (size_t e : { entry_idx(p), exit_idx(last) }) + for (size_t q : neighbors[e]) { + if (! closer(end_points[e], q, removal_gain)) + break; + const size_t m = pos[q >> 1]; + if ((m < p || m > last) && try_oropt(p, last, is_exit(q) ? m : gap_before(m, p, last))) + return true; + } + } + return false; + }; + + // A new link can make room for a run that sits elsewhere, hence the sweeps until one finds no move. Every move shortens + // the chain, so the search ends; the cap only bounds its time. + for (size_t k = 0; k < n; ++ k) + enqueue(k); + bool moved_since_sweep = false; + for (size_t moves = 0; moves < 50 * n;) { + if (queue.empty()) { + if (! moved_since_sweep) + break; + moved_since_sweep = false; + for (size_t k = 0; k < n; ++ k) + enqueue(k); + } + const size_t segment = queue.front(); + queue.pop_front(); + queued[segment] = 0; + if (improve_at(pos[segment])) { + ++ moves; + moved_since_sweep = true; + enqueue(pos[segment]); + } + } + + for (size_t k = 0; k < n; ++ k) + chain[k] = { order[k], flipped[order[k]] != 0 }; +} + +// Chain that always goes on to the nearest free end point, from start. +static std::vector> chain_nearest_next(const std::vector &end_points, const std::vector &could_reverse, const Vec2d &start) +{ + const NearestPoints<1> nearest(end_points); + std::vector taken(could_reverse.size(), 0); + std::vector> out; + out.reserve(could_reverse.size()); + for (Vec2d at = start; out.size() < could_reverse.size();) { + const size_t e = nearest.query(at, [&](size_t idx) { return ! taken[idx >> 1] && ((idx & 1) == 0 || could_reverse[idx >> 1]); })[0]; + taken[e >> 1] = 1; + out.emplace_back(e >> 1, (e & 1) != 0); + at = end_points[e ^ 1]; + } + return out; +} + +static double chain_travel(const std::vector> &chain, const std::vector &end_points, const Vec2d &start) +{ + double travel = 0.; + Vec2d at = start; + for (const std::pair &segment : chain) { + travel += (end_points[2 * segment.first + segment.second] - at).norm(); + at = end_points[2 * segment.first + 1 - segment.second]; + } + return travel; +} + template -static std::vector> chain_extrusion_entities_impl(const std::vector &entities, const Point *start_near) +static std::vector> chain_extrusion_entities_impl(const std::vector &entities, const Point *start_near, bool improve = false) { auto segment_end_point = [&entities](size_t idx, bool first_point) -> Point { return first_point ? entities[idx]->first_point() : entities[idx]->last_point(); }; auto could_reverse = [&entities](size_t idx) { const ExtrusionEntity *ee = entities[idx]; return ee->is_loop() || ee->can_reverse(); }; std::vector> out = chain_segments_greedy_constrained_reversals(segment_end_point, could_reverse, entities.size(), start_near); + if (improve && out.size() > 1) { + std::vector end_points; + std::vector reversible; + end_points.reserve(2 * entities.size()); + reversible.reserve(entities.size()); + for (size_t idx = 0; idx < entities.size(); ++ idx) { + end_points.emplace_back(segment_end_point(idx, true).template cast()); + end_points.emplace_back(segment_end_point(idx, false).template cast()); + reversible.emplace_back(could_reverse(idx)); + } + Vec2d start = Vec2d::Zero(); + if (start_near != nullptr) + start = start_near->cast(); + if (entities.size() <= 8) { + // Few paths are chained exactly; the local search below can stop short of the shortest chain. + out = chain_segments_exact(end_points, reversible, start_near != nullptr ? &start : nullptr); + } else { + improve_chain_by_local_search(out, end_points, reversible, start_near != nullptr ? &start : nullptr); + if (start_near != nullptr) { + // The greedy chain can settle into a sweep that local moves cannot undo, which a nearest-next chain may avoid. + std::vector> nearest_next = chain_nearest_next(end_points, reversible, start); + if (chain_travel(nearest_next, end_points, start) < chain_travel(out, end_points, start) - SCALED_EPSILON) { + improve_chain_by_local_search(nearest_next, end_points, reversible, &start); + out = std::move(nearest_next); + } + } + } + } for (std::pair &segment : out) { const ExtrusionEntity *ee = entities[segment.first]; if (ee->is_loop()) @@ -1086,7 +1500,8 @@ void reorder_extrusion_entities(std::vector &entities, const s void chain_and_reorder_extrusion_entities(std::vector &entities, const Point &start_near) { - chain_and_reorder_extrusion_entities(entities, &start_near); + remove_entities_without_endpoints(entities); + reorder_extrusion_entities(entities, chain_extrusion_entities_impl(entities, &start_near, true)); } void chain_and_reorder_extrusion_entities(std::vector &entities, const Point *start_near) @@ -1101,7 +1516,7 @@ void chain_and_reorder_extrusion_entities(std::vector &e remove_entities_without_endpoints(entities); std::vector out; out.reserve(entities.size()); - for (const auto &[idx, reverse] : chain_extrusion_entities_impl(entities, &start_near)) { + for (const auto &[idx, reverse] : chain_extrusion_entities_impl(entities, &start_near, true)) { if (reverse) { ExtrusionEntity *clone = reversed_clones.emplace_back(entities[idx]->clone()).get(); clone->reverse(); @@ -1159,16 +1574,74 @@ std::vector chain_points(const Points &points, const Point *start_near) return out; } +// Moves runs of up to three points of the cycle next to one of the 8 points nearest to an end of the run, reversed or not, +// while that shortens the cycle. path[0] stays first. Returns true if any move was made. +static bool improve_cycle_by_or_opt(std::vector &path, const Points &points) +{ + const size_t pn = path.size(); + if (pn < 5) + return false; + std::vector coords(points.size()); + for (size_t i = 0; i < points.size(); ++ i) + coords[i] = points[i].cast(); + const NearestPoints<8> grid(coords); + std::vector pos(points.size()); + auto refresh = [&]() { for (size_t k = 0; k < pn; ++ k) pos[path[k]] = k; }; + refresh(); + auto dist = [&](size_t a, size_t b) { return (coords[path[a % pn]] - coords[path[b % pn]]).norm(); }; + bool improved = false; + for (bool moved = true; moved;) { + moved = false; + for (size_t len = 1; len <= 3; ++ len) + for (size_t i = 1; i + len <= pn; ++ i) { + // The run path[i..last] goes between path[k] and path[k + 1]. + const size_t last = i + len - 1; + const double removal = dist(i - 1, i) + dist(last, last + 1) - dist(i - 1, last + 1); + bool applied = removal <= SCALED_EPSILON; + for (size_t end : { path[i], path[last] }) + for (size_t q : grid.query(coords[end], [end](size_t idx) { return idx != end; })) + for (size_t k : { q == NearestPoints<8>::npos ? pn : (pos[q] + pn - 1) % pn, q == NearestPoints<8>::npos ? pn : pos[q] }) { + if (applied || k == pn || (k + 1 >= i && k <= last)) + continue; + const double base = dist(k, k + 1); + const double kept = dist(k, i) + dist(last, k + 1) - base; + const double reversed = dist(k, last) + dist(i, k + 1) - base; + if (std::min(kept, reversed) > removal - SCALED_EPSILON) + continue; + std::vector run(path.begin() + i, path.begin() + last + 1); + if (reversed < kept) + std::reverse(run.begin(), run.end()); + path.erase(path.begin() + i, path.begin() + last + 1); + path.insert(path.begin() + (k < i ? k + 1 : k + 1 - len), run.begin(), run.end()); + refresh(); + applied = moved = improved = true; + } + } + } + return improved; +} + std::vector chain_points_with_postprocessing(const Points &points, const Point *start_near) { - std::vector path = chain_points(points, start_near); - // Alternate 2-opt and crossing removal until convergence. - // 2-opt can create new crossings, and crossing removal can create new - // opportunities for 2-opt improvement. Break early if neither improves. - for (int iter = 0; iter < 3; ++iter) { - bool improved = tsp_2opt_improve(path, points); - improved |= tsp_remove_crossings(path, points); - if (!improved) break; + std::vector path; + if (points.size() <= 10) { + // Orca: few points are toured exactly, from the point nearest start_near toward its nearer neighbor. + path = tsp_exact_cycle(points); + if (start_near != nullptr && path.size() > 2) { + auto dist = [&points](size_t a, const Point &b) { return (points[a] - b).cast().squaredNorm(); }; + std::rotate(path.begin(), std::min_element(path.begin(), path.end(), [&](size_t a, size_t b) { return dist(a, *start_near) < dist(b, *start_near); }), path.end()); + if (dist(path.back(), points[path.front()]) < dist(path[1], points[path.front()])) + std::reverse(path.begin() + 1, path.end()); + } + } else { + path = chain_points(points, start_near); + // Alternate 2-opt, or-opt and crossing removal: each can open moves for the others. Break early if none improves. + for (int iter = 0; iter < 3; ++iter) { + bool improved = tsp_2opt_improve(path, points); + improved |= improve_cycle_by_or_opt(path, points); + improved |= tsp_remove_crossings(path, points); + if (!improved) break; + } } if (start_near == nullptr) tsp_rotate_minimize_closing(path, points); diff --git a/src/libslic3r/ShortestPath.hpp b/src/libslic3r/ShortestPath.hpp index 53ec00f9e4..34127fdb9a 100644 --- a/src/libslic3r/ShortestPath.hpp +++ b/src/libslic3r/ShortestPath.hpp @@ -23,9 +23,12 @@ std::vector chain_expolygons(const ExPolygons &input_exploy); std::vector> chain_extrusion_entities(std::vector &entities, const Point *start_near = nullptr); void reorder_extrusion_entities(std::vector &entities, const std::vector> &chain); +// From start_near, the greedy chain is refined by 2-opt and or-opt moves, which shortens the travel at some extra cost. void chain_and_reorder_extrusion_entities(std::vector &entities, const Point &start_near); +// The greedy chain only. void chain_and_reorder_extrusion_entities(std::vector &entities, const Point *start_near = nullptr); -// Each entity the chain reverses is replaced by a reversed clone that reversed_clones owns, so the originals stay unchanged. +// Refined as above. Each entity the chain reverses is replaced by a reversed clone that reversed_clones owns, so the +// originals stay unchanged. void chain_and_reorder_extrusion_entities(std::vector &entities, const Point &start_near, std::vector> &reversed_clones); diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index b6f95e30c0..602464bb86 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -225,7 +225,7 @@ void BackgroundSlicingProcess::process_fff() // BBS: add the logic to process from an existed gcode file if (m_print->finished()) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(" %1%: skip slicing, to process previous gcode file") % __LINE__; - m_fff_print->set_status(80, _utf8(L("Processing G-Code from previous file\u2026"))); + m_fff_print->set_status(80, _utf8(L("Processing G-code from previous file\u2026" /* \u2026 -> ... */))); wxCommandEvent evt(m_event_slicing_completed_id); // Post the Slicing Finished message for the G-code viewer to update. // Passing the timestamp diff --git a/src/slic3r/GUI/ColorPickerDialog.cpp b/src/slic3r/GUI/ColorPickerDialog.cpp index 086eae3a70..b9308c7a8e 100644 --- a/src/slic3r/GUI/ColorPickerDialog.cpp +++ b/src/slic3r/GUI/ColorPickerDialog.cpp @@ -303,10 +303,12 @@ nlohmann::json color_picker_ui_strings() return { {"Color Picker", _u8L("Color Picker")}, {"Basic Colors", _u8L("Basic Colors")}, - {"Orca Palette", _u8L("Orca Palette")},// TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. - {"RAL Classic", _u8L("RAL Classic")}, // TRN: Keep the standard/brand name "RAL" unchanged. + // TRN: Keep the brand name "Orca" unchanged; translate only the palette descriptor. + {"Orca Palette", _u8L("Orca Palette")}, + // TRN: Keep the standard/brand name "RAL" unchanged. + {"RAL Classic", _u8L("RAL Classic")}, {"Gradients", _u8L("Gradients")}, - {"Solid", _u8L("Solid")}, + {"Solid", _u8L_CONTEXT("Solid", "Color picker")}, {"Gradient", _u8L("Gradient")}, {"Gradient start", _u8L("Gradient start")}, {"Gradient end", _u8L("Gradient end")}, @@ -440,7 +442,7 @@ nlohmann::json color_picker_ui_strings() {"Purple", _u8L("Purple")}, {"Rebecca purple", _u8L("Rebecca purple")}, {"Medium violet red", _u8L("Medium violet red")}, - {"PaleV violet red", _u8L("PaleV violet red")}, + {"Pale violet red", _u8L("Pale violet red")}, {"Deep pink", _u8L("Deep pink")}, {"Hot pink", _u8L("Hot pink")}, {"Light pink", _u8L("Light pink")}, @@ -496,7 +498,7 @@ nlohmann::json color_picker_ui_strings() {"Turquoise bay", _u8L("Turquoise bay")}, {"Sky over reef", _u8L("Sky over reef")}, {"Shallow sky", _u8L("Shallow sky")}, - {"Electric bel", _u8L("Electric bel")}, + {"Electric blue", _u8L("Electric blue")}, {"Dolphin", _u8L("Dolphin")}, {"Ocean depths", _u8L("Ocean depths")}, {"Whale", _u8L("Whale")}, @@ -519,7 +521,7 @@ nlohmann::json color_picker_ui_strings() {"Golden yellow", _u8L("Golden yellow")}, {"Honey yellow", _u8L("Honey yellow")}, {"Maize yellow", _u8L("Maize yellow")}, - {"Dalmatian yellow", _u8L("Dalmatian yellow")}, + {"Daffodil yellow", _u8L("Daffodil yellow")}, {"Brown beige", _u8L("Brown beige")}, {"Lemon yellow", _u8L("Lemon yellow")}, {"Oyster white", _u8L("Oyster white")}, @@ -606,7 +608,7 @@ nlohmann::json color_picker_ui_strings() {"Pigeon blue", _u8L("Pigeon blue")}, {"Traffic blue", _u8L("Traffic blue")}, {"Turquoise blue", _u8L("Turquoise blue")}, - {"Capsanthin violet", _u8L("Capsanthin violet")}, + {"Capri blue", _u8L("Capri blue")}, {"Ocean blue", _u8L("Ocean blue")}, {"Water blue", _u8L("Water blue")}, {"Night blue", _u8L("Night blue")}, @@ -644,7 +646,7 @@ nlohmann::json color_picker_ui_strings() {"Luminous green", _u8L("Luminous green")}, {"Squirrel grey", _u8L("Squirrel grey")}, {"Silver grey", _u8L("Silver grey")}, - {"Olivestone", _u8L("Olivestone")}, + {"Olive grey", _u8L("Olive grey")}, {"Moss grey", _u8L("Moss grey")}, {"Signal grey", _u8L("Signal grey")}, {"Mouse grey", _u8L("Mouse grey")}, diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index cd7e44b5d6..a03f63c737 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -843,17 +843,17 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in bool have_multiline_infill_pattern = pattern == ipGyroid || pattern == ipGrid || pattern == ipRectilinear || pattern == ipTpmsD || pattern == ipTpmsFK || pattern == ipCrossHatch || pattern == ipHoneycomb || pattern == ipLateralLattice || pattern == ipLateralHoneycomb || pattern == ipConcentric || pattern == ipCubic || pattern == ipStars || pattern == ipAlignedRectilinear || pattern == ipLightning || pattern == ip3DHoneycomb || pattern == ipAdaptiveCubic || pattern == ipSupportCubic|| pattern == ipTriangles || pattern == ipQuarterCubic|| pattern == ipArchimedeanChords || pattern == ipHilbertCurve || pattern == ipOctagramSpiral; - // The sparse infill density is the surface density of the adaptive TPMS infill; at 100% the infill is solid. - bool have_tpms_infill = have_infill && config->option("sparse_infill_density")->value < 100 && - is_tpms_adaptive_pattern(pattern); - toggle_line("tpms_adaptive", have_tpms_infill); - bool have_tpms_adaptive = have_tpms_infill && config->opt_enum("tpms_adaptive") != TpmsAdaptiveMode::Disabled; - toggle_line("tpms_interior_density", have_tpms_adaptive); - toggle_line("tpms_adaptive_gradient", have_tpms_adaptive); + // The sparse infill density is the surface density of the adaptive infill; at 100% the infill is solid. + bool have_adaptive_infill_pattern = have_infill && config->option("sparse_infill_density")->value < 100 && + is_adaptive_infill_pattern(pattern); + toggle_line("adaptive_infill_mode", have_adaptive_infill_pattern); + bool have_adaptive_infill = have_adaptive_infill_pattern && config->opt_enum("adaptive_infill_mode") != AdaptiveInfillMode::Disabled; + toggle_line("adaptive_infill_interior_density", have_adaptive_infill); + toggle_line("adaptive_infill_gradient", have_adaptive_infill); // gyroid_optimized only applies when the sparse infill pattern is gyroid without adaptive density; // hide the whole line otherwise. - toggle_line("gyroid_optimized", have_infill && pattern == ipGyroid && !have_tpms_adaptive); + toggle_line("gyroid_optimized", have_infill && pattern == ipGyroid && !have_adaptive_infill); // If there is infill, enable/disable fill_multiline according to whether the pattern supports multiline infill. if (have_infill) { @@ -1245,6 +1245,8 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in if(gcf_is_klipper) toggle_field("accel_to_decel_factor", config->opt_bool("accel_to_decel_enable")); + toggle_line("exclude_object_tolerance", gcf_is_klipper && config->opt_bool("exclude_object")); + bool have_make_overhang_printable = config->opt_bool("make_overhang_printable"); toggle_line("make_overhang_printable_angle", have_make_overhang_printable); toggle_line("make_overhang_printable_hole_size", have_make_overhang_printable); diff --git a/src/slic3r/GUI/DailyTips.cpp b/src/slic3r/GUI/DailyTips.cpp index 8bace894e1..dc97117efc 100644 --- a/src/slic3r/GUI/DailyTips.cpp +++ b/src/slic3r/GUI/DailyTips.cpp @@ -161,7 +161,7 @@ void DailyTipsDataRenderer::render_img(const ImVec2& start_pos, const ImVec2& si bool has_cjk(const std::string &text) { - for (size_t i = 0; i < text.size() - 2; ++i) { + for (size_t i = 0; i + 2 < text.size(); ++i) { unsigned char c1 = text[i]; unsigned char c2 = text[i + 1]; unsigned char c3 = text[i + 2]; diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index c838b898f6..5d467d44c7 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -149,9 +149,9 @@ std::map> SettingsFactory::PART_CATE {"sparse_infill_density", "", 1}, {"fill_multiline", "", 1}, {"sparse_infill_pattern", "", 1}, - {"tpms_adaptive", "", 1}, - {"tpms_interior_density", "", 1}, - {"tpms_adaptive_gradient", "", 1}, + {"adaptive_infill_mode", "", 1}, + {"adaptive_infill_interior_density", "", 1}, + {"adaptive_infill_gradient", "", 1}, {"sparse_infill_smooth_factor", "", 1}, {"lateral_lattice_angle_1", "", 1}, {"lateral_lattice_angle_2", "", 1}, @@ -2158,6 +2158,7 @@ wxMenu* MenuFactory::multi_selection_menu() menu->AppendSeparator(); append_menu_items_convert_unit(menu); + append_menu_item_reload_from_disk(menu); append_menu_item_replace_all_with_stl(menu); //BBS append_menu_item_change_filament(menu); @@ -2173,6 +2174,7 @@ wxMenu* MenuFactory::multi_selection_menu() //append_menu_item_simplify(menu); append_menu_item_delete(menu); append_menu_items_convert_unit(menu); + append_menu_item_reload_from_disk(menu); append_menu_item_replace_all_with_stl(menu); append_menu_item_change_filament(menu); wxMenu* split_menu = new wxMenu(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index db125ae1d5..ae39eade25 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -1089,8 +1089,8 @@ EmbossStyles GLGizmoEmboss::create_default_styles() styles.push_back(WxFontUtils::create_emboss_style(wx_font, _u8L("First font"))); } else { // On current OS is not installed any correct TTF font - // use font packed with Slic3r - std::string font_path = Slic3r::resources_dir() + "/fonts/NotoSans-Regular.ttf"; + // use font packed with OrcaSlicer + std::string font_path = Slic3r::resources_dir() + "/fonts/HarmonyOS_Sans_SC_Regular.ttf"; styles.push_back(EmbossStyle{_u8L("Default font"), font_path, EmbossStyle::Type::file_path}); } return styles; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index c4d76a0315..1dd9fdc18d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -1350,7 +1350,7 @@ void GLGizmoSVG::draw_window() assert(m_volume_id.valid()); if (m_volume == nullptr || m_volume_id.invalid()) { - ImGui::Text("%s", _u8L("Not valid state please report reproduction steps on github").c_str()); + ImGui::Text("%s", _u8L("Not valid state please report reproduction steps on GitHub").c_str()); return; } @@ -1362,13 +1362,13 @@ void GLGizmoSVG::draw_window() assert(m_volume->emboss_shape->svg_file.has_value()); if (!m_volume->emboss_shape->svg_file.has_value()){ - ImGui::Text("%s", _u8L("Missing svg file in embossed shape").c_str()); + ImGui::Text("%s", _u8L("Missing SVG file in embossed shape").c_str()); return; } assert(m_volume->emboss_shape->svg_file->file_data != nullptr); if (m_volume->emboss_shape->svg_file->file_data == nullptr){ - ImGui::Text("%s", _u8L("Missing data of svg file").c_str()); + ImGui::Text("%s", _u8L("Missing data of SVG file").c_str()); return; } diff --git a/src/slic3r/GUI/HMS.cpp b/src/slic3r/GUI/HMS.cpp index 2234d1afb4..6bd847f32f 100644 --- a/src/slic3r/GUI/HMS.cpp +++ b/src/slic3r/GUI/HMS.cpp @@ -33,7 +33,7 @@ static const char* HMS_LOCAL_IMG_PATH = "hms/local_image"; // the local HMS info // Orca: dev-id-type set trimmed to the devices Orca ships local HMS images for -static std::unordered_set package_dev_id_types {"094", "239", "093", "22E"}; +static std::unordered_set package_dev_id_types {"094", "239", "093", "22E", "20P", "26A", "31B"}; // Orca: HMS should be disabled when stealth mode is on or networking is not installed static bool should_disable_hms() diff --git a/src/slic3r/GUI/Jobs/PrintJob.cpp b/src/slic3r/GUI/Jobs/PrintJob.cpp index b6b420969f..c903e3b139 100644 --- a/src/slic3r/GUI/Jobs/PrintJob.cpp +++ b/src/slic3r/GUI/Jobs/PrintJob.cpp @@ -716,8 +716,6 @@ void PrintJob::process(Ctl &ctl) } else { // wait for printer mqtt ready the same job id - wxGetApp().plater()->record_slice_preset("print"); - BOOST_LOG_TRIVIAL(error) << "print_job: send ok."; wxCommandEvent* evt = new wxCommandEvent(m_print_job_completed_id); if (!m_completed_evt_data.empty()) diff --git a/src/slic3r/GUI/NetworkTestDialog.cpp b/src/slic3r/GUI/NetworkTestDialog.cpp index 54c0f11cf0..964004b67c 100644 --- a/src/slic3r/GUI/NetworkTestDialog.cpp +++ b/src/slic3r/GUI/NetworkTestDialog.cpp @@ -295,7 +295,7 @@ void NetworkTestDialog::start_test_url(TestJob job, wxString name, wxString url) } }) .on_ip_resolve([this,name,job](std::string ip) { - wxString ip_report = wxString::Format(_L("test %s ip resolved = %s"), name, ip); + wxString ip_report = wxString::Format(_L("test %s IP resolved = %s"), name, ip); update_status(job, ip_report); }) .on_error([this,name,job](std::string body, std::string error, unsigned int status) { diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index d395fe104c..3b224725f6 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -228,6 +228,7 @@ #include "Jobs/PlaterWorker.hpp" #include "Jobs/BoostThreadWorker.hpp" #include "BackgroundSlicingProcess.hpp" +#include "PostProcessor.hpp" #include "SelectMachine.hpp" #include "SendMultiMachinePage.hpp" #include "SendToPrinter.hpp" @@ -17865,6 +17866,9 @@ void Plater::calib_input_shaping_freq(const Calib_Params& params) filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false}); print_config->set_key_value("layer_height", new ConfigOptionFloat(0.2)); set_config_values(print_config, "enable_overhang_speed", false); + // A 100% factor sends Klipper MINIMUM_CRUISE_RATIO=0 with every acceleration change, for the whole test. + print_config->set_key_value("accel_to_decel_enable", new ConfigOptionBool(true)); + print_config->set_key_value("accel_to_decel_factor", new ConfigOptionPercent(100)); print_config->set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional)); print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0)); @@ -17929,6 +17933,9 @@ void Plater::calib_input_shaping_damp(const Calib_Params& params) filament_config->set_key_value("slow_down_min_speed", new ConfigOptionFloats { 0.0 }); filament_config->set_key_value("slow_down_for_layer_cooling", new ConfigOptionBools{false}); set_config_values(print_config, "enable_overhang_speed", false); + // A 100% factor sends Klipper MINIMUM_CRUISE_RATIO=0 with every acceleration change, for the whole test. + print_config->set_key_value("accel_to_decel_enable", new ConfigOptionBool(true)); + print_config->set_key_value("accel_to_decel_factor", new ConfigOptionPercent(100)); print_config->set_key_value("timelapse_type", new ConfigOptionEnum(tlTraditional)); print_config->set_key_value("wall_loops", new ConfigOptionInt(1)); print_config->set_key_value("top_shell_layers", new ConfigOptionInt(0)); @@ -18670,7 +18677,7 @@ void ProjectDropDialog::on_dpi_changed(const wxRect& suggested_rect) //BBS: remove GCodeViewer as seperate APP logic bool Plater::load_files(const wxArrayString& filenames) { - const std::regex pattern_drop(".*[.](stp|step|stl|oltp|obj|amf|3mf|svg|zip|drc)", std::regex::icase); + const std::regex pattern_drop(".*[.](stp|step|stl|oltp|obj|amf|3mf|svg|zip|drc|glb|gltf|fbx)", std::regex::icase); const std::regex pattern_gcode_drop(".*[.](gcode|g)", std::regex::icase); std::vector normal_paths; @@ -19572,7 +19579,11 @@ void Plater::export_gcode_3mf(bool export_all) SaveStrategy strategy = SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithGcode | SaveStrategy::SkipModel; // BBS: silence if (wxGetApp().app_config->get_bool("export_statistics")) strategy = strategy | SaveStrategy::WithStatistics; - export_3mf(output_path, strategy, plate_idx); + if (export_3mf(output_path, strategy, plate_idx) < 0) { + // No file was written (e.g. a post-processing script failed), don't report a successful export. + p->exporting_status = ExportingStatus::NOT_EXPORTING; + return; + } RemovableDriveManager& removable_drive_manager = *wxGetApp().removable_drive_manager(); @@ -20429,6 +20440,45 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy p->partplate_list.store_to_3mf_structure(plate_data_list, (strategy & SaveStrategy::WithGcode || strategy & SaveStrategy::WithSliceInfo), export_plate_idx, strategy & SaveStrategy::WithStatistics); + // Orca: non-BBL G-code isn't post-processed in place, so run the scripts on a copy before packing it. + std::vector pp_tmp_files; + ScopeGuard remove_pp_tmp_files([&pp_tmp_files]() { + for (const std::string& f : pp_tmp_files) { + boost::system::error_code ec; + boost::filesystem::remove(f, ec); + } + }); + + // Backups (SkipStatic) don't pack G-code, so don't run user scripts for them. + if ((strategy & SaveStrategy::WithGcode) && !(strategy & SaveStrategy::SkipStatic) && + p->printer_technology == ptFFF && !wxGetApp().preset_bundle->is_bbl_vendor()) { + try { + for (PlateData* pd : plate_data_list) { + if (pd == nullptr || pd->gcode_file.empty()) + continue; + PartPlate* plate = p->partplate_list.get_plate(pd->plate_index); + if (plate == nullptr) + continue; + PrintBase* print = nullptr; + plate->get_print(&print, nullptr, nullptr); + Print* fff_print = dynamic_cast(print); + if (fff_print == nullptr) + continue; + + std::string src_path = pd->gcode_file; // in/out: becomes the post-processed copy if a script ran + std::string output_name = path_u8; // scripts see the real target; a rename is ignored for 3mf + if (run_post_process_scripts(src_path, true, "File", output_name, fff_print->full_print_config())) { + pp_tmp_files.push_back(src_path); + pd->gcode_file = src_path; + } + } + } catch (const std::exception& ex) { + release_PlateData_list(plate_data_list); + show_error(this, ex.what(), false); + return -1; + } + } + // BBS: backup PresetBundle& preset_bundle = *wxGetApp().preset_bundle; std::vector project_presets = preset_bundle.get_current_project_embedded_presets(); @@ -20746,76 +20796,6 @@ void Plater::reslice() p->preview->reload_print(); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": finished, started slicing for plate %1%") % p->partplate_list.get_curr_plate_index(); - - record_slice_preset("slicing"); -} - -void Plater::record_slice_preset(std::string action) -{ - // record slice preset - try - { - json j; - auto printer_preset = wxGetApp().preset_bundle->printers.get_edited_preset_with_vendor_profile().preset; - if (printer_preset.is_system) { - j["printer_preset_name"] = printer_preset.name; - } - else { - j["printer_preset_name"] = printer_preset.config.opt_string("inherits"); - } - const t_config_enum_values* keys_map = print_config_def.get("curr_bed_type")->enum_keys_map; - if (keys_map) { - for (auto item : *keys_map) { - if (item.second == wxGetApp().preset_bundle->project_config.opt_enum("curr_bed_type")) { - j["curr_bed_type"] = item.first; - break; - } - } - } - auto filament_presets = wxGetApp().preset_bundle->filament_presets; - for (int i = 0; i < filament_presets.size(); ++i) { - auto filament_preset = wxGetApp().preset_bundle->filaments.find_preset(filament_presets[i]); - if (filament_preset->is_system) { - j["filament_preset_" + std::to_string(i)] = filament_preset->name; - } - else { - j["filament_preset_" + std::to_string(i)] = filament_preset->config.opt_string("inherits"); - } - } - - Preset& print_preset = wxGetApp().preset_bundle->prints.get_edited_preset(); - if (print_preset.is_system) { - j["process_preset"] = print_preset.name; - } - else { - j["process_preset"] = print_preset.config.opt_string("inherits"); - } - j["support_type"] = ConfigOptionEnum::get_enum_names().at(print_preset.config.opt_enum("support_type")); - j["sparse_infill_pattern"] = ConfigOptionEnum::get_enum_names().at(print_preset.config.opt_enum("sparse_infill_pattern")); - j["sparse_infill_density"] = print_preset.config.opt("sparse_infill_density")->value; - - j["brim_type"] = ConfigOptionEnum::get_enum_names().at(print_preset.config.opt_enum("brim_type")); - j["user_mode"] = wxGetApp().get_mode_str(); - - if (p->background_process.fff_print()) { - const DynamicPrintConfig& full_config = p->background_process.fff_print()->full_print_config(); - json values = json::array(); - if (full_config.has("different_settings_to_system")) { - std::vector different_values = full_config.option("different_settings_to_system")->values; - for (auto& item : different_values) { - values.push_back(item); - } - } - j["different_settings_to_system"] = values; - } - - j["record_event"] = action; - NetworkAgent* agent = wxGetApp().getAgent(); - } - catch (...) - { - return; - } } //BBS: add project slicing related logic diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 564addb0c7..a879226b42 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -597,7 +597,6 @@ public: bool has_toolpaths_to_export() const; void export_toolpaths_to_obj() const; void reslice(); - void record_slice_preset(std::string action); void reslice_SLA_supports(const ModelObject &object, bool postpone_error_messages = false); void reslice_SLA_hollowing(const ModelObject &object, bool postpone_error_messages = false); void reslice_SLA_until_step(SLAPrintObjectStep step, const ModelObject &object, bool postpone_error_messages = false); diff --git a/src/slic3r/GUI/PostProcessor.cpp b/src/slic3r/GUI/PostProcessor.cpp index 4aa498ad74..c918650aa7 100644 --- a/src/slic3r/GUI/PostProcessor.cpp +++ b/src/slic3r/GUI/PostProcessor.cpp @@ -395,7 +395,7 @@ bool run_post_process_scripts( auto gcode_file = boost::filesystem::path(path); if (!boost::filesystem::exists(gcode_file)) - throw Slic3r::RuntimeError(_u8L("Post-processor can't find exported gcode file")); + throw Slic3r::RuntimeError(_u8L("Post-processor can't find exported G-code file")); // Store print configuration into environment variables. config.setenv_(); diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 3f5bf126a2..26441baf37 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -5738,8 +5738,9 @@ void SelectMachineDialog::reset_and_sync_ams_list() } // Orca: collapse the per-nozzle material items into the single panel when the printer has one -// extruder or a filament switch (both feed a single logical mapping surface); otherwise keep the -// left/right split. Early-returns unless an item is actually in the wrong panel. +// extruder or a filament switch (both feed a single logical mapping surface), or when the plate is +// sliced for one nozzle (it has no left/right filament map); otherwise keep the left/right split. +// Early-returns unless an item is actually in the wrong panel. void SelectMachineDialog::update_material_item_pos(MachineObject* obj_) { if (!obj_) { @@ -5748,7 +5749,10 @@ void SelectMachineDialog::update_material_item_pos(MachineObject* obj_) const bool is_single_head = obj_->GetExtderSystem()->GetTotalExtderCount() < 2; const bool has_switcher = obj_->GetFilaSwitch()->IsInstalled(); - const bool use_single_panel = is_single_head || has_switcher; + // reset_and_sync_ams_list() fills m_filaments_map only for a multi-nozzle plate + const auto& full_config = wxGetApp().preset_bundle->full_config(); + const bool single_nozzle_plate = full_config.option("nozzle_diameter")->values.size() < 2; + const bool use_single_panel = is_single_head || has_switcher || single_nozzle_plate; bool to_change_pos = false; for (const auto& iter : m_materialList) { diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 9d67e7c0fb..00fd72e57f 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -2968,9 +2968,9 @@ void TabPrint::build() optgroup->append_single_option_line("sparse_infill_density", "strength_settings_infill#sparse-infill-density"); optgroup->append_single_option_line("fill_multiline", "strength_settings_infill#fill-multiline"); optgroup->append_single_option_line("sparse_infill_pattern", "strength_settings_infill#sparse-infill-pattern"); - optgroup->append_single_option_line("tpms_adaptive", "strength_settings_patterns#adaptive-density"); - optgroup->append_single_option_line("tpms_interior_density", "strength_settings_patterns#interior-density"); - optgroup->append_single_option_line("tpms_adaptive_gradient", "strength_settings_patterns#adaptive-gradient"); + optgroup->append_single_option_line("adaptive_infill_mode", "strength_settings_patterns#adaptive-density"); + optgroup->append_single_option_line("adaptive_infill_interior_density", "strength_settings_patterns#interior-density"); + optgroup->append_single_option_line("adaptive_infill_gradient", "strength_settings_patterns#adaptive-gradient"); optgroup->append_single_option_line("gyroid_optimized", "strength_settings_patterns#gyroid-optimized"); optgroup->append_single_option_line("sparse_infill_smooth_factor", "strength_settings_infill#sparse-infill-smooth-factor"); optgroup->append_single_option_line("infill_direction", "strength_settings_infill#direction"); @@ -3269,6 +3269,7 @@ void TabPrint::build() optgroup->append_single_option_line("gcode_comments", "others_settings_g_code_output#verbose-g-code"); optgroup->append_single_option_line("gcode_label_objects", "others_settings_g_code_output#label-objects"); optgroup->append_single_option_line("exclude_object", "others_settings_g_code_output#exclude-objects"); + optgroup->append_single_option_line("exclude_object_tolerance", "others_settings_g_code_output#outline-tolerance"); option = optgroup->get_option("filename_format"); // option.opt.full_width = true; option.opt.is_code = true; @@ -5278,7 +5279,7 @@ void TabPrinter::build_fff() option.opt.width = Field::def_width_wider(); option.opt.tooltip = L("Select the network agent implementation for printer communication. " "Available agents are registered at startup."); - optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option, "printer_basic_information_advanced#printer-agent"); } } diff --git a/src/slic3r/Utils/BBLPrinterAgent.cpp b/src/slic3r/Utils/BBLPrinterAgent.cpp index 7fde77a075..30fd075fc4 100644 --- a/src/slic3r/Utils/BBLPrinterAgent.cpp +++ b/src/slic3r/Utils/BBLPrinterAgent.cpp @@ -7,6 +7,8 @@ #include "slic3r/GUI/GUI_App.hpp" #include "slic3r/GUI/DeviceCore/DevManager.h" +#include +#include #include #include #include @@ -16,6 +18,7 @@ #include #include #include +#include #include #include using json = nlohmann::json; @@ -64,12 +67,16 @@ const BambuFilamentIdMap& bambu_filament_id_map() return map; } -// Rewrites every string under "tray_info_idx", "filament_id" or "filamentId", at any depth, in place. +// Keys whose string value is a filament id. "cate" and "fila_id" are the H2C nozzle rack's: the +// auto nozzle mapping request and the rack status in the push message. +constexpr std::array filament_id_keys{"tray_info_idx", "filament_id", "filamentId", "cate", "fila_id"}; + +// Rewrites every string under a filament id key, at any depth, in place. void rewrite_filament_ids(json& j, const std::unordered_map& map) { if (j.is_object()) { for (auto& [key, value] : j.items()) { - if (value.is_string() && (key == "tray_info_idx" || key == "filament_id" || key == "filamentId")) { + if (value.is_string() && std::find(filament_id_keys.begin(), filament_id_keys.end(), key) != filament_id_keys.end()) { auto it = map.find(value.get_ref()); if (it != map.end()) value = it->second; @@ -84,8 +91,8 @@ void rewrite_filament_ids(json& j, const std::unordered_map& map) { - if (map.empty() || (text.find("tray_info_idx") == std::string::npos && text.find("filament_id") == std::string::npos && - text.find("filamentId") == std::string::npos)) + if (map.empty() || std::none_of(filament_id_keys.begin(), filament_id_keys.end(), + [&text](std::string_view key) { return text.find(key) != std::string::npos; })) return text; // nothing to map, skip the parse (moved, not copied) try { json j = json::parse(text); diff --git a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp index 8494eb5cfd..025f0ba918 100644 --- a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp +++ b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp @@ -1415,16 +1415,8 @@ void MoonrakerPrinterAgent::announce_printhost_device() } } - // Try to fetch actual device name from Moonraker - // Priority: 1) Moonraker hostname, 2) Preset model name, 3) Generic fallback - std::string dev_name; - MoonrakerDeviceInfo info; - std::string fetch_error; - if (fetch_device_info(device_info.base_url, device_info.api_key, info, fetch_error) && !info.dev_name.empty()) { - dev_name = info.dev_name; - } else { - dev_name = device_info.model_name.empty() ? "Moonraker Printer" : device_info.model_name; - } + // Never asks the printer, since discovery runs on the GUI thread and an unreachable printer would freeze it + const std::string dev_name = device_info.model_name.empty() ? "Moonraker Printer" : device_info.model_name; const std::string model_id = device_info.model_id; diff --git a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp index f5f7e30d1d..f759d15a2b 100644 --- a/src/slic3r/Utils/OrcaCloudServiceAgent.cpp +++ b/src/slic3r/Utils/OrcaCloudServiceAgent.cpp @@ -1917,13 +1917,20 @@ RefreshResult OrcaCloudServiceAgent::refresh_from_storage(const std::string& rea bool OrcaCloudServiceAgent::refresh_if_expiring(std::chrono::seconds skew, const std::string& reason) { - bool needs_refresh = false; - { + const auto needs_refresh = [&] { std::lock_guard lock(session_mutex); - needs_refresh = should_refresh_locked(skew); - } + return should_refresh_locked(skew); + }; + if (!needs_refresh()) + return true; - if (!needs_refresh) + // A refresh may already be running on another thread, e.g. the one start() launches. Wait for + // it and check again instead of spending the refresh token it is rotating. Bounded: the + // refresh POST times out after 30 s. + const auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(60); + while (refresh_running.load() && std::chrono::steady_clock::now() < deadline) + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + if (!needs_refresh()) return true; // First attempt. refresh_from_storage blocks on the cross-process lock and reads the @@ -1935,6 +1942,8 @@ bool OrcaCloudServiceAgent::refresh_if_expiring(std::chrono::seconds skew, const // One retry, only for a transient network failure of the refresh POST (lost response, // timeout, 429/5xx -> Transient). The retry re-acquires the lock and re-reads the store. std::this_thread::sleep_for(std::chrono::milliseconds(750)); + if (!needs_refresh()) + return true; return refresh_from_storage(reason + "_retry", false) == RefreshResult::Success; } diff --git a/src/slic3r/plugin/CloudPluginService.cpp b/src/slic3r/plugin/CloudPluginService.cpp index 22e0b57f81..221ec7787c 100644 --- a/src/slic3r/plugin/CloudPluginService.cpp +++ b/src/slic3r/plugin/CloudPluginService.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -49,16 +50,22 @@ bool CloudPluginService::fetch_manifests_into_descriptors(std::vectorensure_token_fresh("fetch_plugin_manifests"); + std::vector mine_descriptors; + auto mine = std::async(std::launch::async, [agent = m_orca_agent, &mine_descriptors] { + return agent->fetch_mine_manifests_into_descriptors(mine_descriptors); + }); + int ret = m_orca_agent->fetch_subscribed_manifests_into_descriptors(descriptors, not_found, unauthorized); + const int mine_ret = mine.get(); if (ret != 0) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": Failed to get subscribed plugins."; return false; } - std::vector mine_descriptors; - - ret = m_orca_agent->fetch_mine_manifests_into_descriptors(mine_descriptors); + ret = mine_ret; if (ret != 0) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": Failed to get owned plugins."; diff --git a/src/slic3r/plugin/PluginAuditManager.cpp b/src/slic3r/plugin/PluginAuditManager.cpp index e525f8358a..41a03e514f 100644 --- a/src/slic3r/plugin/PluginAuditManager.cpp +++ b/src/slic3r/plugin/PluginAuditManager.cpp @@ -8,13 +8,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -134,6 +134,20 @@ static AuditEventCategory event_category(const std::string& event_name) return it == audit_event_categories.end() ? AuditEventCategory::None : it->second; } +// Events the 3.12 stdlib raises with sys.audit() inside the function that performs the whole +// operation, so the raising frame bounds everything the operation does. Every other mapped event +// is a primitive raised from C, whose current frame is whatever Python code called it -- possibly +// a library loop over many targets -- so it never marks an operation. glob.glob and glob.glob/2 +// are raised in iglob(), which returns its lazy generator before any directory is listed. +static const std::unordered_set operation_root_events{ + "urllib.Request", "http.client.connect", "os.walk", "os.fwalk", + "glob.glob", "glob.glob/2", "pathlib.Path.glob", "pathlib.Path.rglob", + "subprocess.Popen", "pty.spawn", "tempfile.mkstemp", "tempfile.mkdtemp", + "shutil.copyfile", "shutil.copymode", "shutil.copystat", "shutil.copytree", + "shutil.chown", "shutil.move", "shutil.rmtree", "shutil.make_archive", + "shutil.unpack_archive", +}; + // True for the categories whose targets are filesystem paths, as opposed to a network // address or a process command line -- the deny-path and allowed-root checks only make sense // against a path. @@ -158,14 +172,6 @@ static bool is_network_category(AuditEventCategory category) return category == AuditEventCategory::Http || category == AuditEventCategory::Socket; } -// The only network events whose target can be a resolved address instead of the host the plugin -// asked for. They may fall back to a network-approved call site; every other network event must -// name a host or URL the hook can match directly. -static bool is_resolved_address_event(const std::string& event_name) -{ - return event_name == "socket.connect" || event_name == "socket.sendto"; -} - // --------------------------------------------------------------------------- // Network permission identity // --------------------------------------------------------------------------- @@ -311,7 +317,9 @@ bool PluginAuditManager::network_permission_matches(const std::vector= 2 && host.front() == '[' && host.back() == ']') - host = host.substr(1, host.size() - 2); - - // Drop an IPv6 zone identifier before parsing; it is not part of the address literal. - const size_t zone = host.find('%'); - if (zone != std::string::npos) - host.erase(zone); - - boost::system::error_code ec; - boost::asio::ip::make_address(host, ec); - return !ec; + switch (category) { + case AuditEventCategory::FsRead: return "FsRead"; + case AuditEventCategory::FsReadWrite: return "FsReadWrite"; + case AuditEventCategory::FsCreate: return "FsCreate"; + case AuditEventCategory::FsDelete: return "FsDelete"; + case AuditEventCategory::Http: return "Http"; + case AuditEventCategory::Socket: return "Socket"; + case AuditEventCategory::ProcessCreate: return "ProcessCreate"; + case AuditEventCategory::ProcessReplace: return "ProcessReplace"; + case AuditEventCategory::Threading: return "Threading"; + case AuditEventCategory::None: break; + } + return "None"; } // --------------------------------------------------------------------------- @@ -418,26 +425,50 @@ bool is_inside_allowed_root(const boost::filesystem::path& candidate, const boos thread_local std::string PluginAuditManager::m_current_plugin_key = ""; thread_local std::string PluginAuditManager::m_current_capability_name = ""; thread_local std::vector PluginAuditManager::m_scoped_allowed_roots; +thread_local std::vector PluginAuditManager::m_root_frames; +thread_local int PluginAuditManager::m_releasing_frames = 0; thread_local bool PluginAuditManager::m_audit_denial_pending = false; thread_local bool PluginAuditManager::m_has_last_violation = false; thread_local AuditViolation PluginAuditManager::m_last_violation; ScopedPluginAuditContext::ScopedPluginAuditContext(const std::string& plugin_key, const std::string& capability_name) - : m_previous_id(PluginAuditManager::instance().current_plugin()) + : m_plugin_key(plugin_key) + , m_capability(capability_name) + , m_previous_id(PluginAuditManager::instance().current_plugin()) , m_previous_capability(PluginAuditManager::instance().current_capability()) , m_previous_scoped_roots(PluginAuditManager::m_scoped_allowed_roots) + , m_previous_root_frames(std::move(PluginAuditManager::m_root_frames)) { PluginAuditManager::instance().set_current_plugin(plugin_key); PluginAuditManager::instance().set_current_capability(capability_name); PluginAuditManager::m_scoped_allowed_roots.clear(); + PluginAuditManager::m_root_frames.clear(); } ScopedPluginAuditContext::~ScopedPluginAuditContext() { - PluginAuditManager::instance().set_current_plugin(m_previous_id); - PluginAuditManager::instance().set_current_capability(m_previous_capability); + PluginAuditManager& mgr = PluginAuditManager::instance(); + + // Let this scope's root frames go while it is still the current context, and as its own + // plugin: the trampoline's denial path clears the key before the scope ends, and a finalizer + // must never be judged as the outer plugin, or bypass the audit when there is none. A + // finalizer may record a new root frame, so repeat until none is held. + if (!PluginAuditManager::m_root_frames.empty()) { + assert(PyGILState_Check()); + mgr.set_current_plugin(m_plugin_key); + mgr.set_current_capability(m_capability); + while (!PluginAuditManager::m_root_frames.empty()) { + std::vector frames = std::move(PluginAuditManager::m_root_frames); + PluginAuditManager::m_root_frames.clear(); + mgr.release_frames(frames); + } + } + + mgr.set_current_plugin(m_previous_id); + mgr.set_current_capability(m_previous_capability); PluginAuditManager::m_scoped_allowed_roots = std::move(m_previous_scoped_roots); + PluginAuditManager::m_root_frames = std::move(m_previous_root_frames); } // --------------------------------------------------------------------------- @@ -831,60 +862,6 @@ bool PluginAuditManager::last_violation(AuditViolation& violation) const return true; } -bool PluginAuditManager::has_approved_ancestor(const std::string& plugin_key, - const std::vector& call_site_ids) const -{ - return has_call_site(m_approved_call_sites, plugin_key, call_site_ids); -} - -void PluginAuditManager::record_approved_call_sites(const std::string& plugin_key, - const std::vector& call_site_ids) -{ - record_call_sites(m_approved_call_sites, plugin_key, call_site_ids); -} - -bool PluginAuditManager::has_approved_network_ancestor(const std::string& plugin_key, - const std::vector& call_site_ids) const -{ - return has_call_site(m_approved_network_call_sites, plugin_key, call_site_ids); -} - -void PluginAuditManager::record_approved_network_call_sites(const std::string& plugin_key, - const std::vector& call_site_ids) -{ - record_call_sites(m_approved_network_call_sites, plugin_key, call_site_ids); -} - -bool PluginAuditManager::has_call_site(const CallSiteRegistry& registry, - const std::string& plugin_key, - const std::vector& call_site_ids) const -{ - if (plugin_key.empty() || call_site_ids.empty()) - return false; - - std::lock_guard lock(m_mutex); - auto it = registry.find(plugin_key); - if (it == registry.end()) - return false; - - for (const auto& id : call_site_ids) - if (it->second.count(id)) - return true; - return false; -} - -void PluginAuditManager::record_call_sites(CallSiteRegistry& registry, - const std::string& plugin_key, - const std::vector& call_site_ids) -{ - if (plugin_key.empty() || call_site_ids.empty()) - return; - - std::lock_guard lock(m_mutex); - auto& approved = registry[plugin_key]; - approved.insert(call_site_ids.begin(), call_site_ids.end()); -} - // --------------------------------------------------------------------------- // The C-level audit hook // --------------------------------------------------------------------------- @@ -964,61 +941,88 @@ std::string python_str(PyObject* object) return result; } -// Network audit events expose different shapes for the same thing: a URL, a bare host, or an -// address tuple such as ("host", 443). Reduce the argument to the host it names, leaving the -// scheme and port to be judged by the permission matcher. None / an empty tuple has no target. -std::string python_network_host(PyObject* object) +// The interpreter's stdlib folders, and the site-packages folders inside them that hold +// third-party code, both resolved. Set by install_hook(); like the verdict cache below, only +// touched while the GIL is held. +static std::vector s_stdlib_dirs; +static std::vector s_site_package_dirs; +static std::unordered_map s_stdlib_file_verdicts; // co_filename -> is stdlib + +void collect_stdlib_dirs() { - if (!object || object == Py_None) - return {}; + s_stdlib_dirs.clear(); + s_site_package_dirs.clear(); + s_stdlib_file_verdicts.clear(); - if (PyTuple_Check(object)) { - if (PyTuple_GET_SIZE(object) == 0) - return {}; - return python_network_host(PyTuple_GET_ITEM(object, 0)); + PyObject* sysconfig = PyImport_ImportModule("sysconfig"); + PyObject* paths = sysconfig ? PyObject_CallMethod(sysconfig, "get_paths", nullptr) : nullptr; + if (paths && PyDict_Check(paths)) { + const auto collect = [paths](const char* key, std::vector& out) { + const std::string dir = python_unicode(PyDict_GetItemString(paths, key)); // borrowed + if (dir.empty()) + return; + boost::system::error_code ec; + const boost::filesystem::path resolved = boost::filesystem::weakly_canonical(dir, ec); + out.push_back(ec ? boost::filesystem::path(dir) : resolved); + }; + collect("stdlib", s_stdlib_dirs); + collect("platstdlib", s_stdlib_dirs); + collect("purelib", s_site_package_dirs); + collect("platlib", s_site_package_dirs); + } + Py_XDECREF(paths); + Py_XDECREF(sysconfig); + if (PyErr_Occurred()) { + PyErr_Clear(); + BOOST_LOG_TRIVIAL(error) << "[AUDIT] Failed to read the stdlib folders from sysconfig"; } - - std::string text; - if (python_text(object, text)) - return text; - - return python_str(object); } -std::vector call_site_identities(const std::string& plugin_root) +bool is_stdlib_frame(PyObject* frame) { - std::vector ids; - if (plugin_root.empty()) - return ids; + PyCodeObject* code = PyFrame_GetCode(reinterpret_cast(frame)); // new reference + const std::string filename = python_unicode(code->co_filename); + Py_DECREF(code); + return PluginAuditManager::is_stdlib_file(filename); +} +// The frames on this thread's Python stack, innermost first. The pointers stay valid while the +// caller runs, because a running activation keeps its frame object alive. +std::vector stack_frames() +{ + std::vector frames; PyFrameObject* frame = PyEval_GetFrame(); // borrowed reference Py_XINCREF(frame); // normalize to an owned reference for the loop below - while (frame) { - PyCodeObject* code = PyFrame_GetCode(frame); // new reference - const std::string filename = python_unicode(reinterpret_cast(code->co_filename)); - const bool is_plugin_frame = !filename.empty() && boost::algorithm::starts_with(filename, plugin_root); - - std::string id; - if (!is_plugin_frame && !filename.empty()) { - const std::string funcname = python_unicode(reinterpret_cast(code->co_name)); - id = filename + ":" + funcname + ":" + std::to_string(code->co_firstlineno); - } - Py_DECREF(code); - + frames.push_back(reinterpret_cast(frame)); PyFrameObject* back = PyFrame_GetBack(frame); // new reference, or nullptr at the top of the stack Py_DECREF(frame); frame = back; - - if (is_plugin_frame) - break; - if (!id.empty()) - ids.push_back(std::move(id)); } + return frames; +} - Py_XDECREF(frame); // only holds a reference here if the loop exited via break +// Moves the held root frames whose operation has returned from `held` to `dropped`. A suspended +// generator's frame (os.walk between two items) is off the stack, but its operation resumes, so +// it stays held until the scope ends. +void take_returned_frames(std::vector& held, std::vector& dropped) +{ + if (held.empty()) + return; - return ids; + const std::vector stack = stack_frames(); + const auto running = [&stack](PyObject* frame) { + if (std::find(stack.begin(), stack.end(), frame) != stack.end()) + return true; + // NULL once the generator has finished or been deleted: its frame then owns its own data. + PyObject* generator = PyFrame_GetGenerator(reinterpret_cast(frame)); // new reference + const bool suspended = generator != nullptr; + Py_XDECREF(generator); + return suspended; + }; + const auto returned = std::stable_partition(held.begin(), held.end(), running); + dropped.insert(dropped.end(), returned, held.end()); + held.erase(returned, held.end()); } static const std::unordered_set two_path_fs_events{ @@ -1039,12 +1043,15 @@ static const std::unordered_map> audit_targ {"socket.getnameinfo", {0}}, {"socket.getservbyname", {0}}, {"socket.getservbyport", {0}}, + {"socket.sendto", {1}}, + {"socket.sendmsg", {1}}, {"os.system", {0}}, {"subprocess.Popen", {1, 0}}, {"os.posix_spawn", {1, 0}}, {"os.spawn", {2, 1}}, {"os.startfile", {0}}, + {"os.startfile/2", {0}}, {"pty.spawn", {0}}, {"_winapi.CreateProcess", {1, 0}}, {"_posixsubprocess.fork_exec", {0}}, @@ -1088,10 +1095,12 @@ std::vector audit_targets(const std::string& event_name, AuditEvent const auto it = audit_target_arg_indices.find(event_name); if (it != audit_target_arg_indices.end()) { - const bool network_event = is_network_category(category); for (const Py_ssize_t index : it->second) { - std::string value = network_event ? python_network_host(tuple_item(args, index)) - : python_str(tuple_item(args, index)); + // None is an argument left out (sendmsg without an address), not a target named "None". + PyObject* const item = tuple_item(args, index); + if (item == Py_None) + continue; + std::string value = python_str(item); if (!value.empty()) { targets.push_back(std::move(value)); break; @@ -1102,8 +1111,14 @@ std::vector audit_targets(const std::string& event_name, AuditEvent return targets; } -std::vector* permission_list_for(AuditEventCategory category, PluginPermissions& permissions) +// The saved list that grants an event: its category's target list, or the event-grant list for +// an event with no target. Kept apart, so that no grant doubles as a target of the same name (an +// os.fork grant is not an os.exec of a command named "os.fork"). +std::vector* permission_list_for(AuditEventCategory category, bool by_event, PluginPermissions& permissions) { + if (by_event) + return &permissions.events; + switch (category) { case AuditEventCategory::FsRead: return &permissions.fs_read; case AuditEventCategory::FsReadWrite: return &permissions.fs_readwrite; @@ -1116,6 +1131,13 @@ std::vector* permission_list_for(AuditEventCategory category, Plugi } } +// An event with no target is granted by its effective category and name, e.g. "FsRead:open" +// for a read of a file descriptor, which does not grant a write of one ("FsReadWrite:open"). +std::string event_grant_key(AuditEventCategory category, const std::string& event_name) +{ + return std::string(category_name(category)) + ":" + event_name; +} + bool has_permission(const std::vector& granted, const std::string& target) { return std::find(granted.begin(), granted.end(), target) != granted.end(); @@ -1231,22 +1253,25 @@ bool prompt_for_targets(AuditEventCategory category, const std::string& plugin_n // Records a grant in the plugin's sidecar so it is not asked again. Reads the install state // freshly because the async prompt outlives the caller's stack copy of it. -void persist_grant(const std::string& plugin_key, AuditEventCategory category, const std::vector& targets) +void persist_grant(const std::string& plugin_key, AuditEventCategory category, bool by_event, const std::vector& keys) { PluginInstallState state; if (!PluginManager::instance().get_install_state(plugin_key, state)) return; - std::vector* permission_list = permission_list_for(category, state.permissions); + std::vector* permission_list = permission_list_for(category, by_event, state.permissions); if (!permission_list) return; - for (const auto& target : targets) - persist_permission(plugin_key, state, *permission_list, target); + for (const auto& key : keys) + persist_permission(plugin_key, state, *permission_list, key); } -// Requests permission for an audited event, returning true when it is already granted or the user -// approves an inline prompt. +static PluginAuditManager::PermissionPrompt s_permission_prompt_for_testing; + +// Asks the user to grant an audited event, returning true when they approve an inline prompt. +// `keys` are what a Yes saves: the unresolved targets, or the event-grant key when the event has +// no target (by_event), which the prompt does not show as a target. // // An audited event can fire on a thread the UI thread may itself be blocked waiting on: the // SlicingPipeline hook runs on the slicing worker thread (see PluginHooks.cpp), and @@ -1258,85 +1283,208 @@ void persist_grant(const std::string& plugin_key, AuditEventCategory category, c // prompt); the grant is persisted once the user accepts, so a later attempt succeeds without // re-prompting. bool request_permission(AuditEventCategory category, const std::string& plugin_key, const std::string& plugin_name, - const std::string& event_name, const std::vector& unresolved) + const std::string& event_name, bool by_event, const std::vector& keys) { + const std::vector shown = by_event ? std::vector{} : keys; + + if (s_permission_prompt_for_testing) + return s_permission_prompt_for_testing(event_name, shown); + if (wxTheApp == nullptr || GUI::wxGetApp().is_closing()) return false; if (wxIsMainThread()) - return prompt_for_targets(category, plugin_name, event_name, unresolved); + return prompt_for_targets(category, plugin_name, event_name, shown); - GUI::wxGetApp().CallAfter([category, plugin_key, plugin_name, event_name, unresolved]() { + GUI::wxGetApp().CallAfter([category, plugin_key, plugin_name, event_name, by_event, keys, shown]() { if (wxTheApp == nullptr || GUI::wxGetApp().is_closing()) return; - if (prompt_for_targets(category, plugin_name, event_name, unresolved)) - persist_grant(plugin_key, category, unresolved); + if (prompt_for_targets(category, plugin_name, event_name, shown)) + persist_grant(plugin_key, category, by_event, keys); }); return false; } +// Decides an event that no allowed root or running operation covers: a saved grant allows it, +// otherwise the user is asked and a Yes is saved. int decide_audited_event(PluginAuditManager& mgr, PluginInstallState& state, const std::string& plugin_key, const std::string& plugin_name, const std::string& event_name, AuditEventCategory category, - const std::vector& targets, - std::vector* permission_list, - const std::vector& call_site_ids) + const std::vector& targets) { - std::vector unresolved = targets; - if (is_network_category(category)) { - if (targets.empty()) { - // socket.__new__ and http.client.send carry no host. Any network grant already lets - // the plugin open a connection, and every host-bearing event still matches its own - // grant, so the targetless events are covered by an existing grant instead of - // prompting every run. Deliberately do not record a call site here: a targetless - // approval must not become an ancestor that later network events could use to skip - // their own host check. - if (has_any_network_permission(state.permissions)) - return 0; - } else { - unresolved.clear(); - for (const auto& target : targets) - if (!has_network_permission(state.permissions, target)) - unresolved.push_back(target); - if (unresolved.empty()) { - // Remember the stdlib frames for this approved host. The network ancestor cache - // is only consulted for a resolved-IP socket.connect/sendto, so this cannot - // suppress a later hostname or URL event. - mgr.record_approved_network_call_sites(plugin_key, call_site_ids); - return 0; - } - } - } else if (permission_list) { + const bool by_event = targets.empty(); + const std::vector keys = by_event ? std::vector{event_grant_key(category, event_name)} : targets; + std::vector* permission_list = permission_list_for(category, by_event, state.permissions); + + std::vector unresolved = keys; + if (permission_list || is_network_category(category)) { unresolved.clear(); - for (const auto& target : targets) - if (!has_permission(*permission_list, target)) - unresolved.push_back(target); - if (!targets.empty() && unresolved.empty()) + for (const auto& key : keys) + if (!(permission_list && has_permission(*permission_list, key)) && + !(is_network_category(category) && + (by_event ? has_any_network_permission(state.permissions) + : has_network_permission(state.permissions, key)))) + unresolved.push_back(key); + if (unresolved.empty()) return 0; } - if (!request_permission(category, plugin_key, plugin_name, event_name, unresolved)) + // Letting a root frame go runs finalizers inside a scope destructor or another event's hook, + // where no dialog may open: what they do must already be granted. + if (mgr.releasing_frames()) + return report_denied(mgr, event_name, {false, "audit permission required"}); + + if (!request_permission(category, plugin_key, plugin_name, event_name, by_event, unresolved)) return report_denied(mgr, event_name, {false, "audit permission required"}); if (permission_list) - for (const auto& target : unresolved) - persist_permission(plugin_key, state, *permission_list, target); - - // A target-bearing network approval may cover the resolved address of the same connection. - // A targetless approval does not: it carries no host, so it must not create an ancestor that - // a later hostname/URL check could be skipped by (and the network cache is IP-only anyway). - if (is_network_category(category) && !targets.empty()) - mgr.record_approved_network_call_sites(plugin_key, call_site_ids); - - mgr.record_approved_call_sites(plugin_key, call_site_ids); + for (const auto& key : unresolved) + persist_permission(plugin_key, state, *permission_list, key); return 0; } +// Judges an audited event raised while a plugin context is active. +int audit_plugin_event(PluginAuditManager& mgr, const std::string& event_name, AuditEventCategory event_type, PyObject* args) +{ + const bool fs_category = is_fs_category(event_type); + const std::vector targets = audit_targets(event_name, event_type, args); + + // A denied path (secrets, certificates, config files -- see is_denied_path) is an + // unconditional block: checked before the running-operation check below, so no granted + // operation can launder access to one, and before the allowed-root shortcut further down, + // so an allowed root (e.g. the read-only resources folder) cannot make a denied path + // underneath it reachable. + if (fs_category) { + for (const auto& target : targets) { + if (mgr.is_denied_path(boost::filesystem::path(target))) + return report_denied(mgr, event_name, {false, "denied path"}, target); + } + } + + // A nested event of an operation already granted, e.g. socket.connect inside an approved + // urlopen(), is not asked again. urllib.Request is always judged on its own URL, so a + // redirect or a nested urlopen() inside a running request is not covered by it. + if (event_name != "urllib.Request" && mgr.covered_by_root_frame()) + return 0; + + // A filesystem target that resolves entirely inside a pre-determined allowed root -- the + // plugin system's own data_dir() tree (which holds each plugin's storage folder and the + // installed/system profile cache), the read-only bundled resources folder, or a per-call + // scoped root such as the current G-code folder -- is part of the plugin system's normal + // workflow and does not need a prompt. + if (fs_category && !targets.empty()) { + const bool is_write = event_type != AuditEventCategory::FsRead; + const bool all_inside_allowed_root = + std::all_of(targets.begin(), targets.end(), [&](const std::string& target) { + return mgr.check_path_access(boost::filesystem::path(target), is_write).allowed; + }); + if (all_inside_allowed_root) + return 0; + } + + PluginInstallState state; + const bool have_install_state = PluginManager::instance().get_install_state(mgr.current_plugin(), state); + if (!have_install_state) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << " Failed to get install state for " << mgr.current_plugin(); + } + + const std::string plugin_name = state.plugin_name.empty() ? mgr.current_plugin() : state.plugin_name; + + const int result = decide_audited_event(mgr, state, mgr.current_plugin(), plugin_name, event_name, event_type, targets); + + // A granted operation covers its nested events while it runs. A targetless grant names no + // operation, so it covers nothing else. + if (result == 0 && !targets.empty() && operation_root_events.count(event_name)) + mgr.record_root_frame(); + return result; +} + } // namespace PluginAuditDetail +void PluginAuditManager::record_root_frame() +{ + PyObject* frame = reinterpret_cast(PyEval_GetFrame()); // borrowed reference + if (!frame || !PluginAuditDetail::is_stdlib_frame(frame)) + return; + if (std::find(m_root_frames.begin(), m_root_frames.end(), frame) != m_root_frames.end()) + return; // glob.glob and glob.glob/2 share a frame + Py_INCREF(frame); + m_root_frames.push_back(frame); +} + +bool PluginAuditManager::covered_by_root_frame() const +{ + if (m_root_frames.empty()) + return false; + + // Only stdlib frames may sit between the event and the operation: plugin or library code + // the operation calls back into (an os.walk onerror, a urllib handler) acts on its own. + for (PyObject* frame : PluginAuditDetail::stack_frames()) { + if (std::find(m_root_frames.begin(), m_root_frames.end(), frame) != m_root_frames.end()) + return true; + if (!PluginAuditDetail::is_stdlib_frame(frame)) + return false; + } + return false; +} + +bool PluginAuditManager::releasing_frames() const { return m_releasing_frames > 0; } + +bool PluginAuditManager::is_stdlib_file(const std::string& filename) +{ + // Frozen stdlib modules (os, posixpath, codecs, ...) carry a pseudo filename. + if (boost::algorithm::starts_with(filename, "& dirs) { + return std::any_of(dirs.begin(), dirs.end(), + [&file](const boost::filesystem::path& dir) { return is_inside_allowed_root(file, dir); }); + }; + it->second = inside_any(PluginAuditDetail::s_stdlib_dirs) && !inside_any(PluginAuditDetail::s_site_package_dirs); + } + return it->second; +} + +void PluginAuditManager::release_frames(std::vector& frames) +{ + if (frames.empty()) + return; + + // A finalizer's own denial must neither replace the PermissionError of the event being + // decided nor leave a stale denial behind for the next call. + PyObject* const error = PyErr_GetRaisedException(); + const bool denial_pending = m_audit_denial_pending; + const bool has_violation = m_has_last_violation; + const AuditViolation violation = m_last_violation; + + std::vector released; + released.swap(frames); + ++m_releasing_frames; + for (PyObject* frame : released) + Py_DECREF(frame); + --m_releasing_frames; + + m_audit_denial_pending = denial_pending; + m_has_last_violation = has_violation; + m_last_violation = violation; + PyErr_SetRaisedException(error); +} + +void PluginAuditManager::set_permission_prompt_for_testing(PermissionPrompt prompt) +{ + PluginAuditDetail::s_permission_prompt_for_testing = std::move(prompt); +} + int PluginAuditManager::audit_hook(const char* event, PyObject* args, void* user_data) { auto* mgr = static_cast(user_data); @@ -1364,78 +1512,20 @@ int PluginAuditManager::audit_hook(const char* event, PyObject* args, void* user if (event_type == AuditEventCategory::None) return 0; - const bool fs_category = is_fs_category(event_type); - const std::vector targets = PluginAuditDetail::audit_targets(event_name, event_type, args); - - // A denied path (secrets, certificates, config files -- see is_denied_path) is an - // unconditional block: checked before the ancestor-cascade check below, so a cascade - // approval recorded for an unrelated action can never launder access to one, and before - // the allowed-root shortcut further down, so an allowed root (e.g. the read-only resources - // folder) cannot make a denied path underneath it reachable. - if (fs_category) { - for (const auto& target : targets) { - if (mgr->is_denied_path(boost::filesystem::path(target))) - return PluginAuditDetail::report_denied(*mgr, event_name, {false, "denied path"}, target); - } - } - - PluginDescriptor plugin_descriptor; - PluginManager::instance().try_get_plugin_descriptor(mgr->current_plugin(), plugin_descriptor); - - // Some plugins call other audited events, e.g. urllib.request will call socket.connect. - // Collect the stdlib frames now so an approved network host can cover the resolved address - // of the same connection without covering another host. - const std::vector call_site_ids = - PluginAuditDetail::call_site_identities(plugin_descriptor.plugin_root); - - // A general call-site approval may cover nested events for the same logical action. Network - // events use a separate rule: a hostname/URL target must match its own grant even when a - // parent event was approved, and targetless events are handled by the any-grant rule. Only a - // resolved-address connect/sendto (target is an IP literal) may use an approval recorded for - // an earlier network host event, because its own target carries no hostname to match. - if (is_network_category(event_type)) { - const bool all_resolved_addresses = - !targets.empty() && std::all_of(targets.begin(), targets.end(), [](const std::string& target) { - return PluginAuditManager::is_ip_address_target(target); - }); - if (is_resolved_address_event(event_name) && all_resolved_addresses && - mgr->has_approved_network_ancestor(mgr->current_plugin(), call_site_ids)) - return 0; - } else if (mgr->has_approved_ancestor(mgr->current_plugin(), call_site_ids)) { - return 0; - } - - // A filesystem target that resolves entirely inside a pre-determined allowed root -- the - // plugin system's own data_dir() tree (which holds each plugin's storage folder and the - // installed/system profile cache), the read-only bundled resources folder, or a per-call - // scoped root such as the current G-code folder -- is part of the plugin system's normal - // workflow and does not need a prompt. - if (fs_category && !targets.empty()) { - const bool is_write = event_type != AuditEventCategory::FsRead; - const bool all_inside_allowed_root = - std::all_of(targets.begin(), targets.end(), [&](const std::string& target) { - return mgr->check_path_access(boost::filesystem::path(target), is_write).allowed; - }); - if (all_inside_allowed_root) - return 0; - } - - PluginInstallState state; - const bool have_install_state = PluginManager::instance().get_install_state(mgr->current_plugin(), state); - if (!have_install_state) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << " Failed to get install state for " << mgr->current_plugin(); - } - - const std::string plugin_name = state.plugin_name.empty() ? mgr->current_plugin() : state.plugin_name; - - std::vector* permission_list = PluginAuditDetail::permission_list_for(event_type, state.permissions); - - return PluginAuditDetail::decide_audited_event(*mgr, state, mgr->current_plugin(), plugin_name, event_name, - event_type, targets, permission_list, call_site_ids); + // Root frames whose operation has returned are let go once this event is decided, so that a + // finalizer they run re-enters a hook whose held frames are already consistent. + std::vector returned_frames; + PluginAuditDetail::take_returned_frames(m_root_frames, returned_frames); + const int result = PluginAuditDetail::audit_plugin_event(*mgr, event_name, event_type, args); + mgr->release_frames(returned_frames); + return result; } void PluginAuditManager::install_hook() { + // Tells the stdlib's own frames apart, for the operation-root frames (see record_root_frame). + PluginAuditDetail::collect_stdlib_dirs(); + // data_dir() is the primary globally-allowed root during plugin execution: read+write. It // covers the plugin system's own workflow needs -- each plugin's storage folder // (data_dir()/orca_plugins) and the installed/system profile cache (data_dir()/system) -- diff --git a/src/slic3r/plugin/PluginAuditManager.hpp b/src/slic3r/plugin/PluginAuditManager.hpp index bd5ca801ea..80a24254af 100644 --- a/src/slic3r/plugin/PluginAuditManager.hpp +++ b/src/slic3r/plugin/PluginAuditManager.hpp @@ -4,10 +4,9 @@ // Via pybind11 so this file requests the same python3xx.lib as everything else. #include #include +#include #include #include -#include -#include #include #include @@ -155,42 +154,38 @@ public: // True when a granted scheme://host entry covers `target`. `target` is a URL (urllib.Request), // a bare host (http.client.connect, socket.getaddrinfo) or an address as exposed by the audit // event (a hostname, a host:port pair, or a legacy persisted tuple such as "('host', 443)"). - // URL targets must match both scheme and host. A bare host carries no scheme, so it matches - // the host part of any grant; it never matches a different host. + // URL targets must match both scheme and host. Canonical scheme://host grants cover all paths; + // older full-URL grants remain exact. A bare host carries no scheme, so it matches the host + // part of any grant; it never matches a different host. static bool network_permission_matches(const std::vector& granted, const std::string& target); - // True when `target` is a bare IPv4/IPv6 literal (optionally bracketed). A network event - // carrying an IP literal has no hostname the audit hook can match, so it is the only kind of - // network event allowed to use an approved network call-site ancestor. - static bool is_ip_address_target(const std::string& target); - void report_violation(const AuditViolation& violation); bool audit_denial_pending() const; void clear_audit_denial(); void clear_last_violation(); bool last_violation(AuditViolation& violation) const; - // --- call-site cascade cache --- - // A single plugin action often fires several nested CPython audit events as it passes - // through stdlib layers (urllib.request calling http.client calling socket, for example). - // Once the user approves one event, every stdlib frame still on the stack for that call - // is recorded here by (filename, function, first line) identity. A later event whose own - // ancestor chain still contains one of those frames is the same logical action seen from - // a deeper layer, so it is auto-approved instead of prompting again. - // - // Network events do not use this general cache: see the network call-site cache below. - bool has_approved_ancestor(const std::string& plugin_key, const std::vector& call_site_ids) const; - void record_approved_call_sites(const std::string& plugin_key, const std::vector& call_site_ids); + // --- operation-root frames --- + // One stdlib operation fires several nested audit events as it passes through lower layers: + // urlopen() raises urllib.Request, then http.client and socket events. When an operation's + // own root event is granted (by a saved grant or the user), the stdlib frame that raised it + // is held, and a later event whose stack reaches that frame through stdlib frames only is + // part of the same operation, so it is allowed without a prompt of its own. Plugin or + // library code the operation calls back into is judged on its own. A frame is let go once it + // returns, a suspended generator's (os.walk) when the audit scope ends. Letting a frame go may + // run finalizers of objects its locals held; they are judged as the plugin and never prompt. + void record_root_frame(); + bool covered_by_root_frame() const; + bool releasing_frames() const; - // --- network call-site cache --- - // Separate from the general cascade above so a network approval can only suppress a later - // network event with no hostname to check: a resolved address (socket.connect/sendto with an - // IP literal). Hostname and URL events are never auto-approved by an ancestor; they must - // match their own grant. Targetless events are handled by the "any network grant" rule and - // never record an entry here. - bool has_approved_network_ancestor(const std::string& plugin_key, const std::vector& call_site_ids) const; - void record_approved_network_call_sites(const std::string& plugin_key, const std::vector& call_site_ids); + // True when code from `filename` (a code object's co_filename) is the interpreter's own + // stdlib: the only code a root frame's coverage passes through. Valid after install_hook(). + static bool is_stdlib_file(const std::string& filename); + + // Answers permission prompts in place of the dialog, for tests. Production never sets it. + using PermissionPrompt = std::function& targets)>; + static void set_permission_prompt_for_testing(PermissionPrompt prompt); bool verbose_events = true; @@ -201,35 +196,33 @@ private: static int audit_hook(const char* event, PyObject* args, void* user_data); + // Drops the references in `frames`, keeping the caller's error and denial state intact. + void release_frames(std::vector& frames); + static thread_local std::string m_current_plugin_key; static thread_local std::string m_current_capability_name; static thread_local std::vector m_scoped_allowed_roots; + static thread_local std::vector m_root_frames; // strong references + static thread_local int m_releasing_frames; static thread_local bool m_audit_denial_pending; static thread_local bool m_has_last_violation; static thread_local AuditViolation m_last_violation; - // mutable: the deny and ancestor queries are const but must lock. + // mutable: is_denied_filename() is a const query that must lock. mutable std::mutex m_mutex; - using CallSiteRegistry = std::unordered_map>; - - // Shared lookup/insert mechanics for the two registries below. The caller selects the - // registry, so the general and network approvals remain independent. - bool has_call_site(const CallSiteRegistry& registry, const std::string& plugin_key, - const std::vector& call_site_ids) const; - void record_call_sites(CallSiteRegistry& registry, const std::string& plugin_key, - const std::vector& call_site_ids); - std::vector m_global_allowed_roots; std::vector m_denied_filenames; std::vector m_denied_path_keywords; - CallSiteRegistry m_approved_call_sites; - CallSiteRegistry m_approved_network_call_sites; }; // RAII guard that sets the current plugin key and capability name, restoring the previous // pair on scope exit. `capability_name` may be empty for calls that are not scoped to a // single capability. +// +// Each scope owns the root frames recorded inside it and lets them go, as its own plugin, before +// restoring the outer context. That needs the GIL whenever a frame is still held, so construct +// the scope after the GIL guard, to be destroyed before it. class ScopedPluginAuditContext { public: @@ -243,9 +236,12 @@ public: ScopedPluginAuditContext& operator=(const ScopedPluginAuditContext&) = delete; private: + std::string m_plugin_key; + std::string m_capability; std::string m_previous_id; std::string m_previous_capability; std::vector m_previous_scoped_roots; + std::vector m_previous_root_frames; }; } // namespace Slic3r diff --git a/src/slic3r/plugin/PluginFsUtils.cpp b/src/slic3r/plugin/PluginFsUtils.cpp index ec3be1d871..2b4a38928a 100644 --- a/src/slic3r/plugin/PluginFsUtils.cpp +++ b/src/slic3r/plugin/PluginFsUtils.cpp @@ -808,6 +808,7 @@ bool read_install_state(const boost::filesystem::path& plugin_dir, PluginInstall read_string_list("network_socket", parsed.permissions.network_socket); read_string_list("process", parsed.permissions.process); read_string_list("threading", parsed.permissions.threading); + read_string_list("events", parsed.permissions.events); } if (state.contains("enabled") && state["enabled"].is_boolean()) @@ -875,6 +876,7 @@ bool write_install_state(const boost::filesystem::path& plugin_dir, const Plugin {"network_socket", state.permissions.network_socket}, {"process", state.permissions.process}, {"threading", state.permissions.threading}, + {"events", state.permissions.events}, }; nlohmann::json capabilities = nlohmann::json::array(); diff --git a/src/slic3r/plugin/PluginFsUtils.hpp b/src/slic3r/plugin/PluginFsUtils.hpp index 91a7820fd9..64c57f9867 100644 --- a/src/slic3r/plugin/PluginFsUtils.hpp +++ b/src/slic3r/plugin/PluginFsUtils.hpp @@ -104,6 +104,8 @@ struct PluginPermissions std::vector network_socket; std::vector process; std::vector threading; + // Grants for audit events that expose no target, keyed ":" (e.g. "Socket:socket.__new__"). + std::vector events; }; struct PluginInstallState { diff --git a/src/slic3r/plugin/PyPluginTrampoline.hpp b/src/slic3r/plugin/PyPluginTrampoline.hpp index 915c578353..6d7ca9135c 100644 --- a/src/slic3r/plugin/PyPluginTrampoline.hpp +++ b/src/slic3r/plugin/PyPluginTrampoline.hpp @@ -102,9 +102,9 @@ public: // mistake), both fall back to the base's empty object rather than writing `"cap_config": null`. nlohmann::json get_default_config() const override { + pybind11::gil_scoped_acquire gil; ORCA_PY_AUDIT_SCOPE(); try { - pybind11::gil_scoped_acquire gil; pybind11::function override = pybind11::get_override(static_cast(this), "get_default_config"); if (!override) return Base::get_default_config(); diff --git a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp index 790f6e3ac6..812d69c072 100644 --- a/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp +++ b/src/slic3r/plugin/pluginTypes/printerAgent/PrinterAgentPluginCapabilityTrampoline.hpp @@ -282,11 +282,11 @@ public: int request_bind_ticket(std::string* ticket) override { try { - ORCA_PY_AUDIT_SCOPE(); ::Slic3r::PluginCapabilityInterface::RefCounter _orca_ref_counter(*this); ::Slic3r::PythonGILState gil; if (!gil) throw std::runtime_error("Python interpreter is shutting down"); + ORCA_PY_AUDIT_SCOPE(); pybind11::function override = pybind11::get_override(static_cast(this), "request_bind_ticket"); if (!override) diff --git a/tests/data/texture_import/README.md b/tests/data/texture_import/README.md new file mode 100644 index 0000000000..c398b0ac28 --- /dev/null +++ b/tests/data/texture_import/README.md @@ -0,0 +1,20 @@ +`two_color_jpeg.glb` is a generated, closed tetrahedron with four faces, UVs, and +an embedded 8×8 red/blue JPEG base-color texture. Its coordinates span 20 mm. + +The core tests load all three fixtures through `Model::read_from_file`, convert +textures or MTL colors to painting with boundary smoothing, and match red and blue +to filaments. They run in CI without a display. A separate layout check compares +the smoothing search-tree type seen by a core consumer with the same type compiled +inside `libslic3r_cgal`. The mismatch is checked directly because undefined behavior +can be masked by which inline template implementations the linker selects. + +`two_color_sphere/test_two_color_sphere.obj` and its matching MTL are the original +red/blue material-color sphere supplied by RF47 in +[the PR discussion](https://github.com/OrcaSlicer/OrcaSlicer/pull/16607#issuecomment-6244475095). +They contain solid `Kd` colors and no texture images. + +`test_two_color_sphere_textured.obj` is a derived version of that sphere. Its MTL +uses white `Kd` values and references `textures/two_color.jpg` by a relative path; +the two face groups sample different halves of that image through their UVs. +The JPEG is extracted unchanged from `two_color_jpeg.glb`. This case must retain +both colors from the external texture, rather than fall back to MTL colors. diff --git a/tests/data/texture_import/two_color_jpeg.glb b/tests/data/texture_import/two_color_jpeg.glb new file mode 100644 index 0000000000..35ca7f9069 Binary files /dev/null and b/tests/data/texture_import/two_color_jpeg.glb differ diff --git a/tests/data/texture_import/two_color_sphere/test_two_color_sphere.mtl b/tests/data/texture_import/two_color_sphere/test_two_color_sphere.mtl new file mode 100644 index 0000000000..2c5433836b --- /dev/null +++ b/tests/data/texture_import/two_color_sphere/test_two_color_sphere.mtl @@ -0,0 +1,11 @@ +# test model for OrcaSlicer tex2color +newmtl Red +Ka 0.0000 0.0000 0.0000 +Kd 0.7500 0.2500 0.2500 +Ks 0.0000 0.0000 0.0000 +d 1.0000 +newmtl Blue +Ka 0.0000 0.0000 0.0000 +Kd 0.0700 0.2100 0.7000 +Ks 0.0000 0.0000 0.0000 +d 1.0000 diff --git a/tests/data/texture_import/two_color_sphere/test_two_color_sphere.obj b/tests/data/texture_import/two_color_sphere/test_two_color_sphere.obj new file mode 100644 index 0000000000..eb22031864 --- /dev/null +++ b/tests/data/texture_import/two_color_sphere/test_two_color_sphere.obj @@ -0,0 +1,457 @@ +# test model for OrcaSlicer tex2color +mtllib test_two_color_sphere.mtl +v 0.000000 0.000000 20.000000 +v 7.653669 0.000000 18.477591 +v 7.071068 2.928932 18.477591 +v 5.411961 5.411961 18.477591 +v 2.928932 7.071068 18.477591 +v 0.000000 7.653669 18.477591 +v -2.928932 7.071068 18.477591 +v -5.411961 5.411961 18.477591 +v -7.071068 2.928932 18.477591 +v -7.653669 0.000000 18.477591 +v -7.071068 -2.928932 18.477591 +v -5.411961 -5.411961 18.477591 +v -2.928932 -7.071068 18.477591 +v -0.000000 -7.653669 18.477591 +v 2.928932 -7.071068 18.477591 +v 5.411961 -5.411961 18.477591 +v 7.071068 -2.928932 18.477591 +v 14.142136 0.000000 14.142136 +v 13.065630 5.411961 14.142136 +v 10.000000 10.000000 14.142136 +v 5.411961 13.065630 14.142136 +v 0.000000 14.142136 14.142136 +v -5.411961 13.065630 14.142136 +v -10.000000 10.000000 14.142136 +v -13.065630 5.411961 14.142136 +v -14.142136 0.000000 14.142136 +v -13.065630 -5.411961 14.142136 +v -10.000000 -10.000000 14.142136 +v -5.411961 -13.065630 14.142136 +v -0.000000 -14.142136 14.142136 +v 5.411961 -13.065630 14.142136 +v 10.000000 -10.000000 14.142136 +v 13.065630 -5.411961 14.142136 +v 18.477591 0.000000 7.653669 +v 17.071068 7.071068 7.653669 +v 13.065630 13.065630 7.653669 +v 7.071068 17.071068 7.653669 +v 0.000000 18.477591 7.653669 +v -7.071068 17.071068 7.653669 +v -13.065630 13.065630 7.653669 +v -17.071068 7.071068 7.653669 +v -18.477591 0.000000 7.653669 +v -17.071068 -7.071068 7.653669 +v -13.065630 -13.065630 7.653669 +v -7.071068 -17.071068 7.653669 +v -0.000000 -18.477591 7.653669 +v 7.071068 -17.071068 7.653669 +v 13.065630 -13.065630 7.653669 +v 17.071068 -7.071068 7.653669 +v 20.000000 0.000000 0.000000 +v 18.477591 7.653669 0.000000 +v 14.142136 14.142136 0.000000 +v 7.653669 18.477591 0.000000 +v 0.000000 20.000000 0.000000 +v -7.653669 18.477591 0.000000 +v -14.142136 14.142136 0.000000 +v -18.477591 7.653669 0.000000 +v -20.000000 0.000000 0.000000 +v -18.477591 -7.653669 0.000000 +v -14.142136 -14.142136 0.000000 +v -7.653669 -18.477591 0.000000 +v -0.000000 -20.000000 0.000000 +v 7.653669 -18.477591 0.000000 +v 14.142136 -14.142136 0.000000 +v 18.477591 -7.653669 0.000000 +v 18.477591 0.000000 -7.653669 +v 17.071068 7.071068 -7.653669 +v 13.065630 13.065630 -7.653669 +v 7.071068 17.071068 -7.653669 +v 0.000000 18.477591 -7.653669 +v -7.071068 17.071068 -7.653669 +v -13.065630 13.065630 -7.653669 +v -17.071068 7.071068 -7.653669 +v -18.477591 0.000000 -7.653669 +v -17.071068 -7.071068 -7.653669 +v -13.065630 -13.065630 -7.653669 +v -7.071068 -17.071068 -7.653669 +v -0.000000 -18.477591 -7.653669 +v 7.071068 -17.071068 -7.653669 +v 13.065630 -13.065630 -7.653669 +v 17.071068 -7.071068 -7.653669 +v 14.142136 0.000000 -14.142136 +v 13.065630 5.411961 -14.142136 +v 10.000000 10.000000 -14.142136 +v 5.411961 13.065630 -14.142136 +v 0.000000 14.142136 -14.142136 +v -5.411961 13.065630 -14.142136 +v -10.000000 10.000000 -14.142136 +v -13.065630 5.411961 -14.142136 +v -14.142136 0.000000 -14.142136 +v -13.065630 -5.411961 -14.142136 +v -10.000000 -10.000000 -14.142136 +v -5.411961 -13.065630 -14.142136 +v -0.000000 -14.142136 -14.142136 +v 5.411961 -13.065630 -14.142136 +v 10.000000 -10.000000 -14.142136 +v 13.065630 -5.411961 -14.142136 +v 7.653669 0.000000 -18.477591 +v 7.071068 2.928932 -18.477591 +v 5.411961 5.411961 -18.477591 +v 2.928932 7.071068 -18.477591 +v 0.000000 7.653669 -18.477591 +v -2.928932 7.071068 -18.477591 +v -5.411961 5.411961 -18.477591 +v -7.071068 2.928932 -18.477591 +v -7.653669 0.000000 -18.477591 +v -7.071068 -2.928932 -18.477591 +v -5.411961 -5.411961 -18.477591 +v -2.928932 -7.071068 -18.477591 +v -0.000000 -7.653669 -18.477591 +v 2.928932 -7.071068 -18.477591 +v 5.411961 -5.411961 -18.477591 +v 7.071068 -2.928932 -18.477591 +v 0.000000 0.000000 -20.000000 +vt 0 0 +vn 0.000000 -0.000000 1.000000 +vn 0.439605 0.035510 0.897489 +vn 0.392553 0.201037 0.897489 +vn 0.285739 0.335958 0.897489 +vn 0.135423 0.419732 0.897489 +vn -0.035510 0.439605 0.897489 +vn -0.201037 0.392553 0.897489 +vn -0.335958 0.285739 0.897489 +vn -0.419732 0.135423 0.897489 +vn -0.439605 -0.035510 0.897489 +vn -0.392553 -0.201037 0.897489 +vn -0.285739 -0.335958 0.897489 +vn -0.135423 -0.419732 0.897489 +vn 0.035510 -0.439605 0.897489 +vn 0.201037 -0.392553 0.897489 +vn 0.335958 -0.285739 0.897489 +vn 0.419732 -0.135423 0.897489 +vn 0.725001 0.027230 0.688209 +vn 0.659393 0.302603 0.688209 +vn 0.493399 0.531907 0.688209 +vn 0.252289 0.680234 0.688209 +vn -0.027230 0.725001 0.688209 +vn -0.302603 0.659393 0.688209 +vn -0.531907 0.493399 0.688209 +vn -0.680234 0.252289 0.688209 +vn -0.725001 -0.027230 0.688209 +vn -0.659393 -0.302603 0.688209 +vn -0.493399 -0.531907 0.688209 +vn -0.252289 -0.680234 0.688209 +vn 0.027230 -0.725001 0.688209 +vn 0.302603 -0.659393 0.688209 +vn 0.531907 -0.493399 0.688209 +vn 0.680234 -0.252289 0.688209 +vn 0.927851 0.014745 0.372658 +vn 0.851580 0.368696 0.372658 +vn 0.645664 0.666516 0.372658 +vn 0.341451 0.862865 0.372658 +vn -0.014745 0.927851 0.372658 +vn -0.368696 0.851580 0.372658 +vn -0.666516 0.645664 0.372658 +vn -0.862865 0.341451 0.372658 +vn -0.927851 -0.014745 0.372658 +vn -0.851580 -0.368696 0.372658 +vn -0.645664 -0.666516 0.372658 +vn -0.341451 -0.862865 0.372658 +vn 0.014745 -0.927851 0.372658 +vn 0.368696 -0.851580 0.372658 +vn 0.666516 -0.645664 0.372658 +vn 0.862865 -0.341451 0.372658 +vn 1.000000 -0.000000 -0.000000 +vn 0.923880 0.382683 0.000000 +vn 0.707107 0.707107 0.000000 +vn 0.382683 0.923880 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.382683 0.923880 0.000000 +vn -0.707107 0.707107 0.000000 +vn -0.923880 0.382683 0.000000 +vn -1.000000 0.000000 0.000000 +vn -0.923880 -0.382683 -0.000000 +vn -0.707107 -0.707107 0.000000 +vn -0.382683 -0.923880 -0.000000 +vn -0.000000 -1.000000 -0.000000 +vn 0.382683 -0.923880 0.000000 +vn 0.707107 -0.707107 0.000000 +vn 0.923880 -0.382683 -0.000000 +vn 0.927851 -0.014745 -0.372658 +vn 0.862865 0.341451 -0.372658 +vn 0.666516 0.645664 -0.372658 +vn 0.368696 0.851580 -0.372658 +vn 0.014745 0.927851 -0.372658 +vn -0.341451 0.862865 -0.372658 +vn -0.645664 0.666516 -0.372658 +vn -0.851580 0.368696 -0.372658 +vn -0.927851 0.014745 -0.372658 +vn -0.862865 -0.341451 -0.372658 +vn -0.666516 -0.645664 -0.372658 +vn -0.368696 -0.851580 -0.372658 +vn -0.014745 -0.927851 -0.372658 +vn 0.341451 -0.862865 -0.372658 +vn 0.645664 -0.666516 -0.372658 +vn 0.851580 -0.368696 -0.372658 +vn 0.725001 -0.027230 -0.688209 +vn 0.680234 0.252289 -0.688209 +vn 0.531907 0.493399 -0.688209 +vn 0.302603 0.659393 -0.688209 +vn 0.027230 0.725001 -0.688209 +vn -0.252289 0.680234 -0.688209 +vn -0.493399 0.531907 -0.688209 +vn -0.659393 0.302603 -0.688209 +vn -0.725001 0.027230 -0.688209 +vn -0.680234 -0.252289 -0.688209 +vn -0.531907 -0.493399 -0.688209 +vn -0.302603 -0.659393 -0.688209 +vn -0.027230 -0.725001 -0.688209 +vn 0.252289 -0.680234 -0.688209 +vn 0.493399 -0.531907 -0.688209 +vn 0.659393 -0.302603 -0.688209 +vn 0.439605 -0.035510 -0.897489 +vn 0.419732 0.135423 -0.897489 +vn 0.335958 0.285739 -0.897489 +vn 0.201037 0.392553 -0.897489 +vn 0.035510 0.439605 -0.897489 +vn -0.135423 0.419732 -0.897489 +vn -0.285739 0.335958 -0.897489 +vn -0.392553 0.201037 -0.897489 +vn -0.439605 0.035510 -0.897489 +vn -0.419732 -0.135423 -0.897489 +vn -0.335958 -0.285739 -0.897489 +vn -0.201037 -0.392553 -0.897489 +vn -0.035510 -0.439605 -0.897489 +vn 0.135423 -0.419732 -0.897489 +vn 0.285739 -0.335958 -0.897489 +vn 0.392553 -0.201037 -0.897489 +vn 0.000000 -0.000000 -1.000000 +usemtl Red +f 1/1/1 2/1/2 3/1/3 +f 1/1/1 3/1/3 4/1/4 +f 1/1/1 4/1/4 5/1/5 +f 1/1/1 5/1/5 6/1/6 +f 1/1/1 6/1/6 7/1/7 +f 1/1/1 7/1/7 8/1/8 +f 1/1/1 8/1/8 9/1/9 +f 1/1/1 9/1/9 10/1/10 +f 1/1/1 10/1/10 11/1/11 +f 1/1/1 11/1/11 12/1/12 +f 1/1/1 12/1/12 13/1/13 +f 1/1/1 13/1/13 14/1/14 +f 1/1/1 14/1/14 15/1/15 +f 1/1/1 15/1/15 16/1/16 +f 1/1/1 16/1/16 17/1/17 +f 1/1/1 17/1/17 2/1/2 +f 2/1/2 18/1/18 19/1/19 +f 2/1/2 19/1/19 3/1/3 +f 3/1/3 19/1/19 20/1/20 +f 3/1/3 20/1/20 4/1/4 +f 4/1/4 20/1/20 21/1/21 +f 4/1/4 21/1/21 5/1/5 +f 5/1/5 21/1/21 22/1/22 +f 5/1/5 22/1/22 6/1/6 +f 6/1/6 22/1/22 23/1/23 +f 6/1/6 23/1/23 7/1/7 +f 7/1/7 23/1/23 24/1/24 +f 7/1/7 24/1/24 8/1/8 +f 8/1/8 24/1/24 25/1/25 +f 8/1/8 25/1/25 9/1/9 +f 9/1/9 25/1/25 26/1/26 +f 9/1/9 26/1/26 10/1/10 +f 10/1/10 26/1/26 27/1/27 +f 10/1/10 27/1/27 11/1/11 +f 11/1/11 27/1/27 28/1/28 +f 11/1/11 28/1/28 12/1/12 +f 12/1/12 28/1/28 29/1/29 +f 12/1/12 29/1/29 13/1/13 +f 13/1/13 29/1/29 30/1/30 +f 13/1/13 30/1/30 14/1/14 +f 14/1/14 30/1/30 31/1/31 +f 14/1/14 31/1/31 15/1/15 +f 15/1/15 31/1/31 32/1/32 +f 15/1/15 32/1/32 16/1/16 +f 16/1/16 32/1/32 33/1/33 +f 16/1/16 33/1/33 17/1/17 +f 17/1/17 33/1/33 18/1/18 +f 17/1/17 18/1/18 2/1/2 +f 18/1/18 34/1/34 35/1/35 +f 18/1/18 35/1/35 19/1/19 +f 19/1/19 35/1/35 36/1/36 +f 19/1/19 36/1/36 20/1/20 +f 20/1/20 36/1/36 37/1/37 +f 20/1/20 37/1/37 21/1/21 +f 21/1/21 37/1/37 38/1/38 +f 21/1/21 38/1/38 22/1/22 +f 22/1/22 38/1/38 39/1/39 +f 22/1/22 39/1/39 23/1/23 +f 23/1/23 39/1/39 40/1/40 +f 23/1/23 40/1/40 24/1/24 +f 24/1/24 40/1/40 41/1/41 +f 24/1/24 41/1/41 25/1/25 +f 25/1/25 41/1/41 42/1/42 +f 25/1/25 42/1/42 26/1/26 +f 26/1/26 42/1/42 43/1/43 +f 26/1/26 43/1/43 27/1/27 +f 27/1/27 43/1/43 44/1/44 +f 27/1/27 44/1/44 28/1/28 +f 28/1/28 44/1/44 45/1/45 +f 28/1/28 45/1/45 29/1/29 +f 29/1/29 45/1/45 46/1/46 +f 29/1/29 46/1/46 30/1/30 +f 30/1/30 46/1/46 47/1/47 +f 30/1/30 47/1/47 31/1/31 +f 31/1/31 47/1/47 48/1/48 +f 31/1/31 48/1/48 32/1/32 +f 32/1/32 48/1/48 49/1/49 +f 32/1/32 49/1/49 33/1/33 +f 33/1/33 49/1/49 34/1/34 +f 33/1/33 34/1/34 18/1/18 +f 34/1/34 50/1/50 51/1/51 +f 34/1/34 51/1/51 35/1/35 +f 35/1/35 51/1/51 52/1/52 +f 35/1/35 52/1/52 36/1/36 +f 36/1/36 52/1/52 53/1/53 +f 36/1/36 53/1/53 37/1/37 +f 37/1/37 53/1/53 54/1/54 +f 37/1/37 54/1/54 38/1/38 +f 38/1/38 54/1/54 55/1/55 +f 38/1/38 55/1/55 39/1/39 +f 39/1/39 55/1/55 56/1/56 +f 39/1/39 56/1/56 40/1/40 +f 40/1/40 56/1/56 57/1/57 +f 40/1/40 57/1/57 41/1/41 +f 41/1/41 57/1/57 58/1/58 +f 41/1/41 58/1/58 42/1/42 +f 42/1/42 58/1/58 59/1/59 +f 42/1/42 59/1/59 43/1/43 +f 43/1/43 59/1/59 60/1/60 +f 43/1/43 60/1/60 44/1/44 +f 44/1/44 60/1/60 61/1/61 +f 44/1/44 61/1/61 45/1/45 +f 45/1/45 61/1/61 62/1/62 +f 45/1/45 62/1/62 46/1/46 +f 46/1/46 62/1/62 63/1/63 +f 46/1/46 63/1/63 47/1/47 +f 47/1/47 63/1/63 64/1/64 +f 47/1/47 64/1/64 48/1/48 +f 48/1/48 64/1/64 65/1/65 +f 48/1/48 65/1/65 49/1/49 +f 49/1/49 65/1/65 50/1/50 +f 49/1/49 50/1/50 34/1/34 +usemtl Blue +f 50/1/50 66/1/66 67/1/67 +f 50/1/50 67/1/67 51/1/51 +f 51/1/51 67/1/67 68/1/68 +f 51/1/51 68/1/68 52/1/52 +f 52/1/52 68/1/68 69/1/69 +f 52/1/52 69/1/69 53/1/53 +f 53/1/53 69/1/69 70/1/70 +f 53/1/53 70/1/70 54/1/54 +f 54/1/54 70/1/70 71/1/71 +f 54/1/54 71/1/71 55/1/55 +f 55/1/55 71/1/71 72/1/72 +f 55/1/55 72/1/72 56/1/56 +f 56/1/56 72/1/72 73/1/73 +f 56/1/56 73/1/73 57/1/57 +f 57/1/57 73/1/73 74/1/74 +f 57/1/57 74/1/74 58/1/58 +f 58/1/58 74/1/74 75/1/75 +f 58/1/58 75/1/75 59/1/59 +f 59/1/59 75/1/75 76/1/76 +f 59/1/59 76/1/76 60/1/60 +f 60/1/60 76/1/76 77/1/77 +f 60/1/60 77/1/77 61/1/61 +f 61/1/61 77/1/77 78/1/78 +f 61/1/61 78/1/78 62/1/62 +f 62/1/62 78/1/78 79/1/79 +f 62/1/62 79/1/79 63/1/63 +f 63/1/63 79/1/79 80/1/80 +f 63/1/63 80/1/80 64/1/64 +f 64/1/64 80/1/80 81/1/81 +f 64/1/64 81/1/81 65/1/65 +f 65/1/65 81/1/81 66/1/66 +f 65/1/65 66/1/66 50/1/50 +f 66/1/66 82/1/82 83/1/83 +f 66/1/66 83/1/83 67/1/67 +f 67/1/67 83/1/83 84/1/84 +f 67/1/67 84/1/84 68/1/68 +f 68/1/68 84/1/84 85/1/85 +f 68/1/68 85/1/85 69/1/69 +f 69/1/69 85/1/85 86/1/86 +f 69/1/69 86/1/86 70/1/70 +f 70/1/70 86/1/86 87/1/87 +f 70/1/70 87/1/87 71/1/71 +f 71/1/71 87/1/87 88/1/88 +f 71/1/71 88/1/88 72/1/72 +f 72/1/72 88/1/88 89/1/89 +f 72/1/72 89/1/89 73/1/73 +f 73/1/73 89/1/89 90/1/90 +f 73/1/73 90/1/90 74/1/74 +f 74/1/74 90/1/90 91/1/91 +f 74/1/74 91/1/91 75/1/75 +f 75/1/75 91/1/91 92/1/92 +f 75/1/75 92/1/92 76/1/76 +f 76/1/76 92/1/92 93/1/93 +f 76/1/76 93/1/93 77/1/77 +f 77/1/77 93/1/93 94/1/94 +f 77/1/77 94/1/94 78/1/78 +f 78/1/78 94/1/94 95/1/95 +f 78/1/78 95/1/95 79/1/79 +f 79/1/79 95/1/95 96/1/96 +f 79/1/79 96/1/96 80/1/80 +f 80/1/80 96/1/96 97/1/97 +f 80/1/80 97/1/97 81/1/81 +f 81/1/81 97/1/97 82/1/82 +f 81/1/81 82/1/82 66/1/66 +f 82/1/82 98/1/98 99/1/99 +f 82/1/82 99/1/99 83/1/83 +f 83/1/83 99/1/99 100/1/100 +f 83/1/83 100/1/100 84/1/84 +f 84/1/84 100/1/100 101/1/101 +f 84/1/84 101/1/101 85/1/85 +f 85/1/85 101/1/101 102/1/102 +f 85/1/85 102/1/102 86/1/86 +f 86/1/86 102/1/102 103/1/103 +f 86/1/86 103/1/103 87/1/87 +f 87/1/87 103/1/103 104/1/104 +f 87/1/87 104/1/104 88/1/88 +f 88/1/88 104/1/104 105/1/105 +f 88/1/88 105/1/105 89/1/89 +f 89/1/89 105/1/105 106/1/106 +f 89/1/89 106/1/106 90/1/90 +f 90/1/90 106/1/106 107/1/107 +f 90/1/90 107/1/107 91/1/91 +f 91/1/91 107/1/107 108/1/108 +f 91/1/91 108/1/108 92/1/92 +f 92/1/92 108/1/108 109/1/109 +f 92/1/92 109/1/109 93/1/93 +f 93/1/93 109/1/109 110/1/110 +f 93/1/93 110/1/110 94/1/94 +f 94/1/94 110/1/110 111/1/111 +f 94/1/94 111/1/111 95/1/95 +f 95/1/95 111/1/111 112/1/112 +f 95/1/95 112/1/112 96/1/96 +f 96/1/96 112/1/112 113/1/113 +f 96/1/96 113/1/113 97/1/97 +f 97/1/97 113/1/113 98/1/98 +f 97/1/97 98/1/98 82/1/82 +f 114/1/114 99/1/99 98/1/98 +f 114/1/114 100/1/100 99/1/99 +f 114/1/114 101/1/101 100/1/100 +f 114/1/114 102/1/102 101/1/101 +f 114/1/114 103/1/103 102/1/102 +f 114/1/114 104/1/104 103/1/103 +f 114/1/114 105/1/105 104/1/104 +f 114/1/114 106/1/106 105/1/105 +f 114/1/114 107/1/107 106/1/106 +f 114/1/114 108/1/108 107/1/107 +f 114/1/114 109/1/109 108/1/108 +f 114/1/114 110/1/110 109/1/109 +f 114/1/114 111/1/111 110/1/110 +f 114/1/114 112/1/112 111/1/111 +f 114/1/114 113/1/113 112/1/112 +f 114/1/114 98/1/98 113/1/113 diff --git a/tests/data/texture_import/two_color_sphere/test_two_color_sphere_textured.mtl b/tests/data/texture_import/two_color_sphere/test_two_color_sphere_textured.mtl new file mode 100644 index 0000000000..a4fb020656 --- /dev/null +++ b/tests/data/texture_import/two_color_sphere/test_two_color_sphere_textured.mtl @@ -0,0 +1,8 @@ +# Derived texture-file regression: color comes from map_Kd, not Kd. +newmtl Red +Kd 1 1 1 +map_Kd textures/two_color.jpg + +newmtl Blue +Kd 1 1 1 +map_Kd textures/two_color.jpg diff --git a/tests/data/texture_import/two_color_sphere/test_two_color_sphere_textured.obj b/tests/data/texture_import/two_color_sphere/test_two_color_sphere_textured.obj new file mode 100644 index 0000000000..a62f0fefb6 --- /dev/null +++ b/tests/data/texture_import/two_color_sphere/test_two_color_sphere_textured.obj @@ -0,0 +1,458 @@ +# test model for OrcaSlicer tex2color +mtllib test_two_color_sphere_textured.mtl +v 0.000000 0.000000 20.000000 +v 7.653669 0.000000 18.477591 +v 7.071068 2.928932 18.477591 +v 5.411961 5.411961 18.477591 +v 2.928932 7.071068 18.477591 +v 0.000000 7.653669 18.477591 +v -2.928932 7.071068 18.477591 +v -5.411961 5.411961 18.477591 +v -7.071068 2.928932 18.477591 +v -7.653669 0.000000 18.477591 +v -7.071068 -2.928932 18.477591 +v -5.411961 -5.411961 18.477591 +v -2.928932 -7.071068 18.477591 +v -0.000000 -7.653669 18.477591 +v 2.928932 -7.071068 18.477591 +v 5.411961 -5.411961 18.477591 +v 7.071068 -2.928932 18.477591 +v 14.142136 0.000000 14.142136 +v 13.065630 5.411961 14.142136 +v 10.000000 10.000000 14.142136 +v 5.411961 13.065630 14.142136 +v 0.000000 14.142136 14.142136 +v -5.411961 13.065630 14.142136 +v -10.000000 10.000000 14.142136 +v -13.065630 5.411961 14.142136 +v -14.142136 0.000000 14.142136 +v -13.065630 -5.411961 14.142136 +v -10.000000 -10.000000 14.142136 +v -5.411961 -13.065630 14.142136 +v -0.000000 -14.142136 14.142136 +v 5.411961 -13.065630 14.142136 +v 10.000000 -10.000000 14.142136 +v 13.065630 -5.411961 14.142136 +v 18.477591 0.000000 7.653669 +v 17.071068 7.071068 7.653669 +v 13.065630 13.065630 7.653669 +v 7.071068 17.071068 7.653669 +v 0.000000 18.477591 7.653669 +v -7.071068 17.071068 7.653669 +v -13.065630 13.065630 7.653669 +v -17.071068 7.071068 7.653669 +v -18.477591 0.000000 7.653669 +v -17.071068 -7.071068 7.653669 +v -13.065630 -13.065630 7.653669 +v -7.071068 -17.071068 7.653669 +v -0.000000 -18.477591 7.653669 +v 7.071068 -17.071068 7.653669 +v 13.065630 -13.065630 7.653669 +v 17.071068 -7.071068 7.653669 +v 20.000000 0.000000 0.000000 +v 18.477591 7.653669 0.000000 +v 14.142136 14.142136 0.000000 +v 7.653669 18.477591 0.000000 +v 0.000000 20.000000 0.000000 +v -7.653669 18.477591 0.000000 +v -14.142136 14.142136 0.000000 +v -18.477591 7.653669 0.000000 +v -20.000000 0.000000 0.000000 +v -18.477591 -7.653669 0.000000 +v -14.142136 -14.142136 0.000000 +v -7.653669 -18.477591 0.000000 +v -0.000000 -20.000000 0.000000 +v 7.653669 -18.477591 0.000000 +v 14.142136 -14.142136 0.000000 +v 18.477591 -7.653669 0.000000 +v 18.477591 0.000000 -7.653669 +v 17.071068 7.071068 -7.653669 +v 13.065630 13.065630 -7.653669 +v 7.071068 17.071068 -7.653669 +v 0.000000 18.477591 -7.653669 +v -7.071068 17.071068 -7.653669 +v -13.065630 13.065630 -7.653669 +v -17.071068 7.071068 -7.653669 +v -18.477591 0.000000 -7.653669 +v -17.071068 -7.071068 -7.653669 +v -13.065630 -13.065630 -7.653669 +v -7.071068 -17.071068 -7.653669 +v -0.000000 -18.477591 -7.653669 +v 7.071068 -17.071068 -7.653669 +v 13.065630 -13.065630 -7.653669 +v 17.071068 -7.071068 -7.653669 +v 14.142136 0.000000 -14.142136 +v 13.065630 5.411961 -14.142136 +v 10.000000 10.000000 -14.142136 +v 5.411961 13.065630 -14.142136 +v 0.000000 14.142136 -14.142136 +v -5.411961 13.065630 -14.142136 +v -10.000000 10.000000 -14.142136 +v -13.065630 5.411961 -14.142136 +v -14.142136 0.000000 -14.142136 +v -13.065630 -5.411961 -14.142136 +v -10.000000 -10.000000 -14.142136 +v -5.411961 -13.065630 -14.142136 +v -0.000000 -14.142136 -14.142136 +v 5.411961 -13.065630 -14.142136 +v 10.000000 -10.000000 -14.142136 +v 13.065630 -5.411961 -14.142136 +v 7.653669 0.000000 -18.477591 +v 7.071068 2.928932 -18.477591 +v 5.411961 5.411961 -18.477591 +v 2.928932 7.071068 -18.477591 +v 0.000000 7.653669 -18.477591 +v -2.928932 7.071068 -18.477591 +v -5.411961 5.411961 -18.477591 +v -7.071068 2.928932 -18.477591 +v -7.653669 0.000000 -18.477591 +v -7.071068 -2.928932 -18.477591 +v -5.411961 -5.411961 -18.477591 +v -2.928932 -7.071068 -18.477591 +v -0.000000 -7.653669 -18.477591 +v 2.928932 -7.071068 -18.477591 +v 5.411961 -5.411961 -18.477591 +v 7.071068 -2.928932 -18.477591 +v 0.000000 0.000000 -20.000000 +vt 0.25 0.5 +vt 0.75 0.5 +vn 0.000000 -0.000000 1.000000 +vn 0.439605 0.035510 0.897489 +vn 0.392553 0.201037 0.897489 +vn 0.285739 0.335958 0.897489 +vn 0.135423 0.419732 0.897489 +vn -0.035510 0.439605 0.897489 +vn -0.201037 0.392553 0.897489 +vn -0.335958 0.285739 0.897489 +vn -0.419732 0.135423 0.897489 +vn -0.439605 -0.035510 0.897489 +vn -0.392553 -0.201037 0.897489 +vn -0.285739 -0.335958 0.897489 +vn -0.135423 -0.419732 0.897489 +vn 0.035510 -0.439605 0.897489 +vn 0.201037 -0.392553 0.897489 +vn 0.335958 -0.285739 0.897489 +vn 0.419732 -0.135423 0.897489 +vn 0.725001 0.027230 0.688209 +vn 0.659393 0.302603 0.688209 +vn 0.493399 0.531907 0.688209 +vn 0.252289 0.680234 0.688209 +vn -0.027230 0.725001 0.688209 +vn -0.302603 0.659393 0.688209 +vn -0.531907 0.493399 0.688209 +vn -0.680234 0.252289 0.688209 +vn -0.725001 -0.027230 0.688209 +vn -0.659393 -0.302603 0.688209 +vn -0.493399 -0.531907 0.688209 +vn -0.252289 -0.680234 0.688209 +vn 0.027230 -0.725001 0.688209 +vn 0.302603 -0.659393 0.688209 +vn 0.531907 -0.493399 0.688209 +vn 0.680234 -0.252289 0.688209 +vn 0.927851 0.014745 0.372658 +vn 0.851580 0.368696 0.372658 +vn 0.645664 0.666516 0.372658 +vn 0.341451 0.862865 0.372658 +vn -0.014745 0.927851 0.372658 +vn -0.368696 0.851580 0.372658 +vn -0.666516 0.645664 0.372658 +vn -0.862865 0.341451 0.372658 +vn -0.927851 -0.014745 0.372658 +vn -0.851580 -0.368696 0.372658 +vn -0.645664 -0.666516 0.372658 +vn -0.341451 -0.862865 0.372658 +vn 0.014745 -0.927851 0.372658 +vn 0.368696 -0.851580 0.372658 +vn 0.666516 -0.645664 0.372658 +vn 0.862865 -0.341451 0.372658 +vn 1.000000 -0.000000 -0.000000 +vn 0.923880 0.382683 0.000000 +vn 0.707107 0.707107 0.000000 +vn 0.382683 0.923880 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.382683 0.923880 0.000000 +vn -0.707107 0.707107 0.000000 +vn -0.923880 0.382683 0.000000 +vn -1.000000 0.000000 0.000000 +vn -0.923880 -0.382683 -0.000000 +vn -0.707107 -0.707107 0.000000 +vn -0.382683 -0.923880 -0.000000 +vn -0.000000 -1.000000 -0.000000 +vn 0.382683 -0.923880 0.000000 +vn 0.707107 -0.707107 0.000000 +vn 0.923880 -0.382683 -0.000000 +vn 0.927851 -0.014745 -0.372658 +vn 0.862865 0.341451 -0.372658 +vn 0.666516 0.645664 -0.372658 +vn 0.368696 0.851580 -0.372658 +vn 0.014745 0.927851 -0.372658 +vn -0.341451 0.862865 -0.372658 +vn -0.645664 0.666516 -0.372658 +vn -0.851580 0.368696 -0.372658 +vn -0.927851 0.014745 -0.372658 +vn -0.862865 -0.341451 -0.372658 +vn -0.666516 -0.645664 -0.372658 +vn -0.368696 -0.851580 -0.372658 +vn -0.014745 -0.927851 -0.372658 +vn 0.341451 -0.862865 -0.372658 +vn 0.645664 -0.666516 -0.372658 +vn 0.851580 -0.368696 -0.372658 +vn 0.725001 -0.027230 -0.688209 +vn 0.680234 0.252289 -0.688209 +vn 0.531907 0.493399 -0.688209 +vn 0.302603 0.659393 -0.688209 +vn 0.027230 0.725001 -0.688209 +vn -0.252289 0.680234 -0.688209 +vn -0.493399 0.531907 -0.688209 +vn -0.659393 0.302603 -0.688209 +vn -0.725001 0.027230 -0.688209 +vn -0.680234 -0.252289 -0.688209 +vn -0.531907 -0.493399 -0.688209 +vn -0.302603 -0.659393 -0.688209 +vn -0.027230 -0.725001 -0.688209 +vn 0.252289 -0.680234 -0.688209 +vn 0.493399 -0.531907 -0.688209 +vn 0.659393 -0.302603 -0.688209 +vn 0.439605 -0.035510 -0.897489 +vn 0.419732 0.135423 -0.897489 +vn 0.335958 0.285739 -0.897489 +vn 0.201037 0.392553 -0.897489 +vn 0.035510 0.439605 -0.897489 +vn -0.135423 0.419732 -0.897489 +vn -0.285739 0.335958 -0.897489 +vn -0.392553 0.201037 -0.897489 +vn -0.439605 0.035510 -0.897489 +vn -0.419732 -0.135423 -0.897489 +vn -0.335958 -0.285739 -0.897489 +vn -0.201037 -0.392553 -0.897489 +vn -0.035510 -0.439605 -0.897489 +vn 0.135423 -0.419732 -0.897489 +vn 0.285739 -0.335958 -0.897489 +vn 0.392553 -0.201037 -0.897489 +vn 0.000000 -0.000000 -1.000000 +usemtl Red +f 1/1/1 2/1/2 3/1/3 +f 1/1/1 3/1/3 4/1/4 +f 1/1/1 4/1/4 5/1/5 +f 1/1/1 5/1/5 6/1/6 +f 1/1/1 6/1/6 7/1/7 +f 1/1/1 7/1/7 8/1/8 +f 1/1/1 8/1/8 9/1/9 +f 1/1/1 9/1/9 10/1/10 +f 1/1/1 10/1/10 11/1/11 +f 1/1/1 11/1/11 12/1/12 +f 1/1/1 12/1/12 13/1/13 +f 1/1/1 13/1/13 14/1/14 +f 1/1/1 14/1/14 15/1/15 +f 1/1/1 15/1/15 16/1/16 +f 1/1/1 16/1/16 17/1/17 +f 1/1/1 17/1/17 2/1/2 +f 2/1/2 18/1/18 19/1/19 +f 2/1/2 19/1/19 3/1/3 +f 3/1/3 19/1/19 20/1/20 +f 3/1/3 20/1/20 4/1/4 +f 4/1/4 20/1/20 21/1/21 +f 4/1/4 21/1/21 5/1/5 +f 5/1/5 21/1/21 22/1/22 +f 5/1/5 22/1/22 6/1/6 +f 6/1/6 22/1/22 23/1/23 +f 6/1/6 23/1/23 7/1/7 +f 7/1/7 23/1/23 24/1/24 +f 7/1/7 24/1/24 8/1/8 +f 8/1/8 24/1/24 25/1/25 +f 8/1/8 25/1/25 9/1/9 +f 9/1/9 25/1/25 26/1/26 +f 9/1/9 26/1/26 10/1/10 +f 10/1/10 26/1/26 27/1/27 +f 10/1/10 27/1/27 11/1/11 +f 11/1/11 27/1/27 28/1/28 +f 11/1/11 28/1/28 12/1/12 +f 12/1/12 28/1/28 29/1/29 +f 12/1/12 29/1/29 13/1/13 +f 13/1/13 29/1/29 30/1/30 +f 13/1/13 30/1/30 14/1/14 +f 14/1/14 30/1/30 31/1/31 +f 14/1/14 31/1/31 15/1/15 +f 15/1/15 31/1/31 32/1/32 +f 15/1/15 32/1/32 16/1/16 +f 16/1/16 32/1/32 33/1/33 +f 16/1/16 33/1/33 17/1/17 +f 17/1/17 33/1/33 18/1/18 +f 17/1/17 18/1/18 2/1/2 +f 18/1/18 34/1/34 35/1/35 +f 18/1/18 35/1/35 19/1/19 +f 19/1/19 35/1/35 36/1/36 +f 19/1/19 36/1/36 20/1/20 +f 20/1/20 36/1/36 37/1/37 +f 20/1/20 37/1/37 21/1/21 +f 21/1/21 37/1/37 38/1/38 +f 21/1/21 38/1/38 22/1/22 +f 22/1/22 38/1/38 39/1/39 +f 22/1/22 39/1/39 23/1/23 +f 23/1/23 39/1/39 40/1/40 +f 23/1/23 40/1/40 24/1/24 +f 24/1/24 40/1/40 41/1/41 +f 24/1/24 41/1/41 25/1/25 +f 25/1/25 41/1/41 42/1/42 +f 25/1/25 42/1/42 26/1/26 +f 26/1/26 42/1/42 43/1/43 +f 26/1/26 43/1/43 27/1/27 +f 27/1/27 43/1/43 44/1/44 +f 27/1/27 44/1/44 28/1/28 +f 28/1/28 44/1/44 45/1/45 +f 28/1/28 45/1/45 29/1/29 +f 29/1/29 45/1/45 46/1/46 +f 29/1/29 46/1/46 30/1/30 +f 30/1/30 46/1/46 47/1/47 +f 30/1/30 47/1/47 31/1/31 +f 31/1/31 47/1/47 48/1/48 +f 31/1/31 48/1/48 32/1/32 +f 32/1/32 48/1/48 49/1/49 +f 32/1/32 49/1/49 33/1/33 +f 33/1/33 49/1/49 34/1/34 +f 33/1/33 34/1/34 18/1/18 +f 34/1/34 50/1/50 51/1/51 +f 34/1/34 51/1/51 35/1/35 +f 35/1/35 51/1/51 52/1/52 +f 35/1/35 52/1/52 36/1/36 +f 36/1/36 52/1/52 53/1/53 +f 36/1/36 53/1/53 37/1/37 +f 37/1/37 53/1/53 54/1/54 +f 37/1/37 54/1/54 38/1/38 +f 38/1/38 54/1/54 55/1/55 +f 38/1/38 55/1/55 39/1/39 +f 39/1/39 55/1/55 56/1/56 +f 39/1/39 56/1/56 40/1/40 +f 40/1/40 56/1/56 57/1/57 +f 40/1/40 57/1/57 41/1/41 +f 41/1/41 57/1/57 58/1/58 +f 41/1/41 58/1/58 42/1/42 +f 42/1/42 58/1/58 59/1/59 +f 42/1/42 59/1/59 43/1/43 +f 43/1/43 59/1/59 60/1/60 +f 43/1/43 60/1/60 44/1/44 +f 44/1/44 60/1/60 61/1/61 +f 44/1/44 61/1/61 45/1/45 +f 45/1/45 61/1/61 62/1/62 +f 45/1/45 62/1/62 46/1/46 +f 46/1/46 62/1/62 63/1/63 +f 46/1/46 63/1/63 47/1/47 +f 47/1/47 63/1/63 64/1/64 +f 47/1/47 64/1/64 48/1/48 +f 48/1/48 64/1/64 65/1/65 +f 48/1/48 65/1/65 49/1/49 +f 49/1/49 65/1/65 50/1/50 +f 49/1/49 50/1/50 34/1/34 +usemtl Blue +f 50/2/50 66/2/66 67/2/67 +f 50/2/50 67/2/67 51/2/51 +f 51/2/51 67/2/67 68/2/68 +f 51/2/51 68/2/68 52/2/52 +f 52/2/52 68/2/68 69/2/69 +f 52/2/52 69/2/69 53/2/53 +f 53/2/53 69/2/69 70/2/70 +f 53/2/53 70/2/70 54/2/54 +f 54/2/54 70/2/70 71/2/71 +f 54/2/54 71/2/71 55/2/55 +f 55/2/55 71/2/71 72/2/72 +f 55/2/55 72/2/72 56/2/56 +f 56/2/56 72/2/72 73/2/73 +f 56/2/56 73/2/73 57/2/57 +f 57/2/57 73/2/73 74/2/74 +f 57/2/57 74/2/74 58/2/58 +f 58/2/58 74/2/74 75/2/75 +f 58/2/58 75/2/75 59/2/59 +f 59/2/59 75/2/75 76/2/76 +f 59/2/59 76/2/76 60/2/60 +f 60/2/60 76/2/76 77/2/77 +f 60/2/60 77/2/77 61/2/61 +f 61/2/61 77/2/77 78/2/78 +f 61/2/61 78/2/78 62/2/62 +f 62/2/62 78/2/78 79/2/79 +f 62/2/62 79/2/79 63/2/63 +f 63/2/63 79/2/79 80/2/80 +f 63/2/63 80/2/80 64/2/64 +f 64/2/64 80/2/80 81/2/81 +f 64/2/64 81/2/81 65/2/65 +f 65/2/65 81/2/81 66/2/66 +f 65/2/65 66/2/66 50/2/50 +f 66/2/66 82/2/82 83/2/83 +f 66/2/66 83/2/83 67/2/67 +f 67/2/67 83/2/83 84/2/84 +f 67/2/67 84/2/84 68/2/68 +f 68/2/68 84/2/84 85/2/85 +f 68/2/68 85/2/85 69/2/69 +f 69/2/69 85/2/85 86/2/86 +f 69/2/69 86/2/86 70/2/70 +f 70/2/70 86/2/86 87/2/87 +f 70/2/70 87/2/87 71/2/71 +f 71/2/71 87/2/87 88/2/88 +f 71/2/71 88/2/88 72/2/72 +f 72/2/72 88/2/88 89/2/89 +f 72/2/72 89/2/89 73/2/73 +f 73/2/73 89/2/89 90/2/90 +f 73/2/73 90/2/90 74/2/74 +f 74/2/74 90/2/90 91/2/91 +f 74/2/74 91/2/91 75/2/75 +f 75/2/75 91/2/91 92/2/92 +f 75/2/75 92/2/92 76/2/76 +f 76/2/76 92/2/92 93/2/93 +f 76/2/76 93/2/93 77/2/77 +f 77/2/77 93/2/93 94/2/94 +f 77/2/77 94/2/94 78/2/78 +f 78/2/78 94/2/94 95/2/95 +f 78/2/78 95/2/95 79/2/79 +f 79/2/79 95/2/95 96/2/96 +f 79/2/79 96/2/96 80/2/80 +f 80/2/80 96/2/96 97/2/97 +f 80/2/80 97/2/97 81/2/81 +f 81/2/81 97/2/97 82/2/82 +f 81/2/81 82/2/82 66/2/66 +f 82/2/82 98/2/98 99/2/99 +f 82/2/82 99/2/99 83/2/83 +f 83/2/83 99/2/99 100/2/100 +f 83/2/83 100/2/100 84/2/84 +f 84/2/84 100/2/100 101/2/101 +f 84/2/84 101/2/101 85/2/85 +f 85/2/85 101/2/101 102/2/102 +f 85/2/85 102/2/102 86/2/86 +f 86/2/86 102/2/102 103/2/103 +f 86/2/86 103/2/103 87/2/87 +f 87/2/87 103/2/103 104/2/104 +f 87/2/87 104/2/104 88/2/88 +f 88/2/88 104/2/104 105/2/105 +f 88/2/88 105/2/105 89/2/89 +f 89/2/89 105/2/105 106/2/106 +f 89/2/89 106/2/106 90/2/90 +f 90/2/90 106/2/106 107/2/107 +f 90/2/90 107/2/107 91/2/91 +f 91/2/91 107/2/107 108/2/108 +f 91/2/91 108/2/108 92/2/92 +f 92/2/92 108/2/108 109/2/109 +f 92/2/92 109/2/109 93/2/93 +f 93/2/93 109/2/109 110/2/110 +f 93/2/93 110/2/110 94/2/94 +f 94/2/94 110/2/110 111/2/111 +f 94/2/94 111/2/111 95/2/95 +f 95/2/95 111/2/111 112/2/112 +f 95/2/95 112/2/112 96/2/96 +f 96/2/96 112/2/112 113/2/113 +f 96/2/96 113/2/113 97/2/97 +f 97/2/97 113/2/113 98/2/98 +f 97/2/97 98/2/98 82/2/82 +f 114/2/114 99/2/99 98/2/98 +f 114/2/114 100/2/100 99/2/99 +f 114/2/114 101/2/101 100/2/100 +f 114/2/114 102/2/102 101/2/101 +f 114/2/114 103/2/103 102/2/102 +f 114/2/114 104/2/104 103/2/103 +f 114/2/114 105/2/105 104/2/104 +f 114/2/114 106/2/106 105/2/105 +f 114/2/114 107/2/107 106/2/106 +f 114/2/114 108/2/108 107/2/107 +f 114/2/114 109/2/109 108/2/108 +f 114/2/114 110/2/110 109/2/109 +f 114/2/114 111/2/111 110/2/110 +f 114/2/114 112/2/112 111/2/111 +f 114/2/114 113/2/113 112/2/112 +f 114/2/114 98/2/98 113/2/113 diff --git a/tests/data/texture_import/two_color_sphere/textures/two_color.jpg b/tests/data/texture_import/two_color_sphere/textures/two_color.jpg new file mode 100644 index 0000000000..7c4e3aa676 Binary files /dev/null and b/tests/data/texture_import/two_color_sphere/textures/two_color.jpg differ diff --git a/tests/fff_print/test_fill.cpp b/tests/fff_print/test_fill.cpp index 1fbedcda8f..b2d0ef9abe 100644 --- a/tests/fff_print/test_fill.cpp +++ b/tests/fff_print/test_fill.cpp @@ -37,7 +37,7 @@ #include "libslic3r/Fill/Fill.hpp" #include "libslic3r/Fill/FillAdaptive.hpp" #include "libslic3r/Fill/FillGyroid.hpp" -#include "libslic3r/Fill/FillTpmsAdaptive.hpp" +#include "libslic3r/Fill/AdaptiveInfillField.hpp" #include "libslic3r/Flow.hpp" #include "libslic3r/Geometry.hpp" #include "libslic3r/IntersectionPoints.hpp" @@ -1719,9 +1719,10 @@ TEST_CASE("Smoothing multiline lightning infill keeps its outlines connected", " const SparseInfillShape smooth = shape_for("100%"); REQUIRE(sharp.path_count > 0); - // Smoothing should leave the loop count about where it was; uncapping the smoothing reach, the - // regression this guards against, adds about 10%. - const size_t allowed_extra = sharp.path_count / 50; // 2% + // Smoothing should leave the path count about where it was; uncapping the smoothing reach, the + // regression this guards against, adds a quarter to a third. Outline ends next to each other are + // joined into one path, so a few loops more or less are a larger share of the count. + const size_t allowed_extra = sharp.path_count / 10; // 10% REQUIRE(smooth.path_count <= sharp.path_count + allowed_extra); // The outlines are still rounded. REQUIRE(smooth.point_count > sharp.point_count); @@ -2060,9 +2061,9 @@ TEST_CASE("Adaptive TPMS infill thins out from the surface to the interior densi Slic3r::Test::init_and_process_print({Slic3r::Test::cube(60)}, print, {{"sparse_infill_pattern", pattern}, {"sparse_infill_density", "25%"}, - {"tpms_adaptive", adaptive}, - {"tpms_interior_density", "5%"}, - {"tpms_adaptive_gradient", "linear"}, + {"adaptive_infill_mode", adaptive}, + {"adaptive_infill_interior_density", "5%"}, + {"adaptive_infill_gradient", "linear"}, {"layer_height", 0.4}, {"initial_layer_print_height", 0.4}}); }; @@ -2089,9 +2090,9 @@ TEST_CASE("Adaptive TPMS infill of a tall object is sparsest at its middle heigh Slic3r::Test::init_and_process_print({make_cube(30., 30., 90.)}, print, {{"sparse_infill_pattern", "tpmsd"}, {"sparse_infill_density", "25%"}, - {"tpms_adaptive", "lobes"}, - {"tpms_interior_density", "5%"}, - {"tpms_adaptive_gradient", "linear"}, + {"adaptive_infill_mode", "lobes"}, + {"adaptive_infill_interior_density", "5%"}, + {"adaptive_infill_gradient", "linear"}, {"layer_height", 0.4}, {"initial_layer_print_height", 0.4}}); const Polygons core = centered_square(5.); @@ -2111,9 +2112,9 @@ TEST_CASE("2D adaptive TPMS infill does not change along its axis", "[Fill]") Slic3r::Test::init_and_process_print({along_x ? make_cube(90., 30., 30.) : make_cube(30., 30., 90.)}, print, {{"sparse_infill_pattern", "gyroid"}, {"sparse_infill_density", "25%"}, - {"tpms_adaptive", adaptive}, - {"tpms_interior_density", "5%"}, - {"tpms_adaptive_gradient", "linear"}, + {"adaptive_infill_mode", adaptive}, + {"adaptive_infill_interior_density", "5%"}, + {"adaptive_infill_gradient", "linear"}, {"layer_height", 0.4}, {"initial_layer_print_height", 0.4}}); }; @@ -2147,9 +2148,9 @@ TEST_CASE("Adaptive TPMS shells and blend keep the whole deep core of a tall obj Slic3r::Test::init_and_process_print({make_cube(30., 30., 90.)}, print, {{"sparse_infill_pattern", "tpmsd"}, {"sparse_infill_density", "25%"}, - {"tpms_adaptive", adaptive}, - {"tpms_interior_density", "5%"}, - {"tpms_adaptive_gradient", "linear"}, + {"adaptive_infill_mode", adaptive}, + {"adaptive_infill_interior_density", "5%"}, + {"adaptive_infill_gradient", "linear"}, {"layer_height", 0.4}, {"initial_layer_print_height", 0.4}}); }; @@ -2179,9 +2180,9 @@ TEST_CASE("Adaptive TPMS infill is sparse at the center of both of two united sp Slic3r::Test::init_and_process_print({TriangleMesh(spheres)}, print, {{"sparse_infill_pattern", "gyroid"}, {"sparse_infill_density", "25%"}, - {"tpms_adaptive", adaptive}, - {"tpms_interior_density", "5%"}, - {"tpms_adaptive_gradient", "linear"}, + {"adaptive_infill_mode", adaptive}, + {"adaptive_infill_interior_density", "5%"}, + {"adaptive_infill_gradient", "linear"}, {"layer_height", 0.4}, {"initial_layer_print_height", 0.4}}); }; @@ -2209,9 +2210,9 @@ TEST_CASE("Adaptive TPMS gradients keep the surface density deeper in the order Slic3r::Test::init_and_process_print({Slic3r::Test::cube(40)}, print, {{"sparse_infill_pattern", "tpmsd"}, {"sparse_infill_density", "25%"}, - {"tpms_adaptive", "lobes"}, - {"tpms_interior_density", "5%"}, - {"tpms_adaptive_gradient", gradient}, + {"adaptive_infill_mode", "lobes"}, + {"adaptive_infill_interior_density", "5%"}, + {"adaptive_infill_gradient", gradient}, {"layer_height", 0.4}, {"initial_layer_print_height", 0.4}}); return sparse_infill_length(print, 0., 40., centered_square(20.)); @@ -2236,9 +2237,9 @@ TEST_CASE("Adaptive TPMS settings leave the infill unchanged when they do not ap {{"sparse_infill_pattern", pattern}, {"sparse_infill_density", "20%"}, {"layer_height", 0.2}, - {"tpms_adaptive", adaptive}, - {"tpms_interior_density", "40%"}, - {"tpms_adaptive_gradient", "exponential"}}); + {"adaptive_infill_mode", adaptive}, + {"adaptive_infill_interior_density", "40%"}, + {"adaptive_infill_gradient", "exponential"}}); const SparseInfillShape expected = sparse_infill_shape(reference); REQUIRE(expected.path_count > 0); CHECK(sparse_infill_shape(tuned).sequence == expected.sequence); @@ -2252,7 +2253,7 @@ TEST_CASE("Adaptive gyroid infill ignores the Z-buckling optimization", "[Fill]" {{"sparse_infill_pattern", "gyroid"}, {"sparse_infill_density", "10%"}, {"gyroid_optimized", gyroid_optimized}, - {"tpms_adaptive", "lobes"}, + {"adaptive_infill_mode", "lobes"}, {"layer_height", 0.2}}); return sparse_infill_shape(print); }; @@ -2268,10 +2269,10 @@ TEST_CASE("Adaptive TPMS infill of a region matches the infill of a larger regio // An 80 x 80 x 40 mm box around both regions, which share its radial field. const ExPolygons box{ExPolygon(Points{Point::new_scale(60., 20.), Point::new_scale(140., 20.), Point::new_scale(140., 100.), Point::new_scale(60., 100.)})}; - std::vector slices; + std::vector slices; for (int i = 0; i < 200; ++i) slices.push_back({0.2 * i, 0.2 * (i + 1), &box}); - const TpmsRadialField field(slices, get_extents(box), TpmsAdaptiveMode::Lobes, [] {}); + const AdaptiveInfillField field(slices, get_extents(box), AdaptiveInfillMode::Lobes, [] {}); auto circle = [](double radius) { Polygon contour = make_circle_num_segments(scale_(radius), 120); @@ -2285,13 +2286,13 @@ TEST_CASE("Adaptive TPMS infill of a region matches the infill of a larger regio filler->spacing = 0.45; filler->angle = float(M_PI / 7.); filler->z = z; - filler->tpms_radial_field = &field; + filler->adaptive_infill_field = &field; FillParams params; params.density = 0.2f; - params.tpms_adaptive = TpmsAdaptiveMode::Lobes; - params.tpms_interior_density = 0.05f; - params.tpms_adaptive_gradient = TpmsAdaptiveGradient::Linear; + params.adaptive_infill_mode = AdaptiveInfillMode::Lobes; + params.adaptive_infill_interior_density = 0.05f; + params.adaptive_infill_gradient = AdaptiveInfillGradient::Linear; params.layer_height = 0.2; params.dont_adjust = true; Surface surface(stInternal, expolygon); @@ -2328,8 +2329,8 @@ TEST_CASE("Adaptive TPMS anchors match the printed infill", "[Fill][InternalBrid Slic3r::Test::init_and_process_print({Slic3r::Test::cube(30)}, print, {{"sparse_infill_pattern", pattern}, {"sparse_infill_density", "25%"}, - {"tpms_adaptive", "lobes"}, - {"tpms_interior_density", "5%"}, + {"adaptive_infill_mode", "lobes"}, + {"adaptive_infill_interior_density", "5%"}, {"layer_height", 0.2}, {"initial_layer_print_height", 0.2}, {"resolution", 0.012}}); @@ -2353,3 +2354,66 @@ TEST_CASE("Adaptive TPMS anchors match the printed infill", "[Fill][InternalBrid max_distance = std::max(max_distance, printed_tree.distance_from_lines(point)); CHECK(unscale(max_distance) <= 0.012); } + +TEST_CASE("Infill lines whose ends are next to each other join into one path", "[Fill]") +{ + // An out-and-back pair 1 mm apart, as multiline infill leaves, and a line 19 mm away. + Polylines lines { Polyline(Point::new_scale(0., 0.), Point::new_scale(10., 0.)), Polyline(Point::new_scale(0., 1.), Point::new_scale(10., 1.)), + Polyline(Point::new_scale(0., 20.), Point::new_scale(10., 20.)) }; + join_close_ends(lines, scale_(1.5), true); + + REQUIRE(lines.size() == 2); + const auto joined = std::find_if(lines.begin(), lines.end(), [](const Polyline &pl) { return pl.size() == 4; }); + REQUIRE(joined != lines.end()); + // Both lines plus the 1 mm between them, joined at one end only, as joining the other end too would close a loop. + CHECK_THAT(unscale(joined->length()), Catch::Matchers::WithinAbs(21., 1e-6)); + CHECK(joined->first_point() != joined->last_point()); +} + +TEST_CASE("Joined infill lines print each line once", "[Fill]") +{ + // The middle line comes first and both of its ends get joined, so the group has to be walked from an outer line. + Polylines lines { Polyline(Point::new_scale(0., 0.), Point::new_scale(10., 0.)), Polyline(Point::new_scale(0., 1.), Point::new_scale(10., 1.)), + Polyline(Point::new_scale(10., -1.), Point::new_scale(0., -1.)) }; + join_close_ends(lines, scale_(1.5), true); + + REQUIRE(lines.size() == 1); + CHECK(lines.front().size() == 6); + // Three 10 mm lines and two 1 mm joins. + CHECK_THAT(unscale(lines.front().length()), Catch::Matchers::WithinAbs(32., 1e-6)); +} + +TEST_CASE("Infill line ends are not joined across another line", "[Fill]") +{ + // A pair 1 mm apart whose left ends have a third line running between them, which a join there would cross. + Polylines lines { Polyline(Point::new_scale(0., 0.), Point::new_scale(10., 0.)), Polyline(Point::new_scale(0., 1.), Point::new_scale(10., 1.)), + Polyline(Point::new_scale(-5., 0.5), Point::new_scale(5., 0.5)) }; + join_close_ends(lines, scale_(1.5), true); + + REQUIRE(lines.size() == 2); + const auto joined = std::find_if(lines.begin(), lines.end(), [](const Polyline &pl) { return pl.size() == 4; }); + REQUIRE(joined != lines.end()); + // Joined on the right, where nothing is in between, so the left ends stay open. + CHECK(joined->first_point().x() == 0); + CHECK(joined->last_point().x() == 0); +} + +TEST_CASE("Infill lines that cannot reverse join only end to start", "[Fill]") +{ + const Point a(Point::new_scale(0., 0.)), b(Point::new_scale(10., 0.)), c(Point::new_scale(10., 1.)), d(Point::new_scale(0., 1.)); + SECTION("Ends that would need a reversal stay apart") { + Polylines lines { Polyline(a, b), Polyline(d, c) }; + join_close_ends(lines, scale_(1.5), false); + CHECK(lines.size() == 2); + } + SECTION("The end of one line joins the start of the next, both kept in their direction") { + Polylines lines { Polyline(c, d), Polyline(a, b) }; + join_close_ends(lines, scale_(1.5), false); + REQUIRE(lines.size() == 1); + const Points &points = lines.front().points; + REQUIRE(points.size() == 4); + auto position = [&points](const Point &p) { return std::find(points.begin(), points.end(), p) - points.begin(); }; + CHECK(position(a) < position(b)); + CHECK(position(c) < position(d)); + } +} diff --git a/tests/fff_print/test_gcode.cpp b/tests/fff_print/test_gcode.cpp index 07091eddef..cb707ae3d4 100644 --- a/tests/fff_print/test_gcode.cpp +++ b/tests/fff_print/test_gcode.cpp @@ -51,6 +51,44 @@ TEST_CASE("Klipper object labels name each copy without the characters Klipper c } } +// The outline written to EXCLUDE_OBJECT_DEFINE is simplified with exclude_object_tolerance. A larger value must +// leave fewer points, which keeps the exclude-object array small on printers that stall while parsing it. +TEST_CASE("A larger exclude object tolerance writes fewer outline points", "[GCode]") +{ + const auto slice_with_tolerance = [](const std::string &tolerance) { + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_deserialize_strict({{"gcode_flavor", "klipper"}, {"exclude_object", "1"}, + {"exclude_object_tolerance", tolerance}}); + // Default facet angle (2 degrees): 180 hull points, well inside either tolerance. + return Test::slice({make_cylinder(20., 5.)}, config); + }; + // Points of the POLYGON=[[x,y],...] on the first EXCLUDE_OBJECT_DEFINE line. + const auto polygon_points = [](const std::string &gcode) { + const size_t define = gcode.find("EXCLUDE_OBJECT_DEFINE"); + REQUIRE(define != std::string::npos); + const size_t begin = gcode.find("POLYGON=", define); + REQUIRE(begin != std::string::npos); + const std::string polygon = gcode.substr(begin, gcode.find('\n', begin) - begin); + size_t points = 1; + for (size_t pos = polygon.find("],["); pos != std::string::npos; pos = polygon.find("],[", pos + 1)) + ++points; + return points; + }; + + const size_t fine = polygon_points(slice_with_tolerance("0.1")); + const size_t coarse = polygon_points(slice_with_tolerance("0.4")); + INFO("points at 0.1 mm: " << fine << ", at 0.4 mm: " << coarse); + CHECK(coarse >= 4); + CHECK(coarse < fine); +} + +// Existing profiles must keep writing the outlines they wrote when the tolerance was a constant 0.1 mm. +TEST_CASE("The exclude object tolerance defaults to the former fixed 0.1 mm", "[GCode]") +{ + CHECK_THAT(DynamicPrintConfig::full_print_config().opt_float("exclude_object_tolerance"), + Catch::Matchers::WithinAbs(0.1, 1e-9)); +} + // Firmwares read the compatibility header lines (Anycubic's GoKlipper heats the bed with // first_layer_bed_temperature), so they must describe the filament the plate prints, not filament 1. TEST_CASE("The G-code header names the first layer temperatures of the filament the plate prints", "[GCode]") diff --git a/tests/fff_print/test_gcode_timing.cpp b/tests/fff_print/test_gcode_timing.cpp index b3388340dc..cb1b2c4062 100644 --- a/tests/fff_print/test_gcode_timing.cpp +++ b/tests/fff_print/test_gcode_timing.cpp @@ -2,15 +2,18 @@ #include #include +#include #include #include #include "libslic3r/GCode/GCodeProcessor.hpp" #include "libslic3r/MultiNozzleUtils.hpp" #include "libslic3r/PrintConfig.hpp" +#include "libslic3r/libslic3r.h" #include "libslic3r/Utils.hpp" #include "test_utils.hpp" +#include #include #include #include @@ -30,6 +33,7 @@ namespace Slic3r { enum ExtrusionRole : uint8_t; } using namespace Slic3r; using Catch::Matchers::WithinAbs; +using Catch::Matchers::WithinRel; // Regression coverage for filament/tool-change time being folded into the first // pending motion block (an extrusion move) instead of the tool-change move, and @@ -570,6 +574,33 @@ double planned_corner_speed(GCodeFlavor flavor, double corner_velocity, double j } // namespace +TEST_CASE("Klipper extrusion ratio changes use its own corner velocity, not E jerk", "[GCodeTiming][JunctionDeviation]") +{ + const double jerk_e = GENERATE(0.0, 100.0); + auto config = make_junction_config(gcfKlipper, 5.0, 0.0); + config.machine_max_jerk_e.values = {jerk_e, jerk_e}; + GCodeProcessor processor; + run_processor(processor, config, + "G90\nM83\nSET_VELOCITY_LIMIT ACCEL=1000 MINIMUM_CRUISE_RATIO=0\n" + "G1 X20 Y60 F6000\nM400\n" + "G1 X60 Y60 E0.8 F6000\nG1 X100 Y60 E1.6 F6000\nM400\n"); + // A 0.02 -> 0.04 extrusion ratio change is capped at 1 / 0.02 = 50 mm/s. + REQUIRE_THAT(corner_speed(processor.get_result()), Catch::Matchers::WithinAbs(50.0, 0.01)); +} + +TEST_CASE("Klipper legacy smoothing stays absolute across acceleration changes", "[GCodeTiming][Klipper]") +{ + const bool modern = GENERATE(false, true); + auto config = make_junction_config(gcfKlipper, 5.0, 0.0); + const std::string gcode = std::string("G90\nSET_VELOCITY_LIMIT ACCEL=1000 ") + + (modern ? "MINIMUM_CRUISE_RATIO=0.75\n" : "ACCEL_TO_DECEL=250\n") + + "G1 X40 F30000\nM400\nM204 S2000\nG1 X0\nM400\n"; + GCodeProcessor processor; + run_processor(processor, config, gcode.c_str()); + const double expected = modern ? 0.5 + 0.25 * std::sqrt(2.0) : 0.95; + REQUIRE_THAT(processor.get_time(PrintEstimatedStatistics::ETimeMode::Normal), WithinAbs(expected, 1e-5)); +} + TEST_CASE("Klipper corners are planned with junction deviation derived from the square corner velocity", "[GCodeTiming][JunctionDeviation]") { @@ -669,3 +700,172 @@ TEST_CASE("How fast a corner is taken does not depend on how much is extruded th Catch::Matchers::WithinRel(marlin, 0.02)); } } + +// Expected times are Klipper's own planner math (klippy/toolhead.py). For a move from rest to rest, +// LookAheadQueue.flush() reduces to cruise_v2 = min(vmax^2, d * accel, d * pseudo_accel) with +// pseudo_accel = accel * (1 - minimum_cruise_ratio), and Move.set_junction() to a trapezoid at accel; +// a move too short to reach its speed still spends that ratio of its length cruising. +namespace { + +constexpr double klipper_accel = 1000.0; // make_junction_config's acceleration +constexpr double klipper_cruise_ratio = 0.5; +constexpr double klipper_pseudo_accel = klipper_accel * (1.0 - klipper_cruise_ratio); + +// Time of a move that starts and ends at rest. +double rest_to_rest_time(double distance, double max_speed, double accel, double pseudo_accel) +{ + const double cruise_v2 = std::min(sqr(max_speed), distance * pseudo_accel); + const double cruise = std::sqrt(cruise_v2); + return 2.0 * cruise / accel + (distance - cruise_v2 / accel) / cruise; +} + +// Every run states the cruise ratio rather than relying on the estimator's built-in default. +void run_klipper(GCodeProcessor& proc, const std::string& gcode, + const FullPrintConfig& config = make_junction_config(gcfKlipper, 5.0, 0.0)) +{ + const std::string limits = "SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=" + std::to_string(klipper_cruise_ratio) + "\n"; + run_processor(proc, config, (limits + gcode).c_str()); +} + +double klipper_time(const std::string& gcode, const FullPrintConfig& config = make_junction_config(gcfKlipper, 5.0, 0.0)) +{ + GCodeProcessor proc; + run_klipper(proc, gcode, config); + return proc.get_time(PrintEstimatedStatistics::ETimeMode::Normal); +} + +double time_after_retract(const GCodeProcessorResult& r) +{ + double t = 0.0; + bool after = false; + for (const auto& mv : r.moves) { + if (mv.type == EMoveType::Retract) + after = true; + else if (after) + t += mv.time[NORMAL]; + } + return t; +} + +} // namespace + +TEST_CASE("A straight line split into short segments is planned as one move", "[GCodeTiming][Klipper]") +{ + // 100 mm at 50 mm/s queues 2 s of motion, so the look-ahead flushes lazily part-way along the + // line; at 10 mm/s^2 the ramps span many segments and the cruise ratio caps the speed. + const int segments = GENERATE(1, 100, 1000); + std::ostringstream gcode; + gcode << "SET_VELOCITY_LIMIT ACCEL=10\n" << std::fixed << std::setprecision(3); + for (int i = 1; i <= segments; ++i) + gcode << "G1 X" << 100.0 * i / segments << " F3000\n"; + REQUIRE_THAT(klipper_time(gcode.str()), + WithinRel(rest_to_rest_time(100.0, 50.0, 10.0, 10.0 * (1.0 - klipper_cruise_ratio)), 1e-6)); +} + +TEST_CASE("Where the look-ahead flushes does not change the estimate", "[GCodeTiming][Klipper]") +{ + // A retraction stops the toolhead, so the zig-zag after it is planned on its own; the straight run + // before it only shifts where the queue flushes lazily (1 s of motion after a stop, then every 0.15 s). + auto zigzag_time = [](int run_moves) { + std::string gcode = "M83\nG91\n"; + for (int i = 0; i < run_moves; ++i) + gcode += "G1 X1 F6000\n"; + gcode += "G1 E-1 F2400\n"; + const char* moves[] = {"G1 X2 F3000\n", "G1 Y2 F9000\n", "G1 X2 F1200\n", "G1 Y-2 F9000\n"}; + for (int i = 0; i < 24; ++i) + gcode += moves[i % 4]; + GCodeProcessor proc; + run_klipper(proc, gcode); + return time_after_retract(proc.get_result()); + }; + const double reference = zigzag_time(0); + REQUIRE(reference > 0.0); + for (int run_moves : {30, 80, 105, 130}) { + INFO("run moves = " << run_moves); + REQUIRE_THAT(zigzag_time(run_moves), WithinAbs(reference, 1e-9)); + } +} + +TEST_CASE("A short move into a corner is limited by the centripetal term, not the corner velocity", + "[GCodeTiming][Klipper]") +{ + // A 50 mm/s square corner velocity allows 50 mm/s through the right angle; the 1 mm move into it + // allows sqrt(0.5 * 1 * 1000 * tan(45 deg)) = 22.4 mm/s (Move.calc_junction's move_centripetal_v2). + GCodeProcessor proc; + run_klipper(proc, "G90\nG1 X59 Y60 F6000\nM400\nG1 X60 Y60 F9000\nG1 X60 Y100 F9000\n", + make_junction_config(gcfKlipper, 50.0, 0.0)); + REQUIRE_THAT(corner_speed(proc.get_result()), WithinRel(std::sqrt(500.0), 1e-6)); +} + +TEST_CASE("A corner keeps the square corner velocity when the acceleration changes between its moves", + "[GCodeTiming][Klipper]") +{ + GCodeProcessor proc; + run_klipper(proc, "G90\nG1 X20 Y60 F6000\nM400\nG1 X60 Y60 F9000\nM204 S4000\nG1 X60 Y100 F9000\n"); + REQUIRE_THAT(corner_speed(proc.get_result()), WithinRel(5.0, 1e-6)); +} + +TEST_CASE("A retraction stops the toolhead and runs at the extruder's own limits", "[GCodeTiming][Klipper]") +{ + // An E acceleration of 0 is unset, and the retraction then uses the retract acceleration. + const auto [e_accel, retract_accel] = GENERATE(table({{20000.0, 20000.0}, {0.0, 3000.0}})); + auto config = make_junction_config(gcfKlipper, 5.0, 0.0); + config.machine_max_acceleration_e.values = {e_accel, e_accel}; + config.machine_max_acceleration_retracting.values = {3000.0, 3000.0}; + GCodeProcessor proc; + run_klipper(proc, "G90\nM83\nG1 X60 Y60 F9000\nG1 E-1 F2400\nG1 X100 Y60 F9000\n", config); + REQUIRE_THAT(corner_speed(proc.get_result()), WithinAbs(0.0, 1e-6)); + const double expected = rest_to_rest_time(std::sqrt(2.0) * 60.0, 150.0, klipper_accel, klipper_pseudo_accel) + + rest_to_rest_time(1.0, 40.0, retract_accel, std::min(retract_accel, klipper_pseudo_accel)) + + rest_to_rest_time(40.0, 150.0, klipper_accel, klipper_pseudo_accel); + REQUIRE_THAT(proc.get_time(PrintEstimatedStatistics::ETimeMode::Normal), WithinRel(expected, 1e-6)); +} + +TEST_CASE("Extruder limits apply to retractions, not to extrusion along a path", "[GCodeTiming][Klipper]") +{ + auto config = make_junction_config(gcfKlipper, 5.0, 0.0); + config.machine_max_speed_e.values = {10.0, 10.0}; + config.machine_max_acceleration_e.values = {10.0, 10.0}; + REQUIRE_THAT(klipper_time("M83\nG1 X40 E20 F30000\n", config), + WithinRel(rest_to_rest_time(40.0, 500.0, klipper_accel, klipper_pseudo_accel), 1e-6)); + REQUIRE_THAT(klipper_time("M83\nG1 E-1 F2400\n", config), + WithinRel(rest_to_rest_time(1.0, 10.0, 10.0, 10.0), 1e-6)); +} + +TEST_CASE("A Z move is limited by the Z axis speed and acceleration", "[GCodeTiming][Klipper]") +{ + auto config = make_junction_config(gcfKlipper, 5.0, 0.0); + config.machine_max_speed_z.values = {20.0, 20.0}; + config.machine_max_acceleration_z.values = {100.0, 100.0}; + REQUIRE_THAT(klipper_time("G1 Z10 F1200\n", config), + WithinRel(rest_to_rest_time(10.0, 20.0, 100.0, 100.0), 1e-6)); +} + +TEST_CASE("M204 sets the acceleration from S, or the smaller of P and T", "[GCodeTiming][Klipper]") +{ + const char* m204 = GENERATE("M204 S500", "M204 P500 T2000", "M204 P2000 T500"); + REQUIRE_THAT(klipper_time(std::string(m204) + "\nG1 X100 F30000\n"), + WithinRel(rest_to_rest_time(100.0, 500.0, 500.0, 500.0 * (1.0 - klipper_cruise_ratio)), 1e-6)); +} + +TEST_CASE("SET_VELOCITY_LIMIT applies every limit on the line and ignores the comment", "[GCodeTiming][Klipper]") +{ + REQUIRE_THAT(klipper_time("SET_VELOCITY_LIMIT VELOCITY=80 ACCEL=500 MINIMUM_CRUISE_RATIO=0.2 ; ACCEL=9999\n" + "G1 X20 F30000\n"), + WithinRel(rest_to_rest_time(20.0, 80.0, 500.0, 500.0 * (1.0 - 0.2)), 1e-6)); +} + +TEST_CASE("ACCEL_TO_DECEL is ignored on a line that also sets the minimum cruise ratio", "[GCodeTiming][Klipper]") +{ + // Klipper 0.13 prefers the cruise ratio and later releases no longer read ACCEL_TO_DECEL at all. + // ACCEL_TO_DECEL comes last, so applying the parameters in line order would let it win. + REQUIRE_THAT(klipper_time("SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=" + std::to_string(klipper_cruise_ratio) + + " ACCEL_TO_DECEL=100\nG1 X40 F30000\n"), + WithinRel(rest_to_rest_time(40.0, 500.0, klipper_accel, klipper_pseudo_accel), 1e-6)); +} + +TEST_CASE("M400 without a delay waits for the queue to drain", "[GCodeTiming][Klipper]") +{ + REQUIRE_THAT(klipper_time("G90\nG1 X40 F30000\nM400\nG1 X80\n"), + WithinRel(2.0 * rest_to_rest_time(40.0, 500.0, klipper_accel, klipper_pseudo_accel), 1e-6)); +} diff --git a/tests/fff_print/test_gcodewriter.cpp b/tests/fff_print/test_gcodewriter.cpp index d491527db6..6dad1251f9 100644 --- a/tests/fff_print/test_gcodewriter.cpp +++ b/tests/fff_print/test_gcodewriter.cpp @@ -514,7 +514,7 @@ TEST_CASE("Acceleration and velocity limit commands print their values in genera const Case c = GENERATE(values({ {gcfKlipper, Command::KlipperLimits, 2000000, 25. / 3., false, {"SET_VELOCITY_LIMIT ACCEL=2000000 ", "ACCEL_TO_DECEL=1e+06 ", "SQUARE_CORNER_VELOCITY=8.33333\n"}, {}}, - {gcfKlipper, Command::KlipperLimits, 12345, 0., false, {"ACCEL=12345 ", "ACCEL_TO_DECEL=6172.5\n"}, {"SQUARE_CORNER_VELOCITY"}}, + {gcfKlipper, Command::KlipperLimits, 12345, 0., false, {"ACCEL=12345 ", "ACCEL_TO_DECEL=6172.5 ", "MINIMUM_CRUISE_RATIO=0.5\n"}, {"SQUARE_CORNER_VELOCITY"}}, {gcfKlipper, Command::KlipperLimits, 0, 0.25, true, {"SQUARE_CORNER_VELOCITY=0.25 ", "; adjust VELOCITY_LIMIT"}, {"ACCEL"}}, {gcfKlipper, Command::Print, 3001, 0., true, {"ACCEL=3001 ", "ACCEL_TO_DECEL=1500.5 ", "; adjust ACCEL_TO_DECEL", "; adjust acceleration"}, {}}, {gcfMarlinFirmware, Command::Print, 2500, 0., false, {"M204 P2500\n"}, {}}, @@ -1272,6 +1272,41 @@ TEST_CASE("Custom G-code motion limits are restored before generated moves", "[G REQUIRE(gcode.find("M205 X8 Y8 ; adjust jerk", custom_gcode_pos) != std::string::npos); } +TEST_CASE("Klipper acceleration commands send accel_to_decel both as ACCEL_TO_DECEL and as the cruise ratio", "[GCodeWriter]") +{ + // Klipper 0.13 defines MINIMUM_CRUISE_RATIO = 1 - ACCEL_TO_DECEL / ACCEL; older releases read only the + // first parameter and current ones only the second, so both have to describe the same limit. + GCodeWriter writer; + writer.config.gcode_flavor.value = gcfKlipper; + writer.config.accel_to_decel_enable.value = true; + // The writer appends "; adjust ..." comments by default; keep them out so the line ends at the ratio. + struct CommentGuard + { + bool saved = GCodeWriter::full_gcode_comment; + ~CommentGuard() { GCodeWriter::full_gcode_comment = saved; } + } comment_guard; + GCodeWriter::full_gcode_comment = false; + + SECTION("a 25% factor") { + writer.config.accel_to_decel_factor.value = 25; + REQUIRE_THAT(writer.set_print_acceleration(2000), + Catch::Matchers::StartsWith("SET_VELOCITY_LIMIT ACCEL=2000 ACCEL_TO_DECEL=500 MINIMUM_CRUISE_RATIO=0.75")); + REQUIRE_THAT(writer.set_accel_and_jerk(3000, 0.0), + Catch::Matchers::StartsWith("SET_VELOCITY_LIMIT ACCEL=3000 ACCEL_TO_DECEL=750 MINIMUM_CRUISE_RATIO=0.75")); + } + SECTION("a 100% factor turns the cruise ratio off") { + writer.config.accel_to_decel_factor.value = 100; + REQUIRE_THAT(writer.set_print_acceleration(2000), + Catch::Matchers::StartsWith("SET_VELOCITY_LIMIT ACCEL=2000 ACCEL_TO_DECEL=2000 MINIMUM_CRUISE_RATIO=0\n")); + } + SECTION("neither is sent while the option is off") { + writer.config.accel_to_decel_enable.value = false; + const std::string line = writer.set_print_acceleration(2000); + REQUIRE_THAT(line, Catch::Matchers::StartsWith("SET_VELOCITY_LIMIT ACCEL=2000")); + REQUIRE_THAT(line, !Catch::Matchers::ContainsSubstring("ACCEL_TO_DECEL") && !Catch::Matchers::ContainsSubstring("MINIMUM_CRUISE_RATIO")); + } +} + // Regression test for the belt-printer "illegal gantry move at print start" bug. // // On a belt printer the layer-change z-hop is deferred (lazy_lift) and consumed diff --git a/tests/fff_print/test_wipe_tower.cpp b/tests/fff_print/test_wipe_tower.cpp index c094a656f7..78adb000be 100644 --- a/tests/fff_print/test_wipe_tower.cpp +++ b/tests/fff_print/test_wipe_tower.cpp @@ -202,6 +202,23 @@ TEST_CASE("The wipe tower's toolchange planner flush follows the gcode flavor", } } +TEST_CASE("The wipe tower sets Klipper's acceleration and accel_to_decel on one line", "[WipeTower]") +{ + // On separate lines, current Klipper finds nothing it reads on the ACCEL_TO_DECEL one and 0.13 + // derives the cruise ratio from the acceleration before the change. + DynamicPrintConfig config = wipe_tower_toolchange_config("klipper"); + // Type 2 towers leave the acceleration to the main G-code writer. + config.set_deserialize_strict({ { "wipe_tower_type", "type1" }, + { "accel_to_decel_enable", "1" }, { "accel_to_decel_factor", "50%" }, + { "default_acceleration", "1000" }, { "travel_acceleration", "2000" }, + { "machine_max_acceleration_extruding", "5000" } }); + const std::string tower = wipe_tower_regions(slice_with_prime_tower(config)); + REQUIRE_THAT(tower, Catch::Matchers::ContainsSubstring("SET_VELOCITY_LIMIT ACCEL=")); + CHECK_THAT(tower, Catch::Matchers::ContainsSubstring(" MINIMUM_CRUISE_RATIO=0.5\n")); + CHECK_THAT(tower, !Catch::Matchers::ContainsSubstring("SET_VELOCITY_LIMIT ACCEL_TO_DECEL") && + !Catch::Matchers::ContainsSubstring("M204")); +} + // What Print feeds the shared estimate. The libslic3r WipeTowerEstimate cases cannot see this: // they call the estimator directly. The estimate counts the filaments the print really uses, // so the two-filament shape gives the outer wall the second one. diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index 1f72f83478..6ab08f797f 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -1,5 +1,9 @@ get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) +# Observe the geometry backend's actual CGAL layout without duplicating its flags. +# This source is only added when the test suite is enabled. +target_sources(libslic3r_cgal PRIVATE texture_import_cgal.cpp) + add_executable(${_TEST_NAME}_tests ${_TEST_NAME}_tests.cpp test_3mf.cpp @@ -31,11 +35,12 @@ add_executable(${_TEST_NAME}_tests test_preset_diff.cpp test_vendor_cache.cpp test_preset_options.cpp + test_edge_grid.cpp test_elephant_foot_compensation.cpp test_fill_corner_smoothing.cpp test_filament_mixer.cpp test_fill_plane_path.cpp - test_fill_tpms_adaptive.cpp + test_adaptive_infill_field.cpp test_geometry.cpp test_imex_arrange.cpp test_imex_helpers.cpp @@ -67,10 +72,12 @@ add_executable(${_TEST_NAME}_tests test_wipe_path.cpp test_optimizers.cpp test_ordering_strategies.cpp + test_shortest_path.cpp # test_png_io.cpp test_indexed_triangle_set.cpp test_connected_bodies.cpp test_texture_displacement.cpp + test_texture_import.cpp test_instance_lock.cpp ../libnest2d/printer_parts.cpp ) diff --git a/tests/libslic3r/test_fill_tpms_adaptive.cpp b/tests/libslic3r/test_adaptive_infill_field.cpp similarity index 73% rename from tests/libslic3r/test_fill_tpms_adaptive.cpp rename to tests/libslic3r/test_adaptive_infill_field.cpp index d150ae8d7b..ab422bb95d 100644 --- a/tests/libslic3r/test_fill_tpms_adaptive.cpp +++ b/tests/libslic3r/test_adaptive_infill_field.cpp @@ -13,7 +13,7 @@ #include "libslic3r/BoundingBox.hpp" #include "libslic3r/ClipperUtils.hpp" #include "libslic3r/ExPolygon.hpp" -#include "libslic3r/Fill/FillTpmsAdaptive.hpp" +#include "libslic3r/Fill/AdaptiveInfillField.hpp" #include "libslic3r/Point.hpp" #include "libslic3r/Polygon.hpp" #include "libslic3r/PrintConfig.hpp" @@ -30,24 +30,24 @@ ExPolygon rectangle(double x0, double y0, double x1, double y1) } // The expolygons stacked in 0.2 mm layers from z = 0 to height. -TpmsRadialField radial_field(const ExPolygons &expolygons, double height, TpmsAdaptiveMode mode = TpmsAdaptiveMode::Lobes) +AdaptiveInfillField radial_field(const ExPolygons &expolygons, double height, AdaptiveInfillMode mode = AdaptiveInfillMode::Lobes) { - std::vector slices; + std::vector slices; for (int i = 0; 0.2 * (i + 1) < height + EPSILON; ++i) slices.push_back({0.2 * i, 0.2 * (i + 1), &expolygons}); - return TpmsRadialField(slices, get_extents(expolygons), mode, [] {}); + return AdaptiveInfillField(slices, get_extents(expolygons), mode, [] {}); } -double radial(const TpmsRadialField &field, const Vec3d &pt) +double radial(const AdaptiveInfillField &field, const Vec3d &pt) { - TpmsRadialField::Radials radials; + AdaptiveInfillField::Radials radials; field.radial(pt, radials); return radials[0].t; } -Vec3d center(const TpmsRadialField &field, const Vec3d &pt) +Vec3d center(const AdaptiveInfillField &field, const Vec3d &pt) { - TpmsRadialField::Radials radials; + AdaptiveInfillField::Radials radials; field.radial(pt, radials); return radials[0].center; } @@ -57,11 +57,11 @@ constexpr double Tolerance = 0.075; } // namespace -TEST_CASE("TPMS radial field is zero at the center of a cube and one at its faces", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field is zero at the center of a cube and one at its faces", "[AdaptiveInfillField]") { // A 20 mm cube, 10 mm from its center to every face. const ExPolygons square{rectangle(0., 0., 20., 20.)}; - const TpmsRadialField field = radial_field(square, 20.); + const AdaptiveInfillField field = radial_field(square, 20.); const Vec3d c = center(field, {10., 10., 10.}); CHECK_THAT(c.x(), WithinAbs(10., 0.5)); @@ -74,10 +74,10 @@ TEST_CASE("TPMS radial field is zero at the center of a cube and one at its face } } -TEST_CASE("TPMS radial field grows linearly from the center of a cube to its faces", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field grows linearly from the center of a cube to its faces", "[AdaptiveInfillField]") { const ExPolygons square{rectangle(0., 0., 20., 20.)}; - const TpmsRadialField field = radial_field(square, 20.); + const AdaptiveInfillField field = radial_field(square, 20.); for (double d = 1.; d < 10.; d += 1.) { CAPTURE(d); CHECK_THAT(radial(field, {10. - d, 10., 10.}), WithinAbs(d / 10., Tolerance)); @@ -85,11 +85,11 @@ TEST_CASE("TPMS radial field grows linearly from the center of a cube to its fac } } -TEST_CASE("TPMS radial field of a tall box is centered at its middle height", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field of a tall box is centered at its middle height", "[AdaptiveInfillField]") { // 20 x 20 x 60 mm: 10 mm from the center to the sides, 30 mm to the top and the bottom. const ExPolygons square{rectangle(0., 0., 20., 20.)}; - const TpmsRadialField field = radial_field(square, 60.); + const AdaptiveInfillField field = radial_field(square, 60.); CHECK_THAT(center(field, {10., 10., 45.}).z(), WithinAbs(30., 0.5)); CHECK_THAT(radial(field, {10., 10., 15.}), WithinAbs(0.5, Tolerance)); @@ -97,10 +97,10 @@ TEST_CASE("TPMS radial field of a tall box is centered at its middle height", "[ CHECK_THAT(radial(field, {15., 10., 30.}), WithinAbs(0.5, Tolerance)); } -TEST_CASE("TPMS radial field grades every body towards its own center", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field grades every body towards its own center", "[AdaptiveInfillField]") { const ExPolygons squares{rectangle(0., 0., 20., 20.), rectangle(30., 0., 50., 20.)}; - const TpmsRadialField field = radial_field(squares, 20.); + const AdaptiveInfillField field = radial_field(squares, 20.); CHECK_THAT(center(field, {5., 10., 10.}).x(), WithinAbs(10., 0.5)); CHECK_THAT(center(field, {45., 10., 10.}).x(), WithinAbs(40., 0.5)); @@ -108,20 +108,20 @@ TEST_CASE("TPMS radial field grades every body towards its own center", "[FillTp CHECK_THAT(radial(field, {30., 10., 10.}), WithinAbs(1., Tolerance)); } -TEST_CASE("TPMS radial field is beyond one outside of the object", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field is beyond one outside of the object", "[AdaptiveInfillField]") { const ExPolygons square{rectangle(0., 0., 20., 20.)}; - const TpmsRadialField field = radial_field(square, 20.); + const AdaptiveInfillField field = radial_field(square, 20.); CHECK(radial(field, {-5., 10., 10.}) > 1.); CHECK(radial(field, {10., 10., 30.}) > 1.); } -TEST_CASE("TPMS radial field grades every lobe of a body towards its own center", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field grades every lobe of a body towards its own center", "[AdaptiveInfillField]") { // Two spheres of 10 mm united, their centers 16 mm apart: the neck between them is 6 mm deep. const Vec3d c1(10., 10., 10.), c2(26., 10., 10.); std::vector layers; - std::vector slices; + std::vector slices; for (int i = 0; i < 100; ++i) { const double z = 0.2 * i + 0.1, r = std::sqrt(std::max(0., 100. - sqr(z - 10.))); Polygons circles; @@ -134,7 +134,7 @@ TEST_CASE("TPMS radial field grades every lobe of a body towards its own center" } for (int i = 0; i < 100; ++i) slices.push_back({0.2 * i, 0.2 * (i + 1), &layers[i]}); - const TpmsRadialField field(slices, get_extents(layers[50]), TpmsAdaptiveMode::Lobes, [] {}); + const AdaptiveInfillField field(slices, get_extents(layers[50]), AdaptiveInfillMode::Lobes, [] {}); for (const Vec3d &c : {c1, c2}) { CAPTURE(c.x()); @@ -143,7 +143,7 @@ TEST_CASE("TPMS radial field grades every lobe of a body towards its own center" CHECK_THAT(radial(field, c + Vec3d(0., 0., 9.5)), WithinAbs(1., 2. * Tolerance)); } // The side between the lobes is half way to the surface, where both patterns morph into each other. - TpmsRadialField::Radials radials; + AdaptiveInfillField::Radials radials; REQUIRE(field.radial(0.5 * (c1 + c2), radials) == 2); for (size_t i = 0; i < 2; ++i) { CHECK_THAT(radials[i].t, WithinAbs(0.5, 2. * Tolerance)); @@ -151,12 +151,12 @@ TEST_CASE("TPMS radial field grades every lobe of a body towards its own center" } } -TEST_CASE("TPMS radial field blends the lobes meeting at a junction continuously", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field blends the lobes meeting at a junction continuously", "[AdaptiveInfillField]") { // Three spheres of 10 mm united, their centers on a triangle of 16 mm sides: the necks meet at its middle. const std::array centers{Vec3d(10., 10., 10.), Vec3d(26., 10., 10.), Vec3d(18., 10. + 8. * std::sqrt(3.), 10.)}; std::vector layers; - std::vector slices; + std::vector slices; for (int i = 0; i < 100; ++i) { const double z = 0.2 * i + 0.1, r = std::sqrt(std::max(0., 100. - sqr(z - 10.))); Polygons circles; @@ -169,7 +169,7 @@ TEST_CASE("TPMS radial field blends the lobes meeting at a junction continuously } for (int i = 0; i < 100; ++i) slices.push_back({0.2 * i, 0.2 * (i + 1), &layers[i]}); - const TpmsRadialField field(slices, get_extents(layers[50]), TpmsAdaptiveMode::Lobes, [] {}); + const AdaptiveInfillField field(slices, get_extents(layers[50]), AdaptiveInfillMode::Lobes, [] {}); // Around the junction the nearest lobes swap, but the weight of every lobe changes smoothly. const Vec3d junction = (centers[0] + centers[1] + centers[2]) / 3.; @@ -179,7 +179,7 @@ TEST_CASE("TPMS radial field blends the lobes meeting at a junction continuously for (int row = 0; row <= 100; ++row) { std::array previous{}; for (int step = 0; step <= 200; ++step) { - TpmsRadialField::Radials radials; + AdaptiveInfillField::Radials radials; const size_t count = field.radial(junction + Vec3d(0.01 * step - 1., 0.02 * row - 1., 0.), radials); max_count = std::max(max_count, count); std::array weights{}; @@ -201,23 +201,23 @@ TEST_CASE("TPMS radial field blends the lobes meeting at a junction continuously CHECK(max_jump < 0.05); } -TEST_CASE("TPMS radial field is empty when the object is thinner than the grid cells", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field is empty when the object is thinner than the grid cells", "[AdaptiveInfillField]") { // A 0.3 mm square bar between the nodes of a grid sized by a 200 mm bounding box, with cells of 0.5 mm or more. const ExPolygons bar{rectangle(0.1, 0.1, 0.4, 0.4)}; - std::vector slices; + std::vector slices; for (int i = 0; i < 1000; ++i) slices.push_back({0.2 * i, 0.2 * (i + 1), &bar}); - const TpmsRadialField field(slices, BoundingBox(Point::new_scale(0., 0.), Point::new_scale(200., 200.)), - TpmsAdaptiveMode::Lobes, [] {}); + const AdaptiveInfillField field(slices, BoundingBox(Point::new_scale(0., 0.), Point::new_scale(200., 200.)), + AdaptiveInfillMode::Lobes, [] {}); CHECK(field.empty()); } -TEST_CASE("TPMS depth follows the distance to the surface relative to the deepest point", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill depth follows the distance to the surface relative to the deepest point", "[AdaptiveInfillField]") { // 20 x 20 x 60 mm: from 10 to 50 mm high the axis is 10 mm deep, as deep as the center. const ExPolygons square{rectangle(0., 0., 20., 20.)}; - const TpmsRadialField field = radial_field(square, 60., TpmsAdaptiveMode::SmoothBlend); + const AdaptiveInfillField field = radial_field(square, 60., AdaptiveInfillMode::SmoothBlend); for (double z : {15., 30., 45.}) { CAPTURE(z); CHECK_THAT(field.depth({10., 10., z}), WithinAbs(1., Tolerance)); @@ -227,18 +227,18 @@ TEST_CASE("TPMS depth follows the distance to the surface relative to the deepes CHECK_THAT(field.depth({0., 10., 30.}), WithinAbs(0., Tolerance)); } -TEST_CASE("TPMS radial field in Distance warp mode follows the distance to the surface", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field in Distance warp mode follows the distance to the surface", "[AdaptiveInfillField]") { // In a cube the depth falls linearly along every ray from the center, so Distance warp matches Lobes. const ExPolygons square{rectangle(0., 0., 20., 20.)}; - const TpmsRadialField cube = radial_field(square, 20., TpmsAdaptiveMode::DistanceWarp); + const AdaptiveInfillField cube = radial_field(square, 20., AdaptiveInfillMode::DistanceWarp); CHECK_THAT(radial(cube, {10., 10., 10.}), WithinAbs(0., Tolerance)); CHECK_THAT(radial(cube, {15., 10., 10.}), WithinAbs(0.5, Tolerance)); CHECK_THAT(radial(cube, {10., 10., 20.}), WithinAbs(1., Tolerance)); // 20 x 20 x 60 mm: Lobes grades the axis towards the top and the bottom, Distance warp keeps it deep. - const TpmsRadialField lobes = radial_field(square, 60.); - const TpmsRadialField warp = radial_field(square, 60., TpmsAdaptiveMode::DistanceWarp); + const AdaptiveInfillField lobes = radial_field(square, 60.); + const AdaptiveInfillField warp = radial_field(square, 60., AdaptiveInfillMode::DistanceWarp); for (double z : {15., 45.}) { CAPTURE(z); CHECK_THAT(radial(lobes, {10., 10., z}), WithinAbs(0.5, Tolerance)); @@ -247,12 +247,12 @@ TEST_CASE("TPMS radial field in Distance warp mode follows the distance to the s CHECK_THAT(radial(warp, {0., 10., 30.}), WithinAbs(1., Tolerance)); } -TEST_CASE("TPMS stepped shells split a layer by depth from the surface inwards", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill stepped shells split a layer by depth from the surface inwards", "[AdaptiveInfillField]") { // The middle layer of a 40 mm cube, 20 mm from its center to every face, 20% at the surface to 5% inside. const ExPolygons square{rectangle(0., 0., 40., 40.)}; - const TpmsRadialField field = radial_field(square, 40., TpmsAdaptiveMode::SteppedShells); - const std::vector shells = make_tpms_shells(field, square.front(), 20., 0.2f, 0.05f, TpmsAdaptiveGradient::Linear); + const AdaptiveInfillField field = radial_field(square, 40., AdaptiveInfillMode::SteppedShells); + const std::vector shells = make_adaptive_infill_shells(field, square.front(), 20., 0.2f, 0.05f, AdaptiveInfillGradient::Linear); REQUIRE(shells.size() == 5); CHECK_THAT(shells.front().density, WithinAbs(0.2, 1e-6)); CHECK_THAT(shells.back().density, WithinAbs(0.05, 1e-6)); @@ -270,11 +270,11 @@ TEST_CASE("TPMS stepped shells split a layer by depth from the surface inwards", [¢er](const ExPolygon &expolygon) { return expolygon.contains(center); })); } -TEST_CASE("TPMS radial field in 2D grades every section normal to the axis on its own", "[FillTpmsAdaptive]") +TEST_CASE("Adaptive infill field in 2D grades every section normal to the axis on its own", "[AdaptiveInfillField]") { // 20 x 20 x 60 mm: every section normal to Z is 10 mm from its center to the sides, whatever its height. const ExPolygons square{rectangle(0., 0., 20., 20.)}; - const TpmsRadialField normal_z = radial_field(square, 60., TpmsAdaptiveMode::NormalZ); + const AdaptiveInfillField normal_z = radial_field(square, 60., AdaptiveInfillMode::NormalZ); for (double z : {5., 30., 55.}) { CAPTURE(z); CHECK_THAT(radial(normal_z, {10., 10., z}), WithinAbs(0., Tolerance)); @@ -283,7 +283,7 @@ TEST_CASE("TPMS radial field in 2D grades every section normal to the axis on it } // Normal to X, the sections are 20 x 60 mm: 10 mm from the center to the sides, 30 mm to the top and the bottom. - const TpmsRadialField normal_x = radial_field(square, 60., TpmsAdaptiveMode::NormalX); + const AdaptiveInfillField normal_x = radial_field(square, 60., AdaptiveInfillMode::NormalX); for (double x : {3., 10., 17.}) { CAPTURE(x); CHECK_THAT(radial(normal_x, {x, 15., 30.}), WithinAbs(0.5, Tolerance)); diff --git a/tests/libslic3r/test_config.cpp b/tests/libslic3r/test_config.cpp index 20177bcc07..dcf808ab92 100644 --- a/tests/libslic3r/test_config.cpp +++ b/tests/libslic3r/test_config.cpp @@ -1263,6 +1263,55 @@ TEST_CASE("read_cli rejects an invalid scalar numeric value", "[Config]") { REQUIRE_FALSE(config.read_cli(3, argv, &extra, &keys)); } +TEST_CASE("A scalar option keeps its value when deserializing fails", "[Config]") { + using Catch::Matchers::WithinAbs; + + SECTION("float") { + ConfigOptionFloat opt(7.5); + REQUIRE_FALSE(opt.deserialize("abc")); + CHECK_THAT(opt.value, WithinAbs(7.5, 1e-9)); + } + SECTION("int") { + ConfigOptionInt opt(3); + REQUIRE_FALSE(opt.deserialize("abc")); + CHECK(opt.value == 3); + } + SECTION("percent") { + ConfigOptionPercent opt(40.); + REQUIRE_FALSE(opt.deserialize("abc%")); + CHECK_THAT(opt.value, WithinAbs(40., 1e-9)); + } + SECTION("float or percent") { + ConfigOptionFloatOrPercent opt(0.4, false); + REQUIRE_FALSE(opt.deserialize("abc%")); + CHECK_THAT(opt.value, WithinAbs(0.4, 1e-9)); + CHECK_FALSE(opt.percent); + } + SECTION("point") { + ConfigOptionPoint opt(Vec2d(1., 2.)); + REQUIRE_FALSE(opt.deserialize("5,abc")); + CHECK(opt.value == Vec2d(1., 2.)); + } + SECTION("point3") { + ConfigOptionPoint3 opt(Vec3d(1., 2., 3.)); + REQUIRE_FALSE(opt.deserialize("5,6,abc")); + CHECK(opt.value == Vec3d(1., 2., 3.)); + } +} + +TEST_CASE("A scalar option still takes a valid value", "[Config]") { + using Catch::Matchers::WithinAbs; + + ConfigOptionFloatOrPercent opt(0.4, false); + REQUIRE(opt.deserialize("50%")); + CHECK_THAT(opt.value, WithinAbs(50., 1e-9)); + CHECK(opt.percent); + + ConfigOptionPoint point; + REQUIRE(point.deserialize("3x4")); + CHECK(point.value == Vec2d(3., 4.)); +} + TEST_CASE("read_cli appends values when a vector option is repeated", "[Config]") { Slic3r::DynamicPrintConfig config; t_config_option_keys extra, keys; @@ -1457,6 +1506,19 @@ TEST_CASE("min_object_distance yields no floor when an FFF config lacks the opti } } +TEST_CASE("handle_legacy migrates the adaptive TPMS keys", "[Config]") { + ConfigSubstitutionContext ctxt(ForwardCompatibilitySubstitutionRule::Enable); + DynamicPrintConfig config; + config.set_deserialize("tpms_adaptive", "stepped_shells", ctxt); + config.set_deserialize("tpms_interior_density", "12%", ctxt); + config.set_deserialize("tpms_adaptive_gradient", "quadratic", ctxt); + + CHECK(config.opt_enum("adaptive_infill_mode") == AdaptiveInfillMode::SteppedShells); + CHECK(config.option("adaptive_infill_interior_density")->value == Catch::Approx(12.)); + CHECK(config.opt_enum("adaptive_infill_gradient") == AdaptiveInfillGradient::Quadratic); + CHECK(ctxt.substitutions.empty()); +} + TEST_CASE("handle_legacy migrates every IDEX/IQEX key testers already have", "[Config]") { // Three eras of saved profiles: the feature shipped as iXex (is_ixex + ixex_*), the clearance // pair was renamed to say what it measures, then the whole prefix became imex_. Driven from the @@ -1665,3 +1727,75 @@ TEST_CASE("Default options of enum lists get their definition's keys map", "[Con } CHECK(enum_lists > 0); } + +TEST_CASE("A disabled filament override survives the merge with a parent that sets it", "[Config][Variant]") +{ + std::set no_keys; + Slic3r::DynamicPrintConfig parent; + parent.set_deserialize_strict("filament_retract_before_wipe", "100%"); + parent.set_deserialize_strict("filament_ironing_flow", "15%"); + Slic3r::DynamicPrintConfig child; + child.set_deserialize_strict("filament_retract_before_wipe", "nil"); + child.set_deserialize_strict("filament_ironing_flow", "nil"); + parent.update_diff_values_to_child_config(child, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + CHECK(parent.opt_serialize("filament_retract_before_wipe") == "nil"); + CHECK(parent.opt_serialize("filament_ironing_flow") == "nil"); +} + +SCENARIO("A two-variant child's disabled override column is matched to the parent's variant by name", "[Config][Variant]") +{ + std::set no_keys; + GIVEN("A two-variant filament parent") { + Slic3r::DynamicPrintConfig parent; + parent.set_deserialize_strict("filament_extruder_variant", "Direct Drive Standard;Direct Drive High Flow"); + parent.set_deserialize_strict("filament_retract_before_wipe", "100%,100%"); + parent.set_deserialize_strict("filament_flow_ratio", "1,1"); + WHEN("the child disables the override on one variant and leaves a plain option nil on it") { + Slic3r::DynamicPrintConfig child; + child.set_deserialize_strict("filament_extruder_variant", "Direct Drive Standard;Direct Drive High Flow"); + child.set_deserialize_strict("filament_retract_before_wipe", "nil,100%"); + child.set_deserialize_strict("filament_flow_ratio", "nil,1.1"); + parent.update_diff_values_to_child_config(child, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + THEN("the override column is disabled while the plain option's nil column inherits") { + CHECK(parent.opt_serialize("filament_retract_before_wipe") == "nil,100%"); + CHECK(parent.opt_serialize("filament_flow_ratio") == "1,1.1"); + } + } + WHEN("the child lists the same variants in the other order") { + Slic3r::DynamicPrintConfig child; + child.set_deserialize_strict("filament_extruder_variant", "Direct Drive High Flow;Direct Drive Standard"); + child.set_deserialize_strict("filament_retract_before_wipe", "70%,nil"); + child.set_deserialize_strict("filament_flow_ratio", "1.1,nil"); + parent.update_diff_values_to_child_config(child, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + THEN("columns are matched by variant name, the disabled one included") { + CHECK(parent.opt_serialize("filament_retract_before_wipe") == "nil,70%"); + CHECK(parent.opt_serialize("filament_flow_ratio") == "1,1.1"); + } + } + WHEN("the child was saved with a single variant") { + Slic3r::DynamicPrintConfig child; + child.set_deserialize_strict("filament_extruder_variant", "Direct Drive Standard"); + child.set_deserialize_strict("filament_retract_before_wipe", "nil"); + parent.update_diff_values_to_child_config(child, "", "filament_extruder_variant", + Slic3r::filament_options_with_variant, no_keys); + THEN("its one value applies to every variant of that extruder, as slicing does") { + CHECK(parent.opt_serialize("filament_retract_before_wipe") == "nil,nil"); + } + } + } +} + +TEST_CASE("Every listed filament override is nullable", "[Config]") +{ + std::set overrides(Slic3r::filament_extruder_override_keys.begin(), Slic3r::filament_extruder_override_keys.end()); + overrides.insert({ "filament_retract_length_nc", "filament_ironing_flow", "filament_ironing_spacing", "filament_ironing_inset", "filament_ironing_speed" }); + for (const auto &[key, def] : Slic3r::print_config_def.options) { + INFO(key); + CHECK(Slic3r::is_filament_extruder_override_key(key) == (overrides.count(key) == 1)); + if (overrides.count(key) == 1) + CHECK(def.nullable); + } +} diff --git a/tests/libslic3r/test_edge_grid.cpp b/tests/libslic3r/test_edge_grid.cpp new file mode 100644 index 0000000000..406ea198cf --- /dev/null +++ b/tests/libslic3r/test_edge_grid.cpp @@ -0,0 +1,33 @@ +#include +#include +#include "catch2/matchers/catch_matchers.hpp" +#include "libslic3r/BoundingBox.hpp" +#include "libslic3r/EdgeGrid.hpp" +#include "libslic3r/Point.hpp" +#include "libslic3r/Polygon.hpp" +#include "libslic3r/libslic3r.h" + +using namespace Slic3r; + +TEST_CASE("EdgeGrid propagates signed distances across the interior and exterior", "[EdgeGrid][Regression]") +{ + const Polygon rectangle {Point::new_scale(-10., -12.), Point::new_scale(10., -12.), + Point::new_scale(10., 12.), Point::new_scale(-10., 12.)}; + const Polygons outlines {rectangle}; + const BoundingBox bounds(Point::new_scale(-30., -32.), Point::new_scale(30., 32.)); + EdgeGrid::Grid grid(bounds); + grid.create(outlines, scale_(1.)); + // Distances beyond the initialized edge band require backward propagation. + // With -fsanitize=shift, this also checks negative neighbour offsets. + grid.calculate_sdf(); + const auto distance = [&](double x, double y) { + return grid.signed_distance_bilinear(Point::new_scale(x, y)) * SCALING_FACTOR; + }; + REQUIRE_THAT(distance(0., 0.), Catch::Matchers::WithinAbs(-10., 0.01)); + for (double sign : {-1., 1.}) { + REQUIRE_THAT(distance(sign * 5., 0.), Catch::Matchers::WithinAbs(-5., 0.01)); + REQUIRE_THAT(distance(0., sign * 7.), Catch::Matchers::WithinAbs(-5., 0.01)); + REQUIRE_THAT(distance(sign * 20., 0.), Catch::Matchers::WithinAbs(10., 0.01)); + REQUIRE_THAT(distance(0., sign * 22.), Catch::Matchers::WithinAbs(10., 0.01)); + } +} diff --git a/tests/libslic3r/test_ordering_strategies.cpp b/tests/libslic3r/test_ordering_strategies.cpp index 97e5a83f60..f4df7e8b5e 100644 --- a/tests/libslic3r/test_ordering_strategies.cpp +++ b/tests/libslic3r/test_ordering_strategies.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -12,10 +13,13 @@ #include "libslic3r/Point.hpp" #include "libslic3r/GCode/OrderingStrategies.hpp" +#include "libslic3r/ShortestPath.hpp" #include "libslic3r/Geometry.hpp" #include #include +#include +#include #include using namespace Slic3r; @@ -304,3 +308,60 @@ TEST_CASE("snake_core handles three points", "[Snake]") { REQUIRE(is_permutation(p2, 3)); } + +// The shortest cycle through the points, trying every order. +static double shortest_cycle_length(const Points& centers) +{ + std::vector path(centers.size()); + std::iota(path.begin(), path.end(), 0); + double best = std::numeric_limits::max(); + do { + best = std::min(best, tsp_cycle_path_length(path, centers)); + } while (std::next_permutation(path.begin() + 1, path.end())); + return best; +} + +static Points random_centers(unsigned seed, size_t count) +{ + std::mt19937 rng(seed); + std::uniform_real_distribution<> coordinate(0., 200.); + Points centers; + for (size_t i = 0; i < count; ++i) { + // One draw per statement, as the evaluation order of function arguments is unspecified. + const double x = coordinate(rng); + const double y = coordinate(rng); + centers.emplace_back(Point::new_scale(x, y)); + } + return centers; +} + +TEST_CASE("tsp_exact_cycle finds the shortest cycle", "[TSPPostProcessing]") { + const size_t count = GENERATE(4, 5, 6, 8); + for (unsigned seed = 1; seed <= 10; ++seed) { + const Points centers = random_centers(seed, count); + const std::vector path = tsp_exact_cycle(centers); + REQUIRE(is_permutation(path, count)); + CHECK(euclidean_path_length(path, centers) <= shortest_cycle_length(centers) + SCALED_EPSILON); + } +} + +TEST_CASE("Default ordering tours up to ten points along the shortest cycle", "[TSPPostProcessing]") { + const bool from_start = GENERATE(false, true); + const Point start = Point::new_scale(-20., -20.); + for (unsigned seed = 1; seed <= 5; ++seed) { + const Points centers = random_centers(seed, 9); + const std::vector path = chain_points_with_postprocessing(centers, from_start ? &start : nullptr); + REQUIRE(is_permutation(path, centers.size())); + CHECK(euclidean_path_length(path, centers) <= shortest_cycle_length(centers) + SCALED_EPSILON); + } +} + +TEST_CASE("Default ordering of many points is never longer than the greedy cycle", "[TSPPostProcessing]") { + for (unsigned seed = 1; seed <= 10; ++seed) { + const Points centers = random_centers(seed, 150); + const std::vector path = chain_points_with_postprocessing(centers, nullptr); + REQUIRE(is_permutation(path, centers.size())); + CHECK(euclidean_path_length(path, centers) <= euclidean_path_length(chain_points(centers, nullptr), centers) + SCALED_EPSILON); + CHECK_FALSE(has_crossings(path, centers)); + } +} diff --git a/tests/libslic3r/test_preset_bundle_loading.cpp b/tests/libslic3r/test_preset_bundle_loading.cpp index 1b4927f08c..9053fc5496 100644 --- a/tests/libslic3r/test_preset_bundle_loading.cpp +++ b/tests/libslic3r/test_preset_bundle_loading.cpp @@ -8417,3 +8417,58 @@ TEST_CASE("An empty choice list in a G-code's settings keeps the value it had be CHECK(config.opt_serialize("nozzle_volume_type") == "High Flow"); CHECK(config.option("filament_multi_colour")->values.empty()); } + +TEST_CASE("A disabled filament override is saved and reloaded column by column", "[Preset][Bundle]") +{ + ScopedPresetDataDir data_dir; + PresetBundle bundle; + + Preset &parent = add_inmemory_preset(bundle.filaments, "Parent PLA @System"); + parent.config.option("filament_extruder_variant", true)->values = { "Direct Drive Standard", "Direct Drive High Flow" }; + parent.config.option("filament_retract_before_wipe", true)->values = { 100., 100. }; + parent.config.option("filament_flow_ratio", true)->values = { 1., 1. }; + + // The child turns the override off on the first variant and changes a plain option on the second. + const fs::path file = data_dir.tmp.path() / PRESET_FILAMENT_NAME / "Child PLA.json"; + Preset child(Preset::TYPE_FILAMENT, "Child PLA"); + child.file = file.string(); + child.version = *Semver::parse("1.0.0"); + child.config = parent.config; + child.config.option(BBL_JSON_KEY_INHERITS, true)->value = parent.name; + child.config.option("filament_retract_before_wipe")->set_at_to_nil(0); + child.config.option("filament_flow_ratio")->values = { 1., 1.1 }; + REQUIRE(child.save(&parent.config)); + + // On disk the override keeps every column, so its nil can only mean "off"; a plain + // option still stores nil for the columns that match the parent. + DynamicPrintConfig saved; + std::map key_values; + std::string reason; + saved.load_from_json(file.string(), ForwardCompatibilitySubstitutionRule::EnableSilent, key_values, reason); + REQUIRE(reason.empty()); + CHECK(saved.opt_serialize("filament_retract_before_wipe") == "nil,100%"); + CHECK(saved.opt_serialize("filament_flow_ratio") == "nil,1.1"); + + PresetsConfigSubstitutions substitutions; + bundle.filaments.load_presets(data_dir.tmp.path().string(), PRESET_FILAMENT_NAME, substitutions, + ForwardCompatibilitySubstitutionRule::EnableSilent); + const Preset *loaded = bundle.filaments.find_preset("Child PLA"); + REQUIRE(loaded != nullptr); + CHECK(loaded->config.opt_serialize("filament_retract_before_wipe") == "nil,100%"); + CHECK(loaded->config.opt_serialize("filament_flow_ratio") == "1,1.1"); +} + +TEST_CASE("The cloud diff force-emits a disabled override only where the cloud would fill a value in", "[Preset][Bundle]") +{ + PresetBundle bundle; + add_inmemory_preset(bundle.filaments, "Parent PLA @System"); + Preset &child = add_inmemory_preset(bundle.filaments, "Child PLA", "Parent PLA @System"); + // Every override is nil in both parent and child, so none is in the plain diff. + std::map key_values; + REQUIRE(bundle.filaments.get_differed_values_to_update(child, key_values) >= 0); + // Retract Before Wipe defaults to 100%: an absent key would come back as 100%, so nil is sent. + CHECK(key_values.count("filament_retract_before_wipe") == 1); + CHECK(key_values["filament_retract_before_wipe"] == "nil"); + // An ironing override defaults to nil: an absent key stays nil, so it is not sent. + CHECK(key_values.count("filament_ironing_flow") == 0); +} diff --git a/tests/libslic3r/test_shortest_path.cpp b/tests/libslic3r/test_shortest_path.cpp new file mode 100644 index 0000000000..e4b8c60ddc --- /dev/null +++ b/tests/libslic3r/test_shortest_path.cpp @@ -0,0 +1,202 @@ +#include +#include +#include +#include + +#include "libslic3r/ExtrusionEntity.hpp" +#include "libslic3r/ExtrusionEntityCollection.hpp" +#include "libslic3r/Point.hpp" +#include "libslic3r/Polyline.hpp" +#include "libslic3r/ShortestPath.hpp" +#include "libslic3r/libslic3r.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Slic3r; + +namespace { + +// Infill-like paths: lines of 1 to 30 mm scattered over a 100 mm square. The collection owns them, and entities hands +// them out as the raw pointers chain_and_reorder_extrusion_entities() reorders. +struct Paths +{ + ExtrusionEntityCollection collection; + std::vector entities; + + Paths(unsigned seed, size_t count, bool can_reverse) + { + std::mt19937 rng(seed); + std::uniform_real_distribution<> coordinate(0., 100.), length(1., 30.), angle(0., 2. * M_PI); + Polylines lines; + for (size_t i = 0; i < count; ++ i) { + // One draw per statement, as the evaluation order of function arguments is unspecified. + const double x = coordinate(rng); + const double y = coordinate(rng); + const double l = length(rng); + const double t = angle(rng); + const Vec2d a(x, y); + const Vec2d b = a + l * Vec2d(std::cos(t), std::sin(t)); + lines.emplace_back(Point::new_scale(a), Point::new_scale(b)); + } + extrusion_entities_append_paths(collection.entities, std::move(lines), erInternalInfill, 0.1, 0.45f, 0.2f, can_reverse); + entities = collection.entities; + } +}; + +double travel(const std::vector &entities, const Point &start) +{ + double length = 0.; + Point last = start; + for (const ExtrusionEntity *ee : entities) { + length += (ee->first_point() - last).cast().norm(); + last = ee->last_point(); + } + return length; +} + +// Travel of the chain that always goes on to the nearest free path end. +double nearest_next_travel(const std::vector &entities, bool can_reverse, const Point &from) +{ + std::vector taken(entities.size(), 0); + double length = 0.; + Point last = from; + for (size_t step = 0; step < entities.size(); ++ step) { + double best = std::numeric_limits::max(); + size_t best_idx = 0; + bool best_reversed = false; + for (size_t i = 0; i < entities.size(); ++ i) + for (const bool reversed : { false, true }) + if (! taken[i] && (can_reverse || ! reversed)) { + const double d = ((reversed ? entities[i]->last_point() : entities[i]->first_point()) - last).cast().norm(); + if (d < best) { + best = d; + best_idx = i; + best_reversed = reversed; + } + } + taken[best_idx] = 1; + length += best; + last = best_reversed ? entities[best_idx]->first_point() : entities[best_idx]->last_point(); + } + return length; +} + +// The shortest travel over every order and allowed reversal of the paths, from start. +double shortest_travel(const std::vector &entities, bool can_reverse, const Point &from) +{ + std::vector order(entities.size()); + std::iota(order.begin(), order.end(), 0); + double best = std::numeric_limits::max(); + do { + for (size_t mask = 0; mask < (size_t(1) << order.size()) && (can_reverse || mask == 0); ++ mask) { + double length = 0.; + Point last = from; + for (size_t k = 0; k < order.size(); ++ k) { + const ExtrusionEntity *ee = entities[order[k]]; + const bool reversed = (mask >> k & 1) != 0; + length += ((reversed ? ee->last_point() : ee->first_point()) - last).cast().norm(); + last = reversed ? ee->first_point() : ee->last_point(); + } + best = std::min(best, length); + } + } while (std::next_permutation(order.begin(), order.end())); + return best; +} + +const Point start = Point::new_scale(-10., -10.); + +} // namespace + +TEST_CASE("An improved infill chain is never longer than the greedy or nearest-next one and keeps every path", "[ShortestPath]") +{ + const size_t count = GENERATE(2, 3, 10, 60, 300); + const bool can_reverse = GENERATE(true, false); + double greedy_total = 0., improved_total = 0.; + for (unsigned seed = 1; seed <= 20; ++ seed) { + Paths greedy(seed, count, can_reverse), improved(seed, count, can_reverse); + const double nearest_travel = nearest_next_travel(improved.entities, can_reverse, start); + chain_and_reorder_extrusion_entities(greedy.entities, &start); + chain_and_reorder_extrusion_entities(improved.entities, start); + + std::vector sorted = improved.entities; + std::sort(sorted.begin(), sorted.end()); + REQUIRE(std::unique(sorted.begin(), sorted.end()) == sorted.end()); + REQUIRE(sorted.size() == count); + + const double greedy_travel = travel(greedy.entities, start), improved_travel = travel(improved.entities, start); + CHECK(improved_travel <= greedy_travel + SCALED_EPSILON); + CHECK(improved_travel <= nearest_travel + SCALED_EPSILON); + greedy_total += greedy_travel; + improved_total += improved_travel; + } + // Twenty random sets of ten or more paths always leave the greedy chain something to shorten. + if (count >= 10) + CHECK(improved_total < 0.95 * greedy_total); +} + +TEST_CASE("Improving an infill chain keeps the direction of paths that cannot reverse", "[ShortestPath]") +{ + Paths paths(7, 100, false); + std::map first_points; + for (const ExtrusionEntity *ee : paths.entities) + first_points.emplace(ee, ee->first_point()); + + chain_and_reorder_extrusion_entities(paths.entities, start); + + for (const ExtrusionEntity *ee : paths.entities) + CHECK(ee->first_point() == first_points.at(ee)); +} + +TEST_CASE("Chains of a few paths are the shortest possible", "[ShortestPath]") +{ + const size_t count = GENERATE(2, 3, 4, 5, 6); + const bool can_reverse = GENERATE(true, false); + for (unsigned seed = 1; seed <= 10; ++ seed) { + Paths paths(seed, count, can_reverse); + const double shortest = shortest_travel(paths.entities, can_reverse, start); + chain_and_reorder_extrusion_entities(paths.entities, start); + CHECK(travel(paths.entities, start) <= shortest + SCALED_EPSILON); + } +} + +TEST_CASE("The greedy chain of two to four paths is the shortest possible", "[ShortestPath]") +{ + const size_t count = GENERATE(2, 3, 4); + const bool can_reverse = GENERATE(true, false); + for (unsigned seed = 1; seed <= 10; ++ seed) { + Paths paths(seed, count, can_reverse); + const double shortest = shortest_travel(paths.entities, can_reverse, start); + chain_and_reorder_extrusion_entities(paths.entities, &start); + CHECK(travel(paths.entities, start) <= shortest + SCALED_EPSILON); + } +} + +TEST_CASE("A short chain need not start with the path nearest to its start", "[ShortestPath]") +{ + // The nearest end leads 10 mm away from the two other paths, so the shortest chain leaves that path for last. + const Point from = Point::new_scale(0., 0.); + for (const bool greedy : { false, true }) { + ExtrusionEntityCollection collection; + extrusion_entities_append_paths(collection.entities, + Polylines{ Polyline(Point::new_scale(-0.9, 0.), Point::new_scale(-10., 0.)), Polyline(Point::new_scale(1., 0.), Point::new_scale(2., 0.)), + Polyline(Point::new_scale(3., 1.), Point::new_scale(4., 1.)) }, + erInternalInfill, 0.1, 0.45f, 0.2f); + std::vector entities = collection.entities; + const double shortest = shortest_travel(entities, true, from); + if (greedy) + chain_and_reorder_extrusion_entities(entities, &from); + else + chain_and_reorder_extrusion_entities(entities, from); + CHECK(entities.back() == collection.entities.front()); + CHECK_THAT(travel(entities, from), Catch::Matchers::WithinAbs(shortest, SCALED_EPSILON)); + } +} diff --git a/tests/libslic3r/test_texture_import.cpp b/tests/libslic3r/test_texture_import.cpp new file mode 100644 index 0000000000..1106045847 --- /dev/null +++ b/tests/libslic3r/test_texture_import.cpp @@ -0,0 +1,76 @@ +#include +#include + +#include "libslic3r/Model.hpp" +#include "libslic3r/TexturePainting.hpp" +#include "texture_import_cgal.hpp" + +#include +#include +#include +#include + +namespace { + +void check_texture_import(const std::string& fixture) +{ + const std::string filename = std::string(TEST_DATA_DIR) + "/texture_import/" + fixture; + INFO(filename); + const Slic3r::Model model = Slic3r::Model::read_from_file(filename); + REQUIRE_FALSE(model.objects.empty()); + REQUIRE(model.texture_mesh); + const Slic3r::TexturedMesh& mesh = *model.texture_mesh; + + Slic3r::TexturePaintingSettings settings; + settings.target_colors_num = 0; // Match the dialog's initial automatic color count. + settings.smooth_weight = 0.5; + settings.mesh_repair_decision = Slic3r::TexturePaintingSettings::MeshRepairDecision::ImportWithoutRepair; + Slic3r::PaintedMesh painted; + // Follow the dialog worker's format-dependent path, including the boundary + // smoothing that needs a consistent CGAL Kd_tree layout across libraries. + if (!mesh.precomputed_face_colors.empty()) + REQUIRE(Slic3r::face_colors_to_painting(mesh, painted, settings)); + else + REQUIRE(Slic3r::texture_to_painting(mesh, painted, settings)); + + REQUIRE_FALSE(painted.indices.empty()); + REQUIRE(painted.face_colors.size() == painted.indices.size()); + REQUIRE(std::any_of(painted.face_colors.begin(), painted.face_colors.end(), + [](const auto& color) { return color[0] > color[2]; })); + REQUIRE(std::any_of(painted.face_colors.begin(), painted.face_colors.end(), + [](const auto& color) { return color[2] > color[0]; })); + + const std::vector> filament_colors{ + {1.f, 0.f, 0.f, 1.f}, {0.f, 0.f, 1.f, 1.f}}; + const auto matches = Slic3r::match_clusters_to_filaments( + painted.cluster_colors, filament_colors, {"Red PLA", "Blue PLA"}); + REQUIRE(matches.size() == painted.cluster_colors.size()); + REQUIRE(std::any_of(matches.begin(), matches.end(), + [](const auto& match) { return match.filament_index == 0; })); + REQUIRE(std::any_of(matches.begin(), matches.end(), + [](const auto& match) { return match.filament_index == 1; })); +} + +} // namespace + +TEST_CASE("Color-boundary smoothing shares its CGAL tree layout with the geometry backend", "[TextureImport][CGAL][Regression]") +{ + // An ABI mismatch need not crash every link of the importer. Compare the + // layouts directly so a lucky choice of inline symbols cannot mask it. + REQUIRE(sizeof(TextureImportTest::SearchTree) == TextureImportTest::backend_search_tree_size()); +} + +TEST_CASE("A JPEG textured GLB retains both colors through filament matching", "[TextureImport][Regression]") +{ + check_texture_import("two_color_jpeg.glb"); +} + +TEST_CASE("An OBJ preserves both MTL colors through filament matching", "[TextureImport][OBJ][Regression]") +{ + check_texture_import("two_color_sphere/test_two_color_sphere.obj"); +} + +TEST_CASE("An OBJ resolves its MTL and external JPEG through filament matching", "[TextureImport][OBJ][Regression]") +{ + check_texture_import("two_color_sphere/test_two_color_sphere_textured.obj"); +} diff --git a/tests/libslic3r/texture_import_cgal.cpp b/tests/libslic3r/texture_import_cgal.cpp new file mode 100644 index 0000000000..d3ee691d46 --- /dev/null +++ b/tests/libslic3r/texture_import_cgal.cpp @@ -0,0 +1,8 @@ +#include "texture_import_cgal.hpp" + +#include + +std::size_t TextureImportTest::backend_search_tree_size() +{ + return sizeof(SearchTree); +} diff --git a/tests/libslic3r/texture_import_cgal.hpp b/tests/libslic3r/texture_import_cgal.hpp new file mode 100644 index 0000000000..62b3211da4 --- /dev/null +++ b/tests/libslic3r/texture_import_cgal.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace TextureImportTest { + +// The distance-query tree used by ColorUtils.cpp's boundary smoothing. Its +// type name stays the same when CGAL changes its storage for TBB support. +using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel; +using Mesh = CGAL::Surface_mesh; +using Primitive = CGAL::AABB_face_graph_triangle_primitive; +using Traits = CGAL::AABB_traits_3; +using PointId = Traits::Point_and_primitive_id; +using SearchTraits = CGAL::Search_traits_adapter, Traits>; +using SearchTree = CGAL::Kd_tree; + +// Implemented inside the actual geometry target, using its private definitions. +std::size_t backend_search_tree_size(); + +} // namespace TextureImportTest diff --git a/tests/slic3rutils/CMakeLists.txt b/tests/slic3rutils/CMakeLists.txt index c9285b955e..727709f5b2 100644 --- a/tests/slic3rutils/CMakeLists.txt +++ b/tests/slic3rutils/CMakeLists.txt @@ -44,6 +44,7 @@ add_executable(${_TEST_NAME}_tests test_shortcuts.cpp test_texture_color_palette.cpp test_texture_island_view.cpp + test_timelapse_codecs.cpp test_file_url.cpp test_imgui_wrapper.cpp test_user_manager.cpp diff --git a/tests/slic3rutils/test_bambu_filament_ids.cpp b/tests/slic3rutils/test_bambu_filament_ids.cpp index 7d9e0df1f1..fef2c8a224 100644 --- a/tests/slic3rutils/test_bambu_filament_ids.cpp +++ b/tests/slic3rutils/test_bambu_filament_ids.cpp @@ -81,3 +81,24 @@ TEST_CASE("Payload rewrite covers nested trays, calibration lists and mapping in CHECK(BBLPrinterAgent::from_orca_payload("not json") == "not json"); CHECK(BBLPrinterAgent::from_orca_payload(R"({"print":{"command":"pushall"}})") == R"({"print":{"command":"pushall"}})"); } + +TEST_CASE("Payload rewrite covers the nozzle rack status and the auto nozzle mapping request", "[BambuFilamentIds]") +{ + const ScopedRepoResourcesDir repo_resources; + const std::string petg_hf = orca_id_of("GFG96"); + + const std::string rack_status = + R"({"print":{"device":{"nozzle":{"info":[{"id":16,"fila_id":"GFG96","color_m":"FFFFFFFF"},{"id":17,"fila_id":"P22f54c9"}]}}}})"; + json inbound = json::parse(BBLPrinterAgent::to_orca_payload(rack_status)); + CHECK(inbound["print"]["device"]["nozzle"]["info"][0]["fila_id"] == petg_hf); + CHECK(inbound["print"]["device"]["nozzle"]["info"][1]["fila_id"] == "P22f54c9"); // user id: untouched + + const std::string request = R"({"print":{"command":"get_auto_nozzle_mapping","ams_mapping":[65535,65024],)" + R"("fila_info":[{"id":2,"cate":")" + petg_hf + R"(","color":"FFFFFFFF"}],)" + R"("nozzle_info":[{"pos":16,"cate":")" + petg_hf + R"(","color":"FFFFFFFF"},{"pos":1,"cate":""}]}})"; + json outbound = json::parse(BBLPrinterAgent::from_orca_payload(request)); + CHECK(outbound["print"]["fila_info"][0]["cate"] == "GFG96"); + CHECK(outbound["print"]["nozzle_info"][0]["cate"] == "GFG96"); + CHECK(outbound["print"]["nozzle_info"][1]["cate"] == ""); // empty nozzle + CHECK(outbound["print"]["ams_mapping"] == json::parse("[65535,65024]")); +} diff --git a/tests/slic3rutils/test_moonraker_printer_agent.cpp b/tests/slic3rutils/test_moonraker_printer_agent.cpp index d3559cea1f..d3d61903fb 100644 --- a/tests/slic3rutils/test_moonraker_printer_agent.cpp +++ b/tests/slic3rutils/test_moonraker_printer_agent.cpp @@ -420,12 +420,13 @@ TEST_CASE("Moonraker discovery waits for a complete device identity", "[Moonrake agent.device_info.dev_id = "127.0.0.1:7125"; agent.device_info.dev_ip = agent.device_info.dev_id; agent.device_info.base_url = "http://127.0.0.1:7125"; + agent.device_info.model_name = "Test model"; agent.start_discovery(true, false); REQUIRE(announcements == 1); - REQUIRE(agent.fetch_count == 1); + REQUIRE(agent.fetch_count == 0); REQUIRE(announcement.at("dev_id") == agent.device_info.dev_id); REQUIRE(announcement.at("dev_ip") == agent.device_info.dev_ip); - REQUIRE(announcement.at("dev_name") == "Test printer"); + REQUIRE(announcement.at("dev_name") == "Test model"); } TEST_CASE("Stopping the status stream gives a silent printer no more than its timeouts", "[MoonrakerPrinterAgent][StatusStream]") diff --git a/tests/slic3rutils/test_orca_cloud_agent.cpp b/tests/slic3rutils/test_orca_cloud_agent.cpp index 99c4180a9a..f84a14ae76 100644 --- a/tests/slic3rutils/test_orca_cloud_agent.cpp +++ b/tests/slic3rutils/test_orca_cloud_agent.cpp @@ -8,11 +8,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -93,7 +92,9 @@ using boost::asio::ip::tcp; class LoopbackServer { public: - enum class Mode { Ok, Unavailable, Silent }; + // Session answers every request with the body given to set_session_body(), as the token endpoint + // does, after 200 ms so the client is still waiting when the test makes its next call. + enum class Mode { Ok, Unavailable, Silent, Session }; struct Request { @@ -115,6 +116,11 @@ public: std::string url() const { return "http://127.0.0.1:" + std::to_string(m_acceptor.local_endpoint().port()); } void set_mode(Mode mode) { m_mode = mode; } + void set_session_body(std::string body) + { + std::lock_guard lock(m_mutex); + m_session_body = std::move(body); + } bool wait_for_accepts(size_t count, std::chrono::milliseconds timeout) { @@ -174,13 +180,31 @@ private: const Mode mode = m_mode; if (mode == Mode::Silent) return; - const std::string_view response = mode == Mode::Ok ? - "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 11\r\nConnection: close\r\n\r\n{\"ok\":true}" : - "HTTP/1.1 503 Service Unavailable\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"; - boost::asio::async_write(connection->socket, boost::asio::buffer(response), - [connection](boost::system::error_code, size_t) { - boost::system::error_code ignored; - connection->socket.shutdown(tcp::socket::shutdown_both, ignored); + auto response = std::make_shared(); + if (mode == Mode::Session) { + std::lock_guard lock(m_mutex); + *response = "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: " + + std::to_string(m_session_body.size()) + "\r\nConnection: close\r\n\r\n" + m_session_body; + } else { + *response = mode == Mode::Ok ? + "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 11\r\nConnection: close\r\n\r\n{\"ok\":true}" : + "HTTP/1.1 503 Service Unavailable\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"; + } + auto write = [connection, response] { + boost::asio::async_write(connection->socket, boost::asio::buffer(*response), + [connection, response](boost::system::error_code, size_t) { + boost::system::error_code ignored; + connection->socket.shutdown(tcp::socket::shutdown_both, ignored); + }); + }; + if (mode != Mode::Session) { + write(); + return; + } + auto timer = std::make_shared(m_io, 200ms); + timer->async_wait([timer, write](boost::system::error_code ec) { + if (!ec) + write(); }); }); } @@ -194,30 +218,11 @@ private: std::condition_variable m_cv; std::vector m_requests; std::vector> m_connections; + std::string m_session_body; }; -// Sets an environment variable for the lifetime of the guard and restores the previous value. -class ScopedEnvVar -{ -public: - ScopedEnvVar(std::string name, const std::string& value) : m_name(std::move(name)) - { - if (const char* old = boost::nowide::getenv(m_name.c_str())) - m_previous = old; - boost::nowide::setenv(m_name.c_str(), value.c_str(), 1); - } - ~ScopedEnvVar() - { - if (m_previous) - boost::nowide::setenv(m_name.c_str(), m_previous->c_str(), 1); - else - boost::nowide::unsetenv(m_name.c_str()); - } - -private: - std::string m_name; - std::optional m_previous; -}; +// A JWT whose only claim is {"exp":4102444800} (2100-01-01); the agent reads nothing else from it. +constexpr const char* FAR_FUTURE_JWT = "eyJhbGciOiJub25lIn0.eyJleHAiOjQxMDI0NDQ4MDB9.sig"; // What the agent reported through its callbacks, recorded on whichever thread delivers it so the // assertions can run on the test thread. @@ -540,3 +545,24 @@ TEST_CASE_METHOD(HealthCheckFixture, "The health check does no token work", "[Or CHECK(agent->is_user_login()); CHECK(agent->get_access_token() == "test-token"); } + +TEST_CASE_METHOD(HealthCheckFixture, "A token request made while start() refreshes waits for it instead of refreshing again", "[OrcaCloudServiceAgent]") +{ + // A session saved by a previous run: start() refreshes it on its own thread. + agent->persist_user_secret(nlohmann::json{{"refresh_token", "stored-refresh-token"}, {"user_id", "test-user-id"}}.dump()); + const std::string access_token = FAR_FUTURE_JWT; + server.set_session_body(nlohmann::json{{"access_token", access_token}, + {"refresh_token", "rotated-refresh-token"}, + {"user_id", "test-user-id"}}.dump()); + server.set_mode(LoopbackServer::Mode::Session); + + REQUIRE(agent->start() == BAMBU_NETWORK_SUCCESS); + CHECK(agent->ensure_token_fresh("test")); + CHECK(agent->get_access_token() == access_token); + + size_t token_posts = 0; + for (const auto& request : server.requests()) + if (boost::starts_with(request.request_line, "POST /auth/v1/token")) + ++token_posts; + CHECK(token_posts == 1); +} diff --git a/tests/slic3rutils/test_plugin_audit.cpp b/tests/slic3rutils/test_plugin_audit.cpp index 8fecf9d4e7..040cf95993 100644 --- a/tests/slic3rutils/test_plugin_audit.cpp +++ b/tests/slic3rutils/test_plugin_audit.cpp @@ -1,23 +1,48 @@ #include #include +#include #include #include #include // GCODEVIEWER_APP_KEY, SLIC3R_APP_KEY (via libslic3r_version.h) #include +#include +#include +#include +#include +#include +#include #include // secret_constants::USER_SECRET_FILENAME +#include #include +#include +#include #include "libslic3r_version.h" #include "plugin_test_utils.hpp" +#include "test_utils.hpp" #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include using namespace Slic3r; namespace fs = boost::filesystem; +namespace py = pybind11; namespace { @@ -350,6 +375,16 @@ TEST_CASE("Plugin audit network permissions match by scheme and host", "[audit]" CHECK(PluginAuditManager::network_permission_matches(granted, "https://api.example.com:8443/upload")); } + SECTION("canonical host grants are broad but persisted full-URL grants stay exact") + { + const std::vector declared_host{"https://api.example.com"}; + CHECK(PluginAuditManager::network_permission_matches(declared_host, "https://api.example.com/v1")); + + const std::vector saved_url{"https://api.example.com/v1"}; + CHECK(PluginAuditManager::network_permission_matches(saved_url, "https://api.example.com/v1")); + CHECK_FALSE(PluginAuditManager::network_permission_matches(saved_url, "https://api.example.com/v2")); + } + SECTION("a URL target does not match a different host or a different scheme") { const std::vector granted{"https://api.example.com"}; @@ -403,40 +438,6 @@ TEST_CASE("Plugin audit network permissions match by scheme and host", "[audit]" } } -TEST_CASE("Plugin audit limits network ancestor approvals to resolved addresses", "[audit]") -{ - SECTION("IP literals are distinguished from hostnames and URLs") - { - CHECK(PluginAuditManager::is_ip_address_target("127.0.0.1")); - CHECK(PluginAuditManager::is_ip_address_target("93.184.216.34")); - CHECK(PluginAuditManager::is_ip_address_target("::1")); - CHECK(PluginAuditManager::is_ip_address_target("2001:db8::1")); - CHECK(PluginAuditManager::is_ip_address_target("[2001:db8::1]")); - - CHECK_FALSE(PluginAuditManager::is_ip_address_target("api.example.com")); - CHECK_FALSE(PluginAuditManager::is_ip_address_target("localhost")); - CHECK_FALSE(PluginAuditManager::is_ip_address_target("https://api.example.com")); - CHECK_FALSE(PluginAuditManager::is_ip_address_target("")); - } - - SECTION("a network approval is kept apart from the general call-site cascade") - { - PluginAuditManager& mgr = PluginAuditManager::instance(); - const std::string plugin_key = "plugin-audit-network-ancestor"; - const std::string other_key = "plugin-audit-network-ancestor-other"; - - mgr.record_approved_network_call_sites(plugin_key, {"frame:network"}); - mgr.record_approved_call_sites(plugin_key, {"frame:general"}); - - CHECK(mgr.has_approved_network_ancestor(plugin_key, {"frame:network"})); - CHECK_FALSE(mgr.has_approved_network_ancestor(plugin_key, {"frame:general"})); - CHECK_FALSE(mgr.has_approved_network_ancestor(other_key, {"frame:network"})); - - // The network approval must not leak into the general cascade used by other categories. - CHECK_FALSE(mgr.has_approved_ancestor(plugin_key, {"frame:network"})); - } -} - TEST_CASE("Plugin audit a scoped root can also be registered read-only", "[audit]") { ScopedDataDir data_dir_guard("plugin-audit-scoped-readonly"); @@ -461,3 +462,747 @@ TEST_CASE("Plugin audit a scoped root can also be registered read-only", "[audit CHECK_FALSE(mgr.check_open((readonly_dir / "vendor.json").string(), "w").allowed); } } + +// --------------------------------------------------------------------------- +// The audit hook, run in the embedded interpreter +// --------------------------------------------------------------------------- +// +// Each TEST_CASE runs in its own process (catch_discover_tests), so each brings the plugin system +// up with the audit hook installed, once, and shuts it down at the end. The tests loop over their +// cases instead of using SECTIONs, which would restart the interpreter for every section. + +namespace { + +// Discovered, never loaded: the hook only needs the plugin's root and its sidecar. +const char* const AUDIT_PLUGIN_SOURCE = R"PY(# /// script +# requires-python = ">=3.12" +# +# [tool.orcaslicer.plugin] +# name = "Audit Plugin" +# description = "Plugin audit hook fixture" +# author = "OrcaSlicer" +# version = "1.0" +# type = "script" +# /// +)PY"; + +// A third-party library, installed outside the stdlib and outside the plugin. +const char* const LIBRARY_SOURCE = R"PY( +import socket +import urllib.request + +def read_all(paths): + for path in paths: + with open(path) as f: + f.read() + +def connect_from_host(port): + socket.gethostname() + socket.create_connection(("127.0.0.1", port)).close() + +def fetch(url): + with urllib.request.urlopen(url) as response: + return response.read() + +def fetch_each(urls): + for url in urls: + yield fetch(url) + +class ReadingHandler(urllib.request.BaseHandler): + """Reads a file while each response is processed.""" + def __init__(self, path): + self.path = path + self.outcome = None + + def http_response(self, request, response): + try: + open(self.path).close() + self.outcome = "ok" + except PermissionError: + self.outcome = "denied" + return response +)PY"; + +// Test-side Python, run outside any plugin context: files outside every allowed root, a local +// HTTP server, the library, and every module the tests use imported up front, so that no import +// happens inside a plugin context. Code from exec() runs as "", which is not stdlib, so +// attempt() and fetch() stand in for plugin code. +const char* const AUDIT_SETUP = R"PY( +import http.client, http.server, os, pathlib, shutil, socket, subprocess, sys, tempfile, threading +import urllib.request, zipfile +if os.name != "nt": + import pty + +APPROVED = os.path.join(OUTSIDE, "approved.txt") +PRIVATE = os.path.join(OUTSIDE, "private.txt") +MISSING = os.path.join(OUTSIDE, "missing") +TREE = os.path.join(OUTSIDE, "tree") +TRUE_COMMAND = ["cmd", "/c", "exit 0"] if os.name == "nt" else ["true"] +for path in (APPROVED, PRIVATE): + with open(path, "w") as f: + f.write("x") +for sub in ("one", "two"): + os.makedirs(os.path.join(TREE, sub)) + with open(os.path.join(TREE, sub, "f.txt"), "w") as f: + f.write("x") + +LIBRARY = os.path.join(OUTSIDE, "library") +os.makedirs(LIBRARY) +with open(os.path.join(LIBRARY, "netlib.py"), "w") as f: + f.write(LIBRARY_SOURCE) +sys.path.insert(0, LIBRARY) +import netlib + +class Handler(http.server.BaseHTTPRequestHandler): + def do_GET(self): + if self.path == "/redirect": + self.send_response(302) + self.send_header("Location", URL_B) + body = b"" + else: + self.send_response(200) + body = b"ok" + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + + def log_message(self, *args): + pass + +server = http.server.ThreadingHTTPServer(("127.0.0.1", 0), Handler) +threading.Thread(target=server.serve_forever, daemon=True).start() +PORT = server.server_address[1] +BASE = "http://127.0.0.1:%d" % PORT +URL_A, URL_B, URL_REDIRECT = BASE + "/a", BASE + "/b", BASE + "/redirect" +urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler({}))) + +def fetch(url): + with urllib.request.urlopen(url) as response: + return response.read() + +fetch(URL_A) # urllib imports some modules on its first request + +def attempt(action): + try: + action() + return "ok" + except PermissionError: + return "denied" + +def spawn_checked(argv): + parent = os.getpid() + try: + return pty.spawn(argv) + finally: + if os.getpid() != parent: + os._exit(1) # a child whose exec was refused must not go on running the tests + +finalizer_outcomes = [] + +class TrackedRequest(urllib.request.Request): + def __del__(self): + finalizer_outcomes.append(attempt(lambda: open(PRIVATE).close())) +)PY"; + +struct Prompt +{ + std::string plugin; + std::string event; + std::vector targets; +}; + +// One line per prompt, "event: target ...", so a failed check shows every prompt. +std::string describe(const std::vector& prompts) +{ + std::string text; + for (const Prompt& prompt : prompts) { + text += prompt.event + ":"; + for (const std::string& target : prompt.targets) + text += " " + target; + text += "\n"; + } + return text; +} + +// The plugin system with the audit hook installed, and the permission dialog replaced by a +// recorder that answers with `approve`. Declare it first in a test, so it is destroyed last. +struct AuditHarness +{ + // Before initialize(): the interpreter creates {data_dir}/python/packages and {data_dir}/log. + // data_dir() is a global allowed root from then on, so the test files live in `outside`. + ScopedDataDir data{"plugin-audit-hook"}; + bool initialized = PluginManager::instance().initialize(); + ScopedTemporaryDir outside{"orca-plugin-audit-outside"}; + std::vector prompts; + std::function approve = [](const Prompt&) { return false; }; + + AuditHarness() + { + PluginAuditManager::set_permission_prompt_for_testing( + [this](const std::string& event, const std::vector& targets) { + prompts.push_back({PluginAuditManager::instance().current_plugin(), event, targets}); + return approve(prompts.back()); + }); + } + + ~AuditHarness() + { + PluginAuditManager::set_permission_prompt_for_testing(nullptr); + PluginManager::instance().shutdown(); + PythonInterpreter::instance().shutdown(); + } + + // Call before taking the GIL: discovery is not Python work. + void add_plugin(const std::string& key) + { + const fs::path root = data.plugins_dir() / key; + fs::create_directories(root); + std::ofstream((root / (key + ".py")).string(), std::ios::binary) << AUDIT_PLUGIN_SOURCE; + save_permissions(key, {}); + PluginManager::instance().discover_plugins(/*async=*/false, /*clear=*/true); + } + + // Grants as if saved in an earlier session. + void save_permissions(const std::string& key, const PluginPermissions& permissions) + { + PluginInstallState state; + state.installed_from = "local"; + state.installed_version = "1.0"; + state.plugin_name = key; + state.permissions = permissions; + REQUIRE(write_install_state(data.plugins_dir() / key, state)); + } + + PluginPermissions saved_permissions(const std::string& key) const + { + PluginInstallState state; + read_install_state(data.plugins_dir() / key, state); + return state.permissions; + } +}; + +// The test-side Python globals. Construct and destroy it with the GIL held; it stops the HTTP +// server before the interpreter shuts down. +struct PythonSide +{ + py::dict globals; + + explicit PythonSide(const AuditHarness& harness) + { + globals["OUTSIDE"] = harness.outside.path().string(); + globals["LIBRARY_SOURCE"] = LIBRARY_SOURCE; + exec(AUDIT_SETUP); + } + + // A Python error fails the test here, as text: an error_already_set left to propagate would + // outlive the interpreter the harness shuts down. + void exec(const char* code) + { + std::string error; + try { + py::exec(code, globals); + } catch (py::error_already_set& raised) { + error = raised.what(); + } + if (!error.empty()) + FAIL(error); + } + + ~PythonSide() + { + try { + globals["server"].attr("shutdown")(); + globals["server"].attr("server_close")(); + } catch (...) { + } + } + + std::string str(const char* name) const { return py::str(globals[name]).cast(); } + std::string eval(const char* expression) const { return py::str(py::eval(expression, globals)).cast(); } + std::vector strings(const char* name) const { return globals[name].cast>(); } + + // Runs `code` as `plugin_key`, as a trampoline call does: inside the caller's GIL, in an + // audit scope of its own. + void run_as(const std::string& plugin_key, const char* code) + { + ScopedPluginAuditContext audit(plugin_key); + exec(code); + } +}; + +PluginPermissions http_grants(std::vector urls) +{ + PluginPermissions permissions; + permissions.network_http = std::move(urls); + return permissions; +} + +const char* const PLUGIN = "AuditPlugin"; + +} // namespace + +TEST_CASE("A saved request grant covers the request's own connection in a later session", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + py::gil_scoped_acquire gil; + PythonSide python(harness); + harness.save_permissions(PLUGIN, http_grants({python.str("URL_A")})); + + python.run_as(PLUGIN, "outcome = attempt(lambda: fetch(URL_A))"); + + CHECK(python.str("outcome") == "ok"); + CHECK(describe(harness.prompts).empty()); +} + +TEST_CASE("A saved request grant does not cover another URL or a redirect", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + py::gil_scoped_acquire gil; + PythonSide python(harness); + harness.save_permissions(PLUGIN, http_grants({python.str("URL_A"), python.str("URL_REDIRECT")})); + + python.run_as(PLUGIN, R"PY( +outcomes = [attempt(lambda: fetch(url)) for url in (URL_A, URL_B, URL_REDIRECT)] +outcomes += [attempt(lambda: netlib.fetch(url)) for url in (URL_A, URL_B)] +outcomes.append(attempt(lambda: list(netlib.fetch_each([URL_A, URL_B])))) +)PY"); + + // The redirect target is asked for inside the approved redirecting request, and a library's + // wrapper or generator asks for the second URL as plain code does. + CHECK(python.strings("outcomes") == std::vector{"ok", "denied", "denied", "ok", "denied", "denied"}); + const std::string url_b = "urllib.Request: " + python.str("URL_B") + "\n"; + CHECK(describe(harness.prompts) == url_b + url_b + url_b + url_b); +} + +TEST_CASE("Code an approved operation calls back into is judged on its own", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + py::gil_scoped_acquire gil; + PythonSide python(harness); + python.exec(R"PY( +CALLBACK_COPY = os.path.join(OUTSIDE, "callback-copy") +handler = netlib.ReadingHandler(PRIVATE) +handler_opener = urllib.request.build_opener(urllib.request.ProxyHandler({}), handler) +walk_outcomes = [] +copy_outcomes = [] + +def on_walk_error(error): + walk_outcomes.append(attempt(lambda: open(PRIVATE).close())) + +def copy_file(source, destination): + copy_outcomes.append(attempt(lambda: open(PRIVATE).close())) +)PY"); + PluginPermissions permissions = http_grants({python.str("URL_A")}); + permissions.fs_read = {python.str("APPROVED"), python.str("MISSING")}; + permissions.fs_readwrite = {python.str("TREE"), python.str("CALLBACK_COPY")}; + harness.save_permissions(PLUGIN, permissions); + + // A library handler that urllib calls while the approved request runs, the plugin's own + // os.walk error callback and copytree copy function (called once per file), and a library + // loop over a saved file and an unsaved one. + python.run_as(PLUGIN, R"PY( +request_outcome = attempt(lambda: handler_opener.open(URL_A).read()) +for _ in os.walk(MISSING, onerror=on_walk_error): + pass +shutil.copytree(TREE, CALLBACK_COPY, copy_function=copy_file) +loop_outcome = attempt(lambda: netlib.read_all([APPROVED, PRIVATE])) +)PY"); + + CHECK(python.str("request_outcome") == "ok"); + CHECK(python.eval("handler.outcome") == "denied"); + CHECK(python.strings("walk_outcomes") == std::vector{"denied"}); + CHECK(python.strings("copy_outcomes") == std::vector{"denied", "denied"}); + CHECK(python.str("loop_outcome") == "denied"); + const std::string private_file = "open: " + python.str("PRIVATE") + "\n"; + CHECK(describe(harness.prompts) == private_file + private_file + private_file + private_file + private_file); +} + +TEST_CASE("A saved directory walk covers each directory it lists", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + py::gil_scoped_acquire gil; + PythonSide python(harness); + PluginPermissions permissions; + permissions.fs_read = {python.str("TREE"), python.str("APPROVED")}; + harness.save_permissions(PLUGIN, permissions); + + // The walk lists the tree's two subdirectories on later resumes, after the plugin's own + // audited reads in between. Abandoned walks leave frames whose generator is gone, which the + // next audited event lets go. + python.run_as(PLUGIN, R"PY( +walked = [] +for root, dirs, files in os.walk(TREE): + walked.append(root) + open(APPROVED).close() +globbed = list(pathlib.Path(TREE).glob("**/*")) + +abandoned = os.walk(TREE) +next(abandoned) +del abandoned +open(APPROVED).close() +for _ in pathlib.Path(TREE).glob("*"): + break +open(APPROVED).close() +)PY"); + + CHECK(py::len(python.globals["walked"]) == 3); + CHECK(py::len(python.globals["globbed"]) == 4); + CHECK(describe(harness.prompts).empty()); +} + +TEST_CASE("A freshly approved operation covers its nested events", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + py::gil_scoped_acquire gil; + PythonSide python(harness); + + struct Case + { + const char* prompts; + const char* code; + }; + // Each operation names targets no earlier one saved, so each is asked once. FsCreate and + // FsDelete grants are never saved, so those operations are asked every time. Only the + // expected prompts are approved, so a nested event left uncovered fails the operation. + std::vector cases = { + {"shutil.copytree", "shutil.copytree(TREE, os.path.join(OUTSIDE, 'copy'))"}, + {"shutil.copyfile", "shutil.copyfile(APPROVED, os.path.join(OUTSIDE, 'copied.txt'))"}, + {"shutil.move", "shutil.move(os.path.join(OUTSIDE, 'copied.txt'), os.path.join(OUTSIDE, 'moved.txt'))"}, + {"shutil.copystat", "shutil.copystat(os.path.join(TREE, 'one', 'f.txt'), PRIVATE)"}, + {"shutil.make_archive", "shutil.make_archive(os.path.join(OUTSIDE, 'archive'), 'zip', root_dir=TREE)"}, + {"shutil.unpack_archive", "shutil.unpack_archive(os.path.join(OUTSIDE, 'archive.zip'), os.path.join(OUTSIDE, 'unpacked'))"}, + {"pathlib.Path.glob", "list(pathlib.Path(TREE).glob('**/*'))"}, + {"subprocess.Popen", "subprocess.run(TRUE_COMMAND, check=True)"}, + {"tempfile.mkdtemp", "tempfile.mkdtemp(dir=OUTSIDE)"}, + {"tempfile.mkstemp", "os.close(tempfile.mkstemp(dir=OUTSIDE)[0])"}, + {"shutil.rmtree", "shutil.rmtree(os.path.join(OUTSIDE, 'copy'))"}, + // send() runs after connect() has returned, so its own grant is asked once. + {"http.client.connect\nhttp.client.send", + "connection = http.client.HTTPConnection('127.0.0.1', PORT)\n" + "connection.request('GET', '/a')\n" + "connection.getresponse().read()\n" + "connection.close()"}, + }; +#ifndef _WIN32 + cases.push_back({"os.fwalk", "list(os.fwalk(os.path.join(OUTSIDE, 'unpacked')))"}); + // The forked child's exec is covered by the spawn too: had it prompted, the child's own + // denial would end it with status 1. + cases.push_back({"pty.spawn", "spawn_status = spawn_checked(TRUE_COMMAND + ['spawned'])"}); +#endif + + for (const Case& operation : cases) { + INFO(operation.code); + const std::string expected = std::string(operation.prompts) + "\n"; + harness.approve = [&expected](const Prompt& prompt) { + return expected.find(prompt.event + "\n") != std::string::npos; + }; + harness.prompts.clear(); + python.run_as(PLUGIN, operation.code); + + std::string asked; + for (const Prompt& prompt : harness.prompts) + asked += (asked.empty() ? "" : "\n") + prompt.event; + CHECK(asked == operation.prompts); + } +#ifndef _WIN32 + CHECK(python.eval("spawn_status") == "0"); +#endif +} + +TEST_CASE("An event with no target is granted by name and remembered", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + harness.approve = [](const Prompt& prompt) { return prompt.event != "socket.sendto"; }; + py::gil_scoped_acquire gil; + PythonSide python(harness); + + python.run_as(PLUGIN, R"PY( +socket.socket().close() +udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sendto_outcome = attempt(lambda: udp.sendto(b"x", ("127.0.0.1", 9))) +udp.close() +)PY"); + + // The socket is asked for once, without a target to show; the datagram's address is a target. + CHECK(python.str("sendto_outcome") == "denied"); + CHECK(describe(harness.prompts) == "socket.__new__:\nsocket.sendto: ('127.0.0.1', 9)\n"); + CHECK(harness.saved_permissions(PLUGIN).events == std::vector{"Socket:socket.__new__"}); + CHECK(harness.saved_permissions(PLUGIN).network_socket.empty()); + + harness.prompts.clear(); + python.run_as(PLUGIN, "socket.socket().close()"); + CHECK(describe(harness.prompts).empty()); + + // A grant for an event with no target covers nothing else: a library's approved + // gethostname() does not carry the connection it makes next. + harness.approve = [](const Prompt& prompt) { return prompt.event == "socket.gethostname"; }; + python.run_as(PLUGIN, "connect_outcome = attempt(lambda: netlib.connect_from_host(PORT))"); + CHECK(python.str("connect_outcome") == "denied"); + CHECK(describe(harness.prompts) == "socket.gethostname:\nsocket.getaddrinfo: 127.0.0.1\n"); + harness.prompts.clear(); + harness.approve = [](const Prompt&) { return true; }; + +#ifndef _WIN32 + // sendmsg() without an address names no target either. + python.run_as(PLUGIN, R"PY( +left, right = socket.socketpair() +left.sendmsg([b"x"]) +left.close() +right.close() +)PY"); + CHECK(describe(harness.prompts) == "socket.sendmsg:\n"); + CHECK(harness.saved_permissions(PLUGIN).events == + std::vector{"Socket:socket.__new__", "Socket:socket.gethostname", "Socket:socket.sendmsg"}); +#endif +} + +TEST_CASE("An event grant does not stand in for another access or a target of the same name", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + harness.approve = [asked = 0](const Prompt&) mutable { return asked++ == 0; }; + py::gil_scoped_acquire gil; + PythonSide python(harness); + python.exec(R"PY( +READ_FD = os.open(APPROVED, os.O_RDONLY) +WRITE_FD = os.open(os.path.join(OUTSIDE, "scratch.txt"), os.O_WRONLY | os.O_CREAT) +)PY"); + + // A file descriptor has no path to show or save: a granted read of one is not a write. + python.run_as(PLUGIN, R"PY( +fd_outcomes = [attempt(lambda: open(READ_FD, "r", closefd=False).close()), + attempt(lambda: open(WRITE_FD, "w", closefd=False).close())] +)PY"); + CHECK(python.strings("fd_outcomes") == std::vector{"ok", "denied"}); + CHECK(describe(harness.prompts) == "open:\nopen:\n"); + CHECK(harness.saved_permissions(PLUGIN).events == std::vector{"FsRead:open"}); + + // A saved os.fork event grant is not an os.system command named "os.fork". + PluginPermissions permissions; + permissions.events = {"FsRead:open", "ProcessCreate:os.fork"}; + harness.save_permissions(PLUGIN, permissions); + harness.prompts.clear(); + python.run_as(PLUGIN, R"PY( +reread_outcome = attempt(lambda: open(READ_FD, "r", closefd=False).close()) +system_outcome = attempt(lambda: os.system("os.fork")) +os.close(READ_FD) +os.close(WRITE_FD) +)PY"); + CHECK(python.str("reread_outcome") == "ok"); + CHECK(python.str("system_outcome") == "denied"); + REQUIRE(harness.prompts.size() == 1); + CHECK(harness.prompts.front().event == "os.system"); + CHECK(harness.saved_permissions(PLUGIN).process.empty()); +} + +TEST_CASE("A finalizer run when a root frame is let go is judged as the plugin without a prompt", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin(PLUGIN); + py::gil_scoped_acquire gil; + PythonSide python(harness); + PluginPermissions permissions = http_grants({python.str("URL_A")}); + permissions.fs_read = {python.str("APPROVED")}; + harness.save_permissions(PLUGIN, permissions); + PluginAuditManager& mgr = PluginAuditManager::instance(); + + // Once the request returns, only its held frame keeps the request object alive, and the + // request's finalizer reads a file the plugin was never granted. + python.run_as(PLUGIN, "fetch(TrackedRequest(URL_A))"); + CHECK(python.strings("finalizer_outcomes") == std::vector{"denied"}); // at scope end + CHECK(describe(harness.prompts).empty()); + CHECK_FALSE(mgr.audit_denial_pending()); + + python.exec("finalizer_outcomes.clear()"); + python.run_as(PLUGIN, R"PY( +fetch(TrackedRequest(URL_A)) +open(APPROVED).close() # the next event lets the returned request's frame go +outcomes_before_scope_end = list(finalizer_outcomes) +)PY"); + CHECK(python.strings("outcomes_before_scope_end") == std::vector{"denied"}); + CHECK(describe(harness.prompts).empty()); + + // The finalizer's denial during another event's decision leaves that event's own denial intact. + python.exec("finalizer_outcomes.clear()"); + python.run_as(PLUGIN, R"PY( +fetch(TrackedRequest(URL_A)) +try: + os.listdir(OUTSIDE) + outer_error = "" +except PermissionError as error: + outer_error = str(error) +)PY"); + CHECK(python.strings("finalizer_outcomes") == std::vector{"denied"}); + CHECK_THAT(python.str("outer_error"), Catch::Matchers::ContainsSubstring("os.listdir")); + CHECK(describe(harness.prompts) == "os.listdir: " + python.str("OUTSIDE") + "\n"); + AuditViolation violation; + REQUIRE(mgr.last_violation(violation)); + CHECK(violation.event_name == "os.listdir"); + CHECK(mgr.audit_denial_pending()); +} + +TEST_CASE("A nested audit scope does not see the outer scope's running operations", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.add_plugin("PluginA"); + harness.add_plugin("PluginB"); + py::gil_scoped_acquire gil; + PythonSide python(harness); + PluginPermissions permissions; + permissions.fs_read = {python.str("TREE")}; + harness.save_permissions("PluginA", permissions); + + { + // Two walks plugin A started and suspended after listing the tree itself. + ScopedPluginAuditContext plugin_a("PluginA"); + python.exec("first = os.walk(TREE)\nnext(first)\nsecond = os.walk(TREE)\nnext(second)"); + { + // Plugin B resuming one of them is asked for each subdirectory, as plugin B. + ScopedPluginAuditContext plugin_b("PluginB"); + python.exec("listed_by_b = len(list(first))"); + } + // Back in plugin A's scope, its walks are covered again. + python.exec("listed_by_a = len(list(second))"); + } + + CHECK(python.globals["listed_by_b"].cast() == 0); + CHECK(python.globals["listed_by_a"].cast() == 2); + REQUIRE(harness.prompts.size() == 2); + for (const Prompt& prompt : harness.prompts) { + CHECK(prompt.plugin == "PluginB"); + CHECK(prompt.event == "os.scandir"); + } +} + +TEST_CASE("Root frames held when a capability call ends are let go with the GIL, as the plugin", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + harness.approve = [](const Prompt& prompt) { return prompt.event == "os.walk"; }; + py::gil_scoped_acquire gil; + PythonSide python(harness); + (void) PythonPluginBridge::instance(); // force the embedded module registration into the binary + python.globals["orca"] = py::module_::import("orca"); + + // walk_and_drop() leaves a returned walk's frame held by the audit scope alone, with a marker + // in its locals; the frame is let go when the capability call ends, which runs the marker's + // finalizer. + python.exec(R"PY( +class Marker: + def __init__(self, action=None): + self.action = action + def __del__(self): + finalized.append(self.action() if self.action else "ran") + +finalized = [] + +def walk_and_drop(marker): + walker = os.walk(TREE, onerror=marker) + next(walker) + del walker + +class ConfigCapability(orca.PythonPluginBase): + def get_name(self): + return "config_cap" + def get_default_config(self): + walk_and_drop(Marker()) + return {"finalized_during_call": len(finalized)} + def has_config_ui(self): + walker = os.walk(TREE, onerror=Marker(lambda: attempt(lambda: open(PRIVATE).close()))) + next(walker) + attempt(lambda: os.listdir(OUTSIDE)) # denied: the trampoline clears the plugin key + del walker # the walk's frame is now held by the audit scope alone + raise RuntimeError("the capability fails after a denial") + +class TicketAgent(orca.printer_agent.PrinterAgentBase): + def get_name(self): + return "ticket_agent" + def request_bind_ticket(self): + walk_and_drop(Marker()) + return (0, "ticket") +)PY"); + + py::object config_instance = python.globals["ConfigCapability"](); + auto config_cap = config_instance.cast>(); + config_cap->set_audit_plugin_key("GilPlugin"); + config_cap->set_resolved_identity("config_cap", PluginCapabilityType::Script); + + py::object agent_instance = python.globals["TicketAgent"](); + auto agent_cap = agent_instance.cast>(); + agent_cap->set_audit_plugin_key("GilPlugin"); + agent_cap->set_resolved_identity("ticket_agent", PluginCapabilityType::PrinterConnection); + auto agent = std::dynamic_pointer_cast(agent_cap); + REQUIRE(agent); + + // A host call arrives without the GIL; both calls take it before their audit scope. + nlohmann::json config; + int ticket_result = -1; + std::string ticket; + { + py::gil_scoped_release released; + config = config_cap->get_default_config(); + ticket_result = agent->request_bind_ticket(&ticket); + } + CHECK(config == nlohmann::json{{"finalized_during_call", 0}}); + CHECK(ticket_result == 0); + CHECK(ticket == "ticket"); + CHECK(python.strings("finalized") == std::vector{"ran", "ran"}); + + // On the trampoline's denial path the frame is let go as the plugin, though the ambient key + // was cleared: the finalizer's read is audited and denied without a prompt. + python.exec("finalized.clear()"); + harness.prompts.clear(); + CHECK_THROWS_AS(config_cap->has_config_ui(), py::error_already_set); + CHECK(python.strings("finalized") == std::vector{"denied"}); + CHECK(describe(harness.prompts) == "os.walk: " + python.str("TREE") + "\nos.listdir: " + python.str("OUTSIDE") + "\n"); +} + +TEST_CASE("Stdlib code is recognized through a symlinked Python home", "[audit][Python]") +{ + AuditHarness harness; + if (!harness.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + py::gil_scoped_acquire gil; + + const py::dict paths = py::module_::import("sysconfig").attr("get_paths")(); + const fs::path stdlib = py::str(paths["stdlib"]).cast(); + const fs::path purelib = py::str(paths["purelib"]).cast(); + const fs::path link = harness.outside.path() / "linked-stdlib"; + boost::system::error_code ec; + fs::create_directory_symlink(stdlib, link, ec); + if (ec) + SKIP("Cannot create a directory symlink here: " + ec.message()); + + CHECK(PluginAuditManager::is_stdlib_file((stdlib / "os.py").string())); + CHECK(PluginAuditManager::is_stdlib_file((link / "urllib" / "request.py").string())); + CHECK(PluginAuditManager::is_stdlib_file("")); + CHECK_FALSE(PluginAuditManager::is_stdlib_file((purelib / "requests" / "api.py").string())); + CHECK_FALSE(PluginAuditManager::is_stdlib_file((link / "site-packages" / "requests" / "api.py").string())); + CHECK_FALSE(PluginAuditManager::is_stdlib_file((harness.outside.path() / "plugin.py").string())); + CHECK_FALSE(PluginAuditManager::is_stdlib_file("")); +} diff --git a/tests/slic3rutils/test_plugin_lifecycle.cpp b/tests/slic3rutils/test_plugin_lifecycle.cpp index 498935c2f6..0a1a94dcef 100644 --- a/tests/slic3rutils/test_plugin_lifecycle.cpp +++ b/tests/slic3rutils/test_plugin_lifecycle.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -14,8 +15,13 @@ #include #include #include "plugin_test_utils.hpp" +#include "test_utils.hpp" #include +#include +#include +#include +#include #include #include @@ -1068,3 +1074,43 @@ TEST_CASE("Unloading a plugin that is not loaded is a no-op", "[PluginLifecycle] CHECK(manager.unload_plugin("No_Such_Plugin")); CHECK_FALSE(manager.is_plugin_loaded("No_Such_Plugin")); } + +namespace { + +// CA certificates in the default client context, as a plugin's urllib or http.client request would +// verify against. +int default_context_ca_count() +{ + pybind11::gil_scoped_acquire gil; + const pybind11::dict stats = pybind11::module_::import("ssl").attr("create_default_context")().attr("cert_store_stats")(); + return stats["x509_ca"].cast(); +} + +} // namespace + +TEST_CASE("The bundled Python trusts the system CA certificates", "[PluginLifecycle][Python]") +{ + // The app runs this before plugins load; on Linux it is what points OpenSSL at the distro bundle. + Http::tls_global_init(); + ScopedPluginManager plugin_system; + if (!plugin_system.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + + CHECK(default_context_ca_count() > 0); +} + +#ifndef _WIN32 // Windows adds its system store whatever SSL_CERT_FILE names. +TEST_CASE("SSL_CERT_FILE still overrides the bundled Python's default CA certificates", "[PluginLifecycle][Python]") +{ + // Existing but empty: Linux's CurlGlobalInit replaces an SSL_CERT_FILE that names a missing file. + ScopedTemporaryFile empty_bundle(".pem"); + std::ofstream(empty_bundle.string()).close(); + ScopedEnvVar ssl_cert_file{"SSL_CERT_FILE", empty_bundle.string()}; + + ScopedPluginManager plugin_system; + if (!plugin_system.initialized) + SKIP("Bundled Python interpreter unavailable: " + PythonInterpreter::instance().last_error()); + + CHECK(default_context_ca_count() == 0); +} +#endif diff --git a/tests/slic3rutils/test_timelapse_codecs.cpp b/tests/slic3rutils/test_timelapse_codecs.cpp new file mode 100644 index 0000000000..ede43d8f06 --- /dev/null +++ b/tests/slic3rutils/test_timelapse_codecs.cpp @@ -0,0 +1,100 @@ +#include + +#include "libslic3r/GCode/ThumbnailData.hpp" +#include "libslic3r/GCode/Thumbnails.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/TexturePainting.hpp" +#include "slic3r/GUI/AVVideoDecoder.hpp" +#include "slic3r/GUI/Printer/BambuTunnel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +TEST_CASE("JPEG texture decoding coexists with thumbnails and video frames", "[TimelapseCodecs][Regression]") +{ +#if defined(__linux__) + if (!std::getenv("DISPLAY") && !std::getenv("WAYLAND_DISPLAY")) + SKIP("This integration test needs a display (for example, xvfb-run)."); +#endif + wxInitializer init; + REQUIRE(init.IsOk()); + wxInitAllImageHandlers(); + + // Generate a JPEG through the same encoder used for G-code thumbnails. + constexpr int width = 160, height = 90, iterations = 1000; + Slic3r::ThumbnailData thumbnail; + thumbnail.set(width, height); + for (std::size_t i = 0; i < thumbnail.pixels.size(); i += 4) { + thumbnail.pixels[i] = 180; + thumbnail.pixels[i + 1] = 70; + thumbnail.pixels[i + 2] = 30; + thumbnail.pixels[i + 3] = 255; + } + const auto jpeg = Slic3r::GCodeThumbnails::compress_thumbnail(thumbnail, Slic3r::GCodeThumbnailsFormat::JPG); + REQUIRE(jpeg); + REQUIRE(jpeg->size > 0); + const auto* bytes = static_cast(jpeg->data); + Slic3r::TextureImage texture; + texture.width = texture.height = -1; + texture.data.assign(bytes, bytes + jpeg->size); + + std::atomic texture_ok{true}; + std::thread texture_worker([&] { + for (int i = 0; i < iterations; ++i) { + std::vector pixels; + int decoded_width = 0, decoded_height = 0; + if (!Slic3r::decode_texture_to_pixels(texture, pixels, decoded_width, decoded_height) || + decoded_width != width || decoded_height != height || pixels.size() != width * height * 3) + texture_ok = false; + } + }); + + // PrinterFileSystem decodes timelapse thumbnails with wxImage. Do not + // assert until the worker is joined: Catch assertions can unwind the scope. + bool thumbnails_ok = true; + for (int i = 0; i < iterations; ++i) { + wxMemoryInputStream stream(jpeg->data, jpeg->size); + wxImage image(stream, "image/jpeg"); + if (!image.IsOk() || image.GetWidth() != width || image.GetHeight() != height || + image.GetRed(width / 2, height / 2) < 170 || image.GetGreen(width / 2, height / 2) > 80) + thumbnails_ok = false; + } + texture_worker.join(); + REQUIRE(texture_ok.load()); + REQUIRE(thumbnails_ok); + + // Exercise Orca's real FFmpeg decoder and its platform display conversion. + AVVideoDecoder decoder; + Bambu_StreamInfo info{}; + info.type = VIDE; + info.sub_type = MJPG; + info.format_type = video_jpeg; + REQUIRE(decoder.open(info) == 0); + Bambu_Sample sample{}; + sample.size = static_cast(jpeg->size); + sample.buffer = bytes; + for (int i = 0; i < iterations; ++i) { + REQUIRE(decoder.decode(sample) == 0); + wxImage image; + REQUIRE(decoder.toWxImage(image, wxSize(width, height))); + REQUIRE(image.IsOk()); + REQUIRE(image.GetWidth() == width); + REQUIRE(image.GetHeight() == height); +#ifdef _WIN32 + // Playback uses this raw 32-bit bitmap conversion only on Windows. + wxBitmap bitmap; + REQUIRE(decoder.toWxBitmap(bitmap, wxSize(width, height))); + REQUIRE(bitmap.IsOk()); + REQUIRE(bitmap.GetWidth() == width); + REQUIRE(bitmap.GetHeight() == height); +#endif + } +} diff --git a/tests/test_utils.hpp b/tests/test_utils.hpp index d0817ce128..cffa05cb15 100644 --- a/tests/test_utils.hpp +++ b/tests/test_utils.hpp @@ -10,10 +10,13 @@ #include #include +#include #include #include +#include #include +#include #if defined(WIN32) || defined(_WIN32) #define PATH_SEPARATOR R"(\)" @@ -197,4 +200,27 @@ private: boost::filesystem::path m_previous; }; +// Sets an environment variable for the lifetime of the guard and restores the previous value. +class ScopedEnvVar +{ +public: + ScopedEnvVar(std::string name, const std::string& value) : m_name(std::move(name)) + { + if (const char* old = boost::nowide::getenv(m_name.c_str())) + m_previous = old; + boost::nowide::setenv(m_name.c_str(), value.c_str(), 1); + } + ~ScopedEnvVar() + { + if (m_previous) + boost::nowide::setenv(m_name.c_str(), m_previous->c_str(), 1); + else + boost::nowide::unsetenv(m_name.c_str()); + } + +private: + std::string m_name; + std::optional m_previous; +}; + #endif // SLIC3R_TEST_UTILS