Update boundaryFalloff setting and add panel subsection heading styles

- Changed boundaryFalloff from 1 to 0 in main.js settings for improved behavior.
- Added new languages ES, PT, JP
This commit is contained in:
CNCKitchen
2026-04-06 20:16:19 +02:00
parent 6fa12b6b7f
commit 16f5e96751
4 changed files with 622 additions and 22 deletions
+14 -11
View File
@@ -163,11 +163,6 @@
<div id="amplitude-warning" class="amplitude-warning hidden" data-i18n="warnings.amplitudeOverlap"> <div id="amplitude-warning" class="amplitude-warning hidden" data-i18n="warnings.amplitudeOverlap">
⚠ Amplitude exceeds 10% of the smallest model dimension — geometry overlaps may occur in the exported STL. ⚠ Amplitude exceeds 10% of the smallest model dimension — geometry overlaps may occur in the exported STL.
</div> </div>
<div class="form-row slider-row">
<label for="boundary-falloff" data-i18n="labels.boundaryFalloff" data-i18n-title="tooltips.boundaryFalloff" title="Gradually reduces displacement to zero near masked boundaries, preventing triangle overlap where textured and non-textured regions meet.">Boundary Falloff ⓘ</label>
<input type="range" id="boundary-falloff" min="0" max="10" step="0.1" value="1" />
<input type="number" class="val" id="boundary-falloff-val" value="1" min="0" max="10" step="0.1" />
</div>
<div class="form-row"> <div class="form-row">
<label class="checkbox-label" for="symmetric-displacement" <label class="checkbox-label" for="symmetric-displacement"
data-i18n-title="tooltips.symmetricDisplacement" data-i18n-title="tooltips.symmetricDisplacement"
@@ -228,9 +223,19 @@
</div> </div>
</section> </section>
<!-- Mask Angles --> <!-- Masking -->
<section class="panel-section"> <section class="panel-section">
<h2 data-i18n="sections.maskAngles" data-i18n-title="tooltips.maskAngles" title="0° = no masking. Surfaces within this angle of horizontal will not be textured.">Mask Angles ⓘ</h2> <h2 data-i18n="sections.masking">Masking</h2>
<!-- Boundary Falloff (applies to both angle and surface masking) -->
<div class="form-row slider-row">
<label for="boundary-falloff" data-i18n="labels.boundaryFalloff" data-i18n-title="tooltips.boundaryFalloff" title="Gradually reduces displacement to zero near masked boundaries, preventing triangle overlap where textured and non-textured regions meet.">Smooth Mask ⓘ</label>
<input type="range" id="boundary-falloff" min="0" max="10" step="0.1" value="0" />
<input type="number" class="val" id="boundary-falloff-val" value="0" min="0" max="10" step="0.1" />
</div>
<!-- By Angle -->
<h3 class="panel-subsection-heading" data-i18n="sections.maskAngles" data-i18n-title="tooltips.maskAngles" title="0° = no masking. Surfaces within this angle of horizontal will not be textured.">By Angle ⓘ</h3>
<div class="form-row slider-row"> <div class="form-row slider-row">
<label for="bottom-angle-limit" data-i18n="labels.bottomFaces" data-i18n-title="tooltips.bottomFaces" title="Suppress texture on downward-facing surfaces within this angle of horizontal">Bottom faces</label> <label for="bottom-angle-limit" data-i18n="labels.bottomFaces" data-i18n-title="tooltips.bottomFaces" title="Suppress texture on downward-facing surfaces within this angle of horizontal">Bottom faces</label>
<input type="range" id="bottom-angle-limit" min="0" max="90" step="1" value="5" /> <input type="range" id="bottom-angle-limit" min="0" max="90" step="1" value="5" />
@@ -241,11 +246,9 @@
<input type="range" id="top-angle-limit" min="0" max="90" step="1" value="0" /> <input type="range" id="top-angle-limit" min="0" max="90" step="1" value="0" />
<input type="number" class="val" id="top-angle-limit-val" value="0" min="0" max="90" step="1" /> <input type="number" class="val" id="top-angle-limit-val" value="0" min="0" max="90" step="1" />
</div> </div>
</section>
<!-- Surface Exclusions --> <!-- By Surface -->
<section class="panel-section"> <h3 class="panel-subsection-heading" id="excl-section-heading" data-i18n="sections.surfaceMasking" data-i18n-title="tooltips.surfaceMasking" title="Mask surfaces to control which areas receive displacement.">By Surface ⓘ</h3>
<h2 id="excl-section-heading" data-i18n="sections.surfaceMasking" data-i18n-title="tooltips.surfaceMasking" title="Mask surfaces to control which areas receive displacement.">Surface Masking ⓘ</h2>
<p id="excl-hint" class="excl-hint" style="display:none"></p> <p id="excl-hint" class="excl-hint" style="display:none"></p>
<!-- Mode toggle: Exclude / Include Only --> <!-- Mode toggle: Exclude / Include Only -->
+598 -10
View File
@@ -61,8 +61,11 @@ export const TRANSLATIONS = {
'labels.capAngle': 'Cap Angle \u24d8', 'labels.capAngle': 'Cap Angle \u24d8',
'tooltips.capAngle': 'Angle (in degrees) from vertical at which the top/bottom cap projection kicks in. Smaller values limit cap projection to nearly flat faces.', 'tooltips.capAngle': 'Angle (in degrees) from vertical at which the top/bottom cap projection kicks in. Smaller values limit cap projection to nearly flat faces.',
// Masking parent section
'sections.masking': 'Masking',
// Mask angles section // Mask angles section
'sections.maskAngles': 'Mask Angles \u24d8', 'sections.maskAngles': 'By Angle \u24d8',
'tooltips.maskAngles': '0° = no masking. Surfaces within this angle of horizontal will not be textured.', 'tooltips.maskAngles': '0° = no masking. Surfaces within this angle of horizontal will not be textured.',
'labels.bottomFaces': 'Bottom faces', 'labels.bottomFaces': 'Bottom faces',
'tooltips.bottomFaces': 'Suppress texture on downward-facing surfaces within this angle of horizontal', 'tooltips.bottomFaces': 'Suppress texture on downward-facing surfaces within this angle of horizontal',
@@ -70,7 +73,7 @@ export const TRANSLATIONS = {
'tooltips.topFaces': 'Suppress texture on upward-facing surfaces within this angle of horizontal', 'tooltips.topFaces': 'Suppress texture on upward-facing surfaces within this angle of horizontal',
// Surface masking section // Surface masking section
'sections.surfaceMasking': 'Surface Masking \u24d8', 'sections.surfaceMasking': 'By Surface \u24d8',
'sections.surfaceSelection': 'Surface Selection', 'sections.surfaceSelection': 'Surface Selection',
'tooltips.surfaceMasking': 'Mask surfaces to control which areas receive displacement.', 'tooltips.surfaceMasking': 'Mask surfaces to control which areas receive displacement.',
'tooltips.surfaceSelection': 'Selected surfaces appear green and will be the only ones to receive displacement during export.', 'tooltips.surfaceSelection': 'Selected surfaces appear green and will be the only ones to receive displacement during export.',
@@ -108,7 +111,7 @@ export const TRANSLATIONS = {
'precision.warningBody': 'Estimated ~{n} triangles. This may slow down your browser. Continue?', 'precision.warningBody': 'Estimated ~{n} triangles. This may slow down your browser. Continue?',
// Boundary falloff // Boundary falloff
'labels.boundaryFalloff': 'Boundary Falloff \u24d8', 'labels.boundaryFalloff': 'Smooth Mask \u24d8',
'tooltips.boundaryFalloff': 'Gradually reduces displacement to zero near masked boundaries, preventing triangle overlap where textured and non-textured regions meet.', 'tooltips.boundaryFalloff': 'Gradually reduces displacement to zero near masked boundaries, preventing triangle overlap where textured and non-textured regions meet.',
// Symmetric displacement // Symmetric displacement
@@ -251,8 +254,11 @@ export const TRANSLATIONS = {
'labels.capAngle': 'Übergangswinkel \u24d8', 'labels.capAngle': 'Übergangswinkel \u24d8',
'tooltips.capAngle': 'Winkel (in Grad) ab dem die Deckel-/Bodenprojektion einsetzt. Kleinere Werte beschränken die Deckelprojektion auf nahezu flache Flächen.', 'tooltips.capAngle': 'Winkel (in Grad) ab dem die Deckel-/Bodenprojektion einsetzt. Kleinere Werte beschränken die Deckelprojektion auf nahezu flache Flächen.',
// Masking parent section
'sections.masking': 'Maskierung',
// Winkelmaskierung // Winkelmaskierung
'sections.maskAngles': 'Winkel maskieren \u24d8', 'sections.maskAngles': 'Nach Winkel \u24d8',
'tooltips.maskAngles': '0° = keine Maskierung. Fl\u00e4chen innerhalb dieses Winkels zur Horizontalen werden nicht texturiert.', 'tooltips.maskAngles': '0° = keine Maskierung. Fl\u00e4chen innerhalb dieses Winkels zur Horizontalen werden nicht texturiert.',
'labels.bottomFaces': 'Unterseiten', 'labels.bottomFaces': 'Unterseiten',
'tooltips.bottomFaces': 'Textur auf nach unten gerichteten Fl\u00e4chen innerhalb dieses Winkels zur Horizontalen unterdr\u00fccken', 'tooltips.bottomFaces': 'Textur auf nach unten gerichteten Fl\u00e4chen innerhalb dieses Winkels zur Horizontalen unterdr\u00fccken',
@@ -260,8 +266,8 @@ export const TRANSLATIONS = {
'tooltips.topFaces': 'Textur auf nach oben gerichteten Fl\u00e4chen innerhalb dieses Winkels zur Horizontalen unterdr\u00fccken', 'tooltips.topFaces': 'Textur auf nach oben gerichteten Fl\u00e4chen innerhalb dieses Winkels zur Horizontalen unterdr\u00fccken',
// Surface masking section // Surface masking section
'sections.surfaceMasking': 'Fl\u00e4chenmaskierung \u24d8', 'sections.surfaceMasking': 'Nach Fläche \u24d8',
'sections.surfaceSelection': 'Fl\u00e4chenauswahl', 'sections.surfaceSelection': 'Flächenauswahl',
'tooltips.surfaceMasking': 'Fl\u00e4chen maskieren, um zu steuern, welche Bereiche Verschiebung erhalten.', 'tooltips.surfaceMasking': 'Fl\u00e4chen maskieren, um zu steuern, welche Bereiche Verschiebung erhalten.',
'tooltips.surfaceSelection': 'Ausgew\u00e4hlte Fl\u00e4chen erscheinen gr\u00fcn und sind die einzigen, die beim Export eine Verschiebung erhalten.', 'tooltips.surfaceSelection': 'Ausgew\u00e4hlte Fl\u00e4chen erscheinen gr\u00fcn und sind die einzigen, die beim Export eine Verschiebung erhalten.',
'excl.modeExclude': 'Ausschlie\u00dfen', 'excl.modeExclude': 'Ausschlie\u00dfen',
@@ -298,7 +304,7 @@ export const TRANSLATIONS = {
'precision.warningBody': 'Gesch\u00e4tzt ~{n} Dreiecke. Dies kann den Browser verlangsamen. Fortfahren?', 'precision.warningBody': 'Gesch\u00e4tzt ~{n} Dreiecke. Dies kann den Browser verlangsamen. Fortfahren?',
// Boundary falloff // Boundary falloff
'labels.boundaryFalloff': 'Rand\u00fcbergang \u24d8', 'labels.boundaryFalloff': 'Maske glätten \u24d8',
'tooltips.boundaryFalloff': 'Reduziert die Verschiebung schrittweise auf Null nahe maskierter Grenzen, um Dreiecks\u00fcberschneidungen an \u00dcberg\u00e4ngen zu vermeiden.', 'tooltips.boundaryFalloff': 'Reduziert die Verschiebung schrittweise auf Null nahe maskierter Grenzen, um Dreiecks\u00fcberschneidungen an \u00dcberg\u00e4ngen zu vermeiden.',
// Symmetric displacement // Symmetric displacement
@@ -441,8 +447,11 @@ export const TRANSLATIONS = {
'labels.capAngle': 'Angolo di copertura \u24d8', 'labels.capAngle': 'Angolo di copertura \u24d8',
'tooltips.capAngle': 'Angolo (in gradi) rispetto alla verticale al quale entra in gioco la proiezione della copertura superiore/inferiore. Valori più piccoli limitano la proiezione della copertura a facce quasi piatte.', 'tooltips.capAngle': 'Angolo (in gradi) rispetto alla verticale al quale entra in gioco la proiezione della copertura superiore/inferiore. Valori più piccoli limitano la proiezione della copertura a facce quasi piatte.',
// Masking parent section
'sections.masking': 'Mascheramento',
// Mask angles section // Mask angles section
'sections.maskAngles': 'Angoli di mascheramento \u24d8', 'sections.maskAngles': 'Per angolo \u24d8',
'tooltips.maskAngles': '0° = nessuna mascheratura. Le superfici comprese in questo angolo rispetto all\'orizzontale non saranno texturizzate.', 'tooltips.maskAngles': '0° = nessuna mascheratura. Le superfici comprese in questo angolo rispetto all\'orizzontale non saranno texturizzate.',
'labels.bottomFaces': 'Facce inferiori', 'labels.bottomFaces': 'Facce inferiori',
'tooltips.bottomFaces': 'Elimina la texture sulle superfici rivolte verso il basso entro questo angolo rispetto all\'orizzontale', 'tooltips.bottomFaces': 'Elimina la texture sulle superfici rivolte verso il basso entro questo angolo rispetto all\'orizzontale',
@@ -450,7 +459,7 @@ export const TRANSLATIONS = {
'tooltips.topFaces': 'Elimina la texture sulle superfici rivolte verso l\'alto entro questo angolo rispetto all\'orizzontale', 'tooltips.topFaces': 'Elimina la texture sulle superfici rivolte verso l\'alto entro questo angolo rispetto all\'orizzontale',
// Surface masking section // Surface masking section
'sections.surfaceMasking': 'Mascheramento delle superfici \u24d8', 'sections.surfaceMasking': 'Per superficie \u24d8',
'sections.surfaceSelection': 'Selezione delle superfici', 'sections.surfaceSelection': 'Selezione delle superfici',
'tooltips.surfaceMasking': 'Mascherare le superfici per controllare quali aree subiscono la deformazione.', 'tooltips.surfaceMasking': 'Mascherare le superfici per controllare quali aree subiscono la deformazione.',
'tooltips.surfaceSelection': 'Le superfici selezionate appaiono in verde e saranno le uniche a subire la deformazione durante l\'esportazione.', 'tooltips.surfaceSelection': 'Le superfici selezionate appaiono in verde e saranno le uniche a subire la deformazione durante l\'esportazione.',
@@ -488,7 +497,7 @@ export const TRANSLATIONS = {
'precision.warningBody': 'Stima ~{n} triangoli. Ciò potrebbe rallentare il browser. Continuare?', 'precision.warningBody': 'Stima ~{n} triangoli. Ciò potrebbe rallentare il browser. Continuare?',
// Boundary falloff // Boundary falloff
'labels.boundaryFalloff': 'Sfumatura bordo \u24d8', 'labels.boundaryFalloff': 'Maschera liscia \u24d8',
'tooltips.boundaryFalloff': 'Riduce gradualmente la deformazione a zero vicino ai bordi mascherati, impedendo sovrapposizioni di triangoli tra zone con e senza texture.', 'tooltips.boundaryFalloff': 'Riduce gradualmente la deformazione a zero vicino ai bordi mascherati, impedendo sovrapposizioni di triangoli tra zone con e senza texture.',
// Symmetric displacement // Symmetric displacement
@@ -572,6 +581,585 @@ export const TRANSLATIONS = {
'alerts.loadFailed': 'Caricamento del modello fallito: {msg}', 'alerts.loadFailed': 'Caricamento del modello fallito: {msg}',
'alerts.exportFailed': 'Esportazione fallita: {msg}', 'alerts.exportFailed': 'Esportazione fallita: {msg}',
}, },
es: {
'lang.name': 'Español (beta)',
// Theme toggle
'theme.dark': 'Tema Oscuro',
'theme.light': 'Tema Claro',
'theme.toggleTitle': 'Alternar modo claro / oscuro',
'theme.toggleAriaLabel': 'Alternar modo claro/oscuro',
// Drop zone
'dropHint.text': 'Arrastra aquí un archivo <strong>.stl</strong>, <strong>.obj</strong> o <strong>.3mf</strong><br/>o <label for="stl-file-input" class="link-label">haz clic para explorar</label>',
// Viewport footer
'ui.wireframe': 'Malla de alambre',
'ui.controlsHint': 'Arrastrar izq.: orbitar \u00a0·\u00a0 Arrastrar der.: desplazar \u00a0·\u00a0 Rueda: zoom',
'ui.meshInfo': '{n} triángulos · {mb} MB · {sx} × {sy} × {sz} mm',
// Load model button
'ui.loadStl': 'Cargar modelo\u2026',
// Displacement map section
'sections.displacementMap': 'Mapa de desplazamiento',
'ui.uploadCustomMap': 'Subir mapa personalizado',
'ui.noMapSelected': 'Ningún mapa seleccionado',
// Projection section
'sections.projection': 'Proyección',
'labels.mode': 'Modo',
'projection.triplanar': 'Triplanar',
'projection.cubic': 'Cúbica (Caja)',
'projection.cylindrical': 'Cilíndrica',
'projection.spherical': 'Esférica',
'projection.planarXY': 'Planar XY',
'projection.planarXZ': 'Planar XZ',
'projection.planarYZ': 'Planar YZ',
// Transform section
'sections.transform': 'Transformación',
'labels.scaleU': 'Escala U',
'labels.scaleV': 'Escala V',
'labels.offsetU': 'Desplazamiento U',
'labels.offsetV': 'Desplazamiento V',
'labels.rotation': 'Rotación',
'tooltips.proportionalScaling': 'Escalado proporcional (U = V)',
'tooltips.proportionalScalingAria': 'Escalado proporcional (U = V)',
// Displacement section
'sections.displacement': 'Profundidad de textura',
'labels.amplitude': 'Amplitud',
// Seam blend
'labels.seamBlend': 'Fusión de costuras \u24d8',
'tooltips.seamBlend': 'Suaviza la costura donde se unen las caras de proyección. Efectivo para los modos Cúbico y Cilíndrico.',
'labels.transitionSmoothing': 'Suavizado de transición \u24d8',
'tooltips.transitionSmoothing': 'Ancho de la zona de fusión cerca de los bordes de la costura. Valores bajos mantienen las transiciones pegadas a la costura; valores altos difuminan una banda más amplia.',
'labels.textureSmoothing': 'Suavizado de textura \u24d8',
'tooltips.textureSmoothing': 'Aplica un desenfoque gaussiano al mapa de desplazamiento. Valores más altos producen detalles de superficie más suaves y graduales. 0 = desactivado.',
'labels.capAngle': 'Ángulo de tapa \u24d8',
'tooltips.capAngle': 'Ángulo (en grados) desde la vertical en el que se activa la proyección de tapa superior/inferior. Valores más pequeños limitan la proyección a caras casi planas.',
// Masking parent section
'sections.masking': 'Enmascaramiento',
// Mask angles section
'sections.maskAngles': 'Por ángulo \u24d8',
'tooltips.maskAngles': '0° = sin enmascaramiento. Las superficies dentro de este ángulo respecto a la horizontal no serán texturizadas.',
'labels.bottomFaces': 'Caras inferiores',
'tooltips.bottomFaces': 'Eliminar textura en superficies orientadas hacia abajo dentro de este ángulo respecto a la horizontal',
'labels.topFaces': 'Caras superiores',
'tooltips.topFaces': 'Eliminar textura en superficies orientadas hacia arriba dentro de este ángulo respecto a la horizontal',
// Surface masking section
'sections.surfaceMasking': 'Por superficie \u24d8',
'sections.surfaceSelection': 'Selección de superficies',
'tooltips.surfaceMasking': 'Enmascarar superficies para controlar qué áreas reciben desplazamiento.',
'tooltips.surfaceSelection': 'Las superficies seleccionadas aparecen en verde y serán las únicas en recibir desplazamiento durante la exportación.',
'excl.modeExclude': 'Excluir',
'excl.modeExcludeTitle': 'Modo Excluir: las superficies pintadas no recibirán desplazamiento de textura',
'excl.modeIncludeOnly': 'Solo incluir',
'excl.modeIncludeOnlyTitle': 'Modo Solo incluir: solo las superficies pintadas recibirán desplazamiento de textura',
'excl.toolBrush': 'Pincel',
'excl.toolBrushTitle': 'Pincel: pintar triángulos para excluir',
'excl.toolFill': 'Relleno',
'excl.toolFillTitle': 'Relleno: rellenar superficie hasta un ángulo umbral',
'excl.shiftHint': 'Mantén Shift para borrar',
'labels.type': 'Tipo',
'brushType.single': 'Individual',
'brushType.circle': 'Círculo',
'labels.size': 'Tamaño',
'labels.maxAngle': 'Ángulo máx.',
'tooltips.maxAngle': 'Ángulo diedro máximo entre triángulos adyacentes que el relleno puede cruzar',
'ui.clearAll': 'Borrar todo',
'excl.initExcluded': '0 caras enmascaradas',
'excl.faceExcluded': '{n} cara enmascarada',
'excl.facesExcluded': '{n} caras enmascaradas',
'excl.faceSelected': '{n} cara seleccionada',
'excl.facesSelected': '{n} caras seleccionadas',
'excl.hintExclude': 'Las superficies enmascaradas aparecen en naranja y no recibirán desplazamiento durante la exportación.',
'excl.hintInclude': 'Las superficies seleccionadas aparecen en verde y serán las únicas en recibir desplazamiento durante la exportación.',
// Precision masking
'precision.label': 'Precisión (Beta) \u24d8',
'precision.labelTitle': 'Subdivide la malla en segundo plano para que el pincel seleccione con mayor granularidad',
'precision.outdated': '\u26a0 Desactualizado',
'precision.refreshTitle': 'Resubdividir la malla para ajustarla al tamaño actual del pincel',
'precision.triCount': '{n} \u25b3',
'precision.refining': 'Refinando\u2026',
'precision.warningBody': 'Estimados ~{n} triángulos. Esto puede ralentizar el navegador. ¿Continuar?',
// Boundary falloff
'labels.boundaryFalloff': 'Suavizar máscara \u24d8',
'tooltips.boundaryFalloff': 'Reduce gradualmente el desplazamiento a cero cerca de los bordes enmascarados, evitando superposiciones de triángulos entre zonas texturizadas y no texturizadas.',
// Symmetric displacement
'labels.symmetricDisplacement': 'Desplazamiento simétrico \u24d8',
'tooltips.symmetricDisplacement': 'Cuando está activado, el gris al 50% = sin desplazamiento; el blanco empuja hacia fuera, el negro empuja hacia dentro. Mantiene el volumen de la pieza aproximadamente constante.',
// Displacement preview
'labels.displacementPreview': 'Vista previa 3D \u24d8',
'tooltips.displacementPreview': 'Subdivide la malla y desplaza los vértices en tiempo real para evaluar la profundidad real. Uso intensivo de GPU en modelos complejos.',
// Place on face
'ui.placeOnFace': 'Colocar en cara',
'ui.placeOnFaceTitle': 'Haz clic en una cara para orientarla hacia abajo sobre la cama de impresión',
'progress.subdividingPreview': 'Preparando vista previa\u2026',
// Amplitude overlap warning
'warnings.amplitudeOverlap': '\u26a0 La amplitud supera el 10% de la dimensión más pequeña del modelo \u2014 pueden ocurrir superposiciones de geometría en el STL exportado.',
// Export section
'sections.export': 'Exportar \u24d8',
'tooltips.export': 'Menor longitud de arista = mayor detalle de desplazamiento. La salida se reduce al límite de triángulos.',
'labels.resolution': 'Resolución',
'tooltips.resolution': 'Las aristas más largas que este valor se subdividirán durante la exportación',
'labels.outputTriangles': 'Triángulos de salida',
'tooltips.outputTriangles': 'La malla se subdivide completamente primero y luego se reduce a esta cantidad',
'warnings.safetyCapHit': '\u26a0 Se alcanzó el límite de seguridad de 20M de triángulos durante la subdivisión \u2014 el resultado puede ser más grueso que la longitud de arista solicitada.',
'ui.exportStl': 'Exportar STL',
// Export progress stages
'progress.subdividing': 'Subdividiendo malla\u2026',
'progress.refining': 'Refinando: {cur} triángulos, arista más larga {edge}',
'progress.applyingDisplacement': 'Aplicando desplazamiento a {n} triángulos\u2026',
'progress.displacingVertices': 'Desplazando vértices\u2026',
'progress.decimatingTo': 'Simplificando {from} \u2192 {to} triángulos\u2026',
'progress.decimating': 'Simplificando: {cur} \u2192 {to} triángulos',
'progress.writingStl': 'Escribiendo STL\u2026',
'progress.done': '¡Listo!',
'progress.processing': 'Procesando\u2026',
// License popup
'license.btn': 'Licencia y condiciones',
'license.title': 'Licencia y condiciones',
'license.item1': 'Uso gratuito para cualquier propósito, incluyendo <strong>trabajo comercial</strong> (p. ej., texturizado de STLs para clientes o productos).',
'license.item2': 'La atribución es <strong>apreciada</strong> pero <strong>no obligatoria</strong> al usar esta herramienta tal cual.',
'license.item3': '¿Quieres apoyar esta herramienta? Compra en <a href="https://geni.us/CNCStoreTexture" target="_blank" rel="noopener">CNCKitchen.STORE</a> o dona en <a href="https://www.paypal.me/CNCKitchen" target="_blank" rel="noopener">PayPal</a>.',
'license.item4': 'Esta herramienta se proporciona <strong>tal cual</strong> sin <strong>ninguna garantía</strong> de ningún tipo. Úsala bajo tu propio riesgo.',
'license.item5': '<strong>No se proporciona soporte</strong>. El autor no tiene obligación de corregir errores, responder preguntas ni actualizar esta herramienta. Dicho esto, los informes de errores y solicitudes de funciones son siempre bienvenidos en <a href="mailto:texturizer@cnckitchen.com">texturizer@cnckitchen.com</a>.',
'license.item6': 'El autor no será responsable de <strong>daños</strong>, pérdida de datos o problemas derivados del uso de esta herramienta.',
'license.item7': '¿Quieres licenciar o integrar esta herramienta para tu negocio o sitio web? Contáctanos en <a href="mailto:contact@cnckitchen.com">contact@cnckitchen.com</a>.',
'license.item8': 'Código fuente disponible en <a href="https://github.com/CNCKitchen/stlTexturizer" target="_blank" rel="noopener">GitHub</a>.',
// Imprint & Privacy
'imprint.btn': 'Aviso legal y privacidad',
'imprint.title': 'Aviso legal y política de privacidad',
'imprint.sectionImprint': 'Aviso legal (Impressum)',
'imprint.info': 'CNC Kitchen<br>Stefan Hermann<br>Bahnhofstr. 2<br>88145 Hergatz<br>Alemania',
'imprint.contact': 'Correo: <a href="mailto:contact@cnckitchen.com">contact@cnckitchen.com</a><br>Teléfono: +49 175 2011824<br><em>El número de teléfono es exclusivamente para consultas legales/comerciales \u2014 no para soporte.</em>',
'imprint.odr': 'Plataforma de resolución de litigios en línea de la UE: <a href="https://ec.europa.eu/consumers/odr" target="_blank" rel="noopener">https://ec.europa.eu/consumers/odr</a>',
'imprint.sectionPrivacy': 'Política de privacidad (Datenschutzerklärung)',
'imprint.privacyIntro': '<strong>Responsable</strong> (Verantwortlicher gem. Art. 4 Abs. 7 DSGVO): Stefan Hermann, Bahnhofstr. 2, 88145 Hergatz, Alemania.',
'imprint.privacyHosting': 'Este sitio web está alojado en <strong>GitHub Pages</strong> (GitHub Inc. / Microsoft Corp., 88 Colin P Kelly Jr St, San Francisco, CA 94107, EE.UU.). Al visitar este sitio, GitHub puede procesar tu dirección IP en los registros del servidor. Base legal: Art. 6(1)(f) RGPD (interés legítimo en proporcionar el sitio web). Ver <a href="https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement" target="_blank" rel="noopener">Declaración de privacidad de GitHub</a>.',
'imprint.privacyLocal': 'Esta herramienta almacena las preferencias del usuario (idioma, tema) en el <strong>localStorage</strong> de tu navegador. Estos datos nunca salen de tu dispositivo ni se transmiten a ningún servidor.',
'imprint.privacyNoCookies': 'Este sitio web <strong>no</strong> utiliza cookies, herramientas de análisis ni tecnologías de rastreo.',
'imprint.privacyExternal': 'Este sitio contiene enlaces a sitios web externos (p. ej., CNCKitchen.STORE, PayPal). Estos sitios tienen sus propias políticas de privacidad, sobre las cuales no tenemos control.',
'imprint.privacyRights': 'Según el RGPD, tienes derecho a <strong>acceso, rectificación, supresión, limitación del tratamiento, portabilidad de datos</strong> y derecho a <strong>presentar una reclamación</strong> ante una autoridad de control.',
// Sponsor modal
'sponsor.title': '¡Gracias por usar BumpMesh de CNC Kitchen!',
'sponsor.body': 'Esta herramienta es proporcionada <strong>completamente gratis</strong> por CNC Kitchen.<br>Mientras se procesa tu STL, ¿por qué no echas un vistazo a la tienda que nos ayuda a seguir creando cosas geniales para ti?',
'sponsor.visitStore': '\uD83D\uDED2 Visitar CNCKitchen.STORE',
'sponsor.donate': '\uD83D\uDC99 Donar en PayPal',
'sponsor.dontShow': 'No mostrar de nuevo',
'sponsor.closeAndContinue': 'Cerrar y continuar',
// Store CTA
'cta.store': '¿Quieres apoyar esta herramienta? Compra en <a href="https://geni.us/CNCStoreTexture" target="_blank" rel="noopener noreferrer">CNCKitchen.STORE</a> o dona en <a href="https://www.paypal.me/CNCKitchen" target="_blank" rel="noopener noreferrer">PayPal</a>',
'cta.storeDismiss': 'Cerrar',
// Alerts
'alerts.loadFailed': 'No se pudo cargar el modelo: {msg}',
'alerts.exportFailed': 'Error en la exportación: {msg}',
},
pt: {
'lang.name': 'Português (beta)',
// Theme toggle
'theme.dark': 'Tema Escuro',
'theme.light': 'Tema Claro',
'theme.toggleTitle': 'Alternar modo claro / escuro',
'theme.toggleAriaLabel': 'Alternar modo claro/escuro',
// Drop zone
'dropHint.text': 'Arraste um arquivo <strong>.stl</strong>, <strong>.obj</strong> ou <strong>.3mf</strong> aqui<br/>ou <label for="stl-file-input" class="link-label">clique para procurar</label>',
// Viewport footer
'ui.wireframe': 'Wireframe',
'ui.controlsHint': 'Arrastar esq.: orbitar \u00a0·\u00a0 Arrastar dir.: deslocar \u00a0·\u00a0 Roda: zoom',
'ui.meshInfo': '{n} triângulos · {mb} MB · {sx} × {sy} × {sz} mm',
// Load model button
'ui.loadStl': 'Carregar modelo\u2026',
// Displacement map section
'sections.displacementMap': 'Mapa de deslocamento',
'ui.uploadCustomMap': 'Enviar mapa personalizado',
'ui.noMapSelected': 'Nenhum mapa selecionado',
// Projection section
'sections.projection': 'Projeção',
'labels.mode': 'Modo',
'projection.triplanar': 'Triplanar',
'projection.cubic': 'Cúbica (Caixa)',
'projection.cylindrical': 'Cilíndrica',
'projection.spherical': 'Esférica',
'projection.planarXY': 'Planar XY',
'projection.planarXZ': 'Planar XZ',
'projection.planarYZ': 'Planar YZ',
// Transform section
'sections.transform': 'Transformação',
'labels.scaleU': 'Escala U',
'labels.scaleV': 'Escala V',
'labels.offsetU': 'Deslocamento U',
'labels.offsetV': 'Deslocamento V',
'labels.rotation': 'Rotação',
'tooltips.proportionalScaling': 'Escala proporcional (U = V)',
'tooltips.proportionalScalingAria': 'Escala proporcional (U = V)',
// Displacement section
'sections.displacement': 'Profundidade da textura',
'labels.amplitude': 'Amplitude',
// Seam blend
'labels.seamBlend': 'Fusão de costuras \u24d8',
'tooltips.seamBlend': 'Suaviza a costura onde as faces de projeção se encontram. Eficaz para os modos Cúbico e Cilíndrico.',
'labels.transitionSmoothing': 'Suavização de transição \u24d8',
'tooltips.transitionSmoothing': 'Largura da zona de fusão perto das bordas da costura. Valores baixos mantêm as transições próximas à costura; valores altos suavizam uma faixa mais larga.',
'labels.textureSmoothing': 'Suavização de textura \u24d8',
'tooltips.textureSmoothing': 'Aplica um desfoque gaussiano ao mapa de deslocamento. Valores mais altos produzem detalhes de superfície mais suaves e graduais. 0 = desativado.',
'labels.capAngle': 'Ângulo de cobertura \u24d8',
'tooltips.capAngle': 'Ângulo (em graus) a partir da vertical no qual a projeção de cobertura superior/inferior é ativada. Valores menores limitam a projeção a faces quase planas.',
// Masking parent section
'sections.masking': 'Mascaramento',
// Mask angles section
'sections.maskAngles': 'Por ângulo \u24d8',
'tooltips.maskAngles': '0° = sem mascaramento. Superfícies dentro deste ângulo em relação à horizontal não serão texturizadas.',
'labels.bottomFaces': 'Faces inferiores',
'tooltips.bottomFaces': 'Suprimir textura em superfícies voltadas para baixo dentro deste ângulo em relação à horizontal',
'labels.topFaces': 'Faces superiores',
'tooltips.topFaces': 'Suprimir textura em superfícies voltadas para cima dentro deste ângulo em relação à horizontal',
// Surface masking section
'sections.surfaceMasking': 'Por superfície \u24d8',
'sections.surfaceSelection': 'Seleção de superfícies',
'tooltips.surfaceMasking': 'Mascarar superfícies para controlar quais áreas recebem deslocamento.',
'tooltips.surfaceSelection': 'As superfícies selecionadas aparecem em verde e serão as únicas a receber deslocamento durante a exportação.',
'excl.modeExclude': 'Excluir',
'excl.modeExcludeTitle': 'Modo Excluir: superfícies pintadas não receberão deslocamento de textura',
'excl.modeIncludeOnly': 'Incluir apenas',
'excl.modeIncludeOnlyTitle': 'Modo Incluir apenas: somente superfícies pintadas receberão deslocamento de textura',
'excl.toolBrush': 'Pincel',
'excl.toolBrushTitle': 'Pincel: pintar triângulos para excluir',
'excl.toolFill': 'Preenchimento',
'excl.toolFillTitle': 'Preenchimento: preencher superfície até um ângulo limite',
'excl.shiftHint': 'Segure Shift para apagar',
'labels.type': 'Tipo',
'brushType.single': 'Individual',
'brushType.circle': 'Círculo',
'labels.size': 'Tamanho',
'labels.maxAngle': 'Ângulo máx.',
'tooltips.maxAngle': 'Ângulo diedral máximo entre triângulos adjacentes que o preenchimento pode cruzar',
'ui.clearAll': 'Limpar tudo',
'excl.initExcluded': '0 faces mascaradas',
'excl.faceExcluded': '{n} face mascarada',
'excl.facesExcluded': '{n} faces mascaradas',
'excl.faceSelected': '{n} face selecionada',
'excl.facesSelected': '{n} faces selecionadas',
'excl.hintExclude': 'Superfícies mascaradas aparecem em laranja e não receberão deslocamento durante a exportação.',
'excl.hintInclude': 'Superfícies selecionadas aparecem em verde e serão as únicas a receber deslocamento durante a exportação.',
// Precision masking
'precision.label': 'Precisão (Beta) \u24d8',
'precision.labelTitle': 'Subdivide a malha em segundo plano para que o pincel selecione com maior granularidade',
'precision.outdated': '\u26a0 Desatualizado',
'precision.refreshTitle': 'Resubdividir a malha para ajustar ao tamanho atual do pincel',
'precision.triCount': '{n} \u25b3',
'precision.refining': 'Refinando\u2026',
'precision.warningBody': 'Estimados ~{n} triângulos. Isso pode deixar o navegador lento. Continuar?',
// Boundary falloff
'labels.boundaryFalloff': 'Suavizar máscara \u24d8',
'tooltips.boundaryFalloff': 'Reduz gradualmente o deslocamento a zero perto das bordas mascaradas, evitando sobreposição de triângulos entre zonas texturizadas e não texturizadas.',
// Symmetric displacement
'labels.symmetricDisplacement': 'Deslocamento simétrico \u24d8',
'tooltips.symmetricDisplacement': 'Quando ativado, cinza a 50% = sem deslocamento; branco empurra para fora, preto empurra para dentro. Mantém o volume da peça aproximadamente constante.',
// Displacement preview
'labels.displacementPreview': 'Pré-visualização 3D \u24d8',
'tooltips.displacementPreview': 'Subdivide a malha e desloca os vértices em tempo real para avaliar a profundidade real. Uso intensivo de GPU em modelos complexos.',
// Place on face
'ui.placeOnFace': 'Posicionar na face',
'ui.placeOnFaceTitle': 'Clique numa face para orientá-la para baixo sobre a mesa de impressão',
'progress.subdividingPreview': 'Preparando pré-visualização\u2026',
// Amplitude overlap warning
'warnings.amplitudeOverlap': '\u26a0 A amplitude excede 10% da menor dimensão do modelo \u2014 podem ocorrer sobreposições de geometria no STL exportado.',
// Export section
'sections.export': 'Exportar \u24d8',
'tooltips.export': 'Menor comprimento de aresta = maior detalhe de deslocamento. A saída é então reduzida ao limite de triângulos.',
'labels.resolution': 'Resolução',
'tooltips.resolution': 'Arestas maiores que este valor serão subdivididas durante a exportação',
'labels.outputTriangles': 'Triângulos de saída',
'tooltips.outputTriangles': 'A malha é totalmente subdividida primeiro e depois reduzida a esta quantidade',
'warnings.safetyCapHit': '\u26a0 Limite de segurança de 20M de triângulos atingido durante a subdivisão \u2014 o resultado pode ser mais grosseiro que o comprimento de aresta solicitado.',
'ui.exportStl': 'Exportar STL',
// Export progress stages
'progress.subdividing': 'Subdividindo malha\u2026',
'progress.refining': 'Refinando: {cur} triângulos, aresta mais longa {edge}',
'progress.applyingDisplacement': 'Aplicando deslocamento em {n} triângulos\u2026',
'progress.displacingVertices': 'Deslocando vértices\u2026',
'progress.decimatingTo': 'Simplificando {from} \u2192 {to} triângulos\u2026',
'progress.decimating': 'Simplificando: {cur} \u2192 {to} triângulos',
'progress.writingStl': 'Escrevendo STL\u2026',
'progress.done': 'Pronto!',
'progress.processing': 'Processando\u2026',
// License popup
'license.btn': 'Licença e termos',
'license.title': 'Licença e termos',
'license.item1': 'Uso gratuito para qualquer finalidade, incluindo <strong>trabalho comercial</strong> (p. ex., texturização de STLs para clientes ou produtos).',
'license.item2': 'A atribuição é <strong>apreciada</strong> mas <strong>não obrigatória</strong> ao usar esta ferramenta como está.',
'license.item3': 'Quer apoiar esta ferramenta? Compre na <a href="https://geni.us/CNCStoreTexture" target="_blank" rel="noopener">CNCKitchen.STORE</a> ou doe via <a href="https://www.paypal.me/CNCKitchen" target="_blank" rel="noopener">PayPal</a>.',
'license.item4': 'Esta ferramenta é fornecida <strong>como está</strong> sem <strong>nenhuma garantia</strong> de qualquer tipo. Use por sua conta e risco.',
'license.item5': '<strong>Nenhum suporte</strong> é fornecido. O autor não tem obrigação de corrigir bugs, responder perguntas ou atualizar esta ferramenta. Dito isso, relatórios de bugs e pedidos de funcionalidades são sempre bem-vindos em <a href="mailto:texturizer@cnckitchen.com">texturizer@cnckitchen.com</a>.',
'license.item6': 'O autor não será responsável por <strong>danos</strong>, perda de dados ou problemas decorrentes do uso desta ferramenta.',
'license.item7': 'Quer licenciar ou incorporar esta ferramenta para o seu negócio ou site? Entre em contato em <a href="mailto:contact@cnckitchen.com">contact@cnckitchen.com</a>.',
'license.item8': 'Código-fonte disponível no <a href="https://github.com/CNCKitchen/stlTexturizer" target="_blank" rel="noopener">GitHub</a>.',
// Imprint & Privacy
'imprint.btn': 'Aviso legal e privacidade',
'imprint.title': 'Aviso legal e política de privacidade',
'imprint.sectionImprint': 'Aviso legal (Impressum)',
'imprint.info': 'CNC Kitchen<br>Stefan Hermann<br>Bahnhofstr. 2<br>88145 Hergatz<br>Alemanha',
'imprint.contact': 'E-mail: <a href="mailto:contact@cnckitchen.com">contact@cnckitchen.com</a><br>Telefone: +49 175 2011824<br><em>O número de telefone é exclusivamente para consultas legais/comerciais \u2014 não para suporte.</em>',
'imprint.odr': 'Plataforma de resolução de litígios online da UE: <a href="https://ec.europa.eu/consumers/odr" target="_blank" rel="noopener">https://ec.europa.eu/consumers/odr</a>',
'imprint.sectionPrivacy': 'Política de privacidade (Datenschutzerklärung)',
'imprint.privacyIntro': '<strong>Responsável</strong> (Verantwortlicher gem. Art. 4 Abs. 7 DSGVO): Stefan Hermann, Bahnhofstr. 2, 88145 Hergatz, Alemanha.',
'imprint.privacyHosting': 'Este site é hospedado no <strong>GitHub Pages</strong> (GitHub Inc. / Microsoft Corp., 88 Colin P Kelly Jr St, San Francisco, CA 94107, EUA). Ao visitar este site, o GitHub pode processar seu endereço IP nos logs do servidor. Base legal: Art. 6(1)(f) RGPD (interesse legítimo em fornecer o site). Veja a <a href="https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement" target="_blank" rel="noopener">Declaração de privacidade do GitHub</a>.',
'imprint.privacyLocal': 'Esta ferramenta armazena as preferências do usuário (idioma, tema) no <strong>localStorage</strong> do seu navegador. Esses dados nunca saem do seu dispositivo e não são transmitidos a nenhum servidor.',
'imprint.privacyNoCookies': 'Este site <strong>não</strong> utiliza cookies, ferramentas de análise ou tecnologias de rastreamento.',
'imprint.privacyExternal': 'Este site contém links para sites externos (p. ex., CNCKitchen.STORE, PayPal). Esses sites têm suas próprias políticas de privacidade, sobre as quais não temos controle.',
'imprint.privacyRights': 'Nos termos do RGPD, você tem direito a <strong>acesso, retificação, eliminação, limitação do tratamento, portabilidade de dados</strong> e direito de <strong>apresentar uma reclamação</strong> junto a uma autoridade de supervisão.',
// Sponsor modal
'sponsor.title': 'Obrigado por usar o BumpMesh da CNC Kitchen!',
'sponsor.body': 'Esta ferramenta é fornecida <strong>totalmente grátis</strong> pela CNC Kitchen.<br>Enquanto seu STL está sendo processado, que tal dar uma olhada na loja que nos ajuda a continuar criando coisas legais para você?',
'sponsor.visitStore': '\uD83D\uDED2 Visitar CNCKitchen.STORE',
'sponsor.donate': '\uD83D\uDC99 Doar via PayPal',
'sponsor.dontShow': 'Não mostrar novamente',
'sponsor.closeAndContinue': 'Fechar e continuar',
// Store CTA
'cta.store': 'Quer apoiar esta ferramenta? Compre na <a href="https://geni.us/CNCStoreTexture" target="_blank" rel="noopener noreferrer">CNCKitchen.STORE</a> ou doe via <a href="https://www.paypal.me/CNCKitchen" target="_blank" rel="noopener noreferrer">PayPal</a>',
'cta.storeDismiss': 'Fechar',
// Alerts
'alerts.loadFailed': 'Não foi possível carregar o modelo: {msg}',
'alerts.exportFailed': 'Falha na exportação: {msg}',
},
ja: {
'lang.name': '日本語 (beta)',
// Theme toggle
'theme.dark': 'ダークテーマ',
'theme.light': 'ライトテーマ',
'theme.toggleTitle': 'ライト/ダークモードを切り替え',
'theme.toggleAriaLabel': 'ライト/ダークモードを切り替え',
// Drop zone
'dropHint.text': '<strong>.stl</strong>、<strong>.obj</strong>、<strong>.3mf</strong> ファイルをここにドロップ<br/>または <label for="stl-file-input" class="link-label">クリックして参照</label>',
// Viewport footer
'ui.wireframe': 'ワイヤーフレーム',
'ui.controlsHint': '左ドラッグ: 回転 \u00a0·\u00a0 右ドラッグ: パン \u00a0·\u00a0 スクロール: ズーム',
'ui.meshInfo': '{n} 三角形 · {mb} MB · {sx} × {sy} × {sz} mm',
// Load model button
'ui.loadStl': 'モデルを読み込む\u2026',
// Displacement map section
'sections.displacementMap': 'ディスプレイスメントマップ',
'ui.uploadCustomMap': 'カスタムマップをアップロード',
'ui.noMapSelected': 'マップが選択されていません',
// Projection section
'sections.projection': '投影',
'labels.mode': 'モード',
'projection.triplanar': 'トライプラナー',
'projection.cubic': 'キュービック (ボックス)',
'projection.cylindrical': '円筒',
'projection.spherical': '球面',
'projection.planarXY': '平面 XY',
'projection.planarXZ': '平面 XZ',
'projection.planarYZ': '平面 YZ',
// Transform section
'sections.transform': '変換',
'labels.scaleU': 'スケール U',
'labels.scaleV': 'スケール V',
'labels.offsetU': 'オフセット U',
'labels.offsetV': 'オフセット V',
'labels.rotation': '回転',
'tooltips.proportionalScaling': '比例スケーリング (U = V)',
'tooltips.proportionalScalingAria': '比例スケーリング (U = V)',
// Displacement section
'sections.displacement': 'テクスチャの深さ',
'labels.amplitude': '振幅',
// Seam blend
'labels.seamBlend': 'シームブレンド \u24d8',
'tooltips.seamBlend': '投影面が接する境界の硬い継ぎ目を滑らかにします。キュービックおよび円筒モードで効果的です。',
'labels.transitionSmoothing': 'トランジションスムージング \u24d8',
'tooltips.transitionSmoothing': '継ぎ目の端付近のブレンドゾーンの幅。低い値はトランジションを継ぎ目に近づけ、高い値はより広い帯域をブレンドします。',
'labels.textureSmoothing': 'テクスチャスムージング \u24d8',
'tooltips.textureSmoothing': 'ディスプレイスメントマップにガウシアンブラーを適用します。値が高いほど、より滑らかで緩やかな表面ディテールになります。0 = オフ。',
'labels.capAngle': 'キャップ角度 \u24d8',
'tooltips.capAngle': '上面/下面のキャップ投影が作動する垂直からの角度(度数)。小さい値はキャップ投影をほぼ平らな面に制限します。',
// Masking parent section
'sections.masking': 'マスキング',
// Mask angles section
'sections.maskAngles': '角度別 \u24d8',
'tooltips.maskAngles': '0° = マスクなし。水平からこの角度内の面はテクスチャが適用されません。',
'labels.bottomFaces': '底面',
'tooltips.bottomFaces': '水平からこの角度内の下向きの面のテクスチャを抑制',
'labels.topFaces': '上面',
'tooltips.topFaces': '水平からこの角度内の上向きの面のテクスチャを抑制',
// Surface masking section
'sections.surfaceMasking': 'サーフェス別 \u24d8',
'sections.surfaceSelection': 'サーフェス選択',
'tooltips.surfaceMasking': 'サーフェスをマスクして、どの領域にディスプレイスメントを適用するかを制御します。',
'tooltips.surfaceSelection': '選択されたサーフェスは緑色で表示され、エクスポート時にディスプレイスメントを受ける唯一の面になります。',
'excl.modeExclude': '除外',
'excl.modeExcludeTitle': '除外モード: 塗られたサーフェスはテクスチャディスプレイスメントを受けません',
'excl.modeIncludeOnly': '選択のみ',
'excl.modeIncludeOnlyTitle': '選択のみモード: 塗られたサーフェスのみがテクスチャディスプレイスメントを受けます',
'excl.toolBrush': 'ブラシ',
'excl.toolBrushTitle': 'ブラシ: 三角形を塗って除外',
'excl.toolFill': '塗りつぶし',
'excl.toolFillTitle': '塗りつぶし: 閾値角度までサーフェスをフラッドフィル',
'excl.shiftHint': 'Shiftキーを押しながら消去',
'labels.type': 'タイプ',
'brushType.single': '単一',
'brushType.circle': '円',
'labels.size': 'サイズ',
'labels.maxAngle': '最大角度',
'tooltips.maxAngle': '塗りつぶしが越えることができる隣接三角形間の最大二面角',
'ui.clearAll': 'すべてクリア',
'excl.initExcluded': '0 面マスク済み',
'excl.faceExcluded': '{n} 面マスク済み',
'excl.facesExcluded': '{n} 面マスク済み',
'excl.faceSelected': '{n} 面選択済み',
'excl.facesSelected': '{n} 面選択済み',
'excl.hintExclude': 'マスクされたサーフェスはオレンジ色で表示され、エクスポート時にディスプレイスメントを受けません。',
'excl.hintInclude': '選択されたサーフェスは緑色で表示され、エクスポート時にディスプレイスメントを受ける唯一の面になります。',
// Precision masking
'precision.label': '精度 (ベータ) \u24d8',
'precision.labelTitle': 'バックグラウンドでメッシュを細分化し、ブラシの選択精度を向上させます',
'precision.outdated': '\u26a0 古い情報',
'precision.refreshTitle': '現在のブラシサイズに合わせてメッシュを再細分化',
'precision.triCount': '{n} \u25b3',
'precision.refining': '精密化中\u2026',
'precision.warningBody': '推定 ~{n} 三角形。ブラウザが遅くなる可能性があります。続行しますか?',
// Boundary falloff
'labels.boundaryFalloff': 'マスクを滑らかに \u24d8',
'tooltips.boundaryFalloff': 'マスク境界付近でディスプレイスメントを徐々にゼロに減少させ、テクスチャ適用面と非適用面の間の三角形の重なりを防ぎます。',
// Symmetric displacement
'labels.symmetricDisplacement': '対称ディスプレイスメント \u24d8',
'tooltips.symmetricDisplacement': 'オンの場合、50%グレー = 変位なし、白は外側に押し出し、黒は内側に押し込みます。部品の体積をほぼ一定に保ちます。',
// Displacement preview
'labels.displacementPreview': '3Dプレビュー \u24d8',
'tooltips.displacementPreview': 'メッシュを細分化し、リアルタイムで頂点を変位させて実際の深さを確認できます。複雑なモデルではGPU負荷が高くなります。',
// Place on face
'ui.placeOnFace': '面に配置',
'ui.placeOnFaceTitle': '面をクリックして印刷ベッドに向けて配置します',
'progress.subdividingPreview': 'プレビューを準備中\u2026',
// Amplitude overlap warning
'warnings.amplitudeOverlap': '\u26a0 振幅がモデルの最小寸法の10%を超えています \u2014 エクスポートされたSTLでジオメトリの重なりが発生する可能性があります。',
// Export section
'sections.export': 'エクスポート \u24d8',
'tooltips.export': 'エッジ長が短いほど = ディスプレイスメントの詳細度が高くなります。出力はその後三角形の上限まで削減されます。',
'labels.resolution': '解像度',
'tooltips.resolution': 'この値より長いエッジはエクスポート時に分割されます',
'labels.outputTriangles': '出力三角形数',
'tooltips.outputTriangles': 'メッシュはまず完全に細分化され、その後この数まで削減されます',
'warnings.safetyCapHit': '\u26a0 細分化中に2000万三角形の安全制限に達しました \u2014 結果は要求されたエッジ長よりも粗くなる可能性があります。',
'ui.exportStl': 'STLをエクスポート',
// Export progress stages
'progress.subdividing': 'メッシュを細分化中\u2026',
'progress.refining': '精密化中: {cur} 三角形、最長エッジ {edge}',
'progress.applyingDisplacement': '{n} 三角形にディスプレイスメントを適用中\u2026',
'progress.displacingVertices': '頂点を変位中\u2026',
'progress.decimatingTo': '{from} → {to} 三角形に簡略化中\u2026',
'progress.decimating': '簡略化中: {cur} → {to} 三角形',
'progress.writingStl': 'STLを書き出し中\u2026',
'progress.done': '完了!',
'progress.processing': '処理中\u2026',
// License popup
'license.btn': 'ライセンスと利用規約',
'license.title': 'ライセンスと利用規約',
'license.item1': '<strong>商用利用</strong>を含む、あらゆる目的で無料で使用できます(例:クライアントや製品向けのSTLテクスチャリング)。',
'license.item2': 'このツールをそのまま使用する場合、クレジット表記は<strong>歓迎</strong>されますが<strong>必須ではありません</strong>。',
'license.item3': 'このツールを支援しませんか? <a href="https://geni.us/CNCStoreTexture" target="_blank" rel="noopener">CNCKitchen.STORE</a>でお買い物、または<a href="https://www.paypal.me/CNCKitchen" target="_blank" rel="noopener">PayPal</a>で寄付できます。',
'license.item4': 'このツールは<strong>現状のまま</strong>提供され、いかなる種類の<strong>保証もありません</strong>。自己責任でご利用ください。',
'license.item5': '<strong>サポートは提供されません</strong>。作者にはバグの修正、質問への回答、ツールの更新の義務はありません。ただし、バグ報告や機能リクエストは <a href="mailto:texturizer@cnckitchen.com">texturizer@cnckitchen.com</a> までいつでも歓迎します。',
'license.item6': '作者は、このツールの使用に起因する<strong>損害</strong>、データ損失、またはその他の問題について責任を負いません。',
'license.item7': 'このツールをビジネスやウェブサイトにライセンスまたは組み込みたい場合は、<a href="mailto:contact@cnckitchen.com">contact@cnckitchen.com</a> までお問い合わせください。',
'license.item8': 'ソースコードは <a href="https://github.com/CNCKitchen/stlTexturizer" target="_blank" rel="noopener">GitHub</a> で公開されています。',
// Imprint & Privacy
'imprint.btn': '特定商取引法に基づく表記とプライバシー',
'imprint.title': '特定商取引法に基づく表記とプライバシーポリシー',
'imprint.sectionImprint': '運営者情報 (Impressum)',
'imprint.info': 'CNC Kitchen<br>Stefan Hermann<br>Bahnhofstr. 2<br>88145 Hergatz<br>ドイツ',
'imprint.contact': 'メール: <a href="mailto:contact@cnckitchen.com">contact@cnckitchen.com</a><br>電話: +49 175 2011824<br><em>電話番号は法律/ビジネスに関するお問い合わせ専用です \u2014 サポートには対応しておりません。</em>',
'imprint.odr': 'EU オンライン紛争解決プラットフォーム: <a href="https://ec.europa.eu/consumers/odr" target="_blank" rel="noopener">https://ec.europa.eu/consumers/odr</a>',
'imprint.sectionPrivacy': 'プライバシーポリシー (Datenschutzerklärung)',
'imprint.privacyIntro': '<strong>責任者</strong> (Verantwortlicher gem. Art. 4 Abs. 7 DSGVO): Stefan Hermann, Bahnhofstr. 2, 88145 Hergatz, ドイツ。',
'imprint.privacyHosting': 'このウェブサイトは <strong>GitHub Pages</strong>GitHub Inc. / Microsoft Corp., 88 Colin P Kelly Jr St, San Francisco, CA 94107, USA)でホストされています。このサイトにアクセスすると、GitHubがサーバーログでIPアドレスを処理する場合があります。法的根拠: GDPR第6条(1)(f)(ウェブサイト提供の正当な利益)。<a href="https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement" target="_blank" rel="noopener">GitHubのプライバシーステートメント</a>を参照してください。',
'imprint.privacyLocal': 'このツールはユーザーの設定(言語、テーマ)をブラウザの<strong>localStorage</strong>に保存します。このデータはデバイスの外に出ることはなく、サーバーに送信されることもありません。',
'imprint.privacyNoCookies': 'このウェブサイトはCookie、分析ツール、トラッキング技術を<strong>一切使用しません</strong>。',
'imprint.privacyExternal': 'このサイトには外部ウェブサイト(CNCKitchen.STORE、PayPalなど)へのリンクが含まれています。これらのサイトには独自のプライバシーポリシーがあり、当方では管理できません。',
'imprint.privacyRights': 'GDPRに基づき、<strong>アクセス、訂正、削除、処理の制限、データポータビリティ</strong>の権利、および監督機関に<strong>苦情を申し立てる</strong>権利があります。',
// Sponsor modal
'sponsor.title': 'CNC Kitchen の BumpMesh をご利用いただきありがとうございます!',
'sponsor.body': 'このツールは CNC Kitchen が<strong>完全無料</strong>で提供しています。<br>STLの処理中に、私たちがクールなものを作り続けるのを支えてくれるストアを覗いてみませんか?',
'sponsor.visitStore': '\uD83D\uDED2 CNCKitchen.STORE を訪問',
'sponsor.donate': '\uD83D\uDC99 PayPal で寄付',
'sponsor.dontShow': '今後表示しない',
'sponsor.closeAndContinue': '閉じて続行',
// Store CTA
'cta.store': 'このツールを支援しませんか? <a href="https://geni.us/CNCStoreTexture" target="_blank" rel="noopener noreferrer">CNCKitchen.STORE</a>でお買い物、または<a href="https://www.paypal.me/CNCKitchen" target="_blank" rel="noopener noreferrer">PayPal</a>で寄付できます',
'cta.storeDismiss': '閉じる',
// Alerts
'alerts.loadFailed': 'モデルを読み込めませんでした: {msg}',
'alerts.exportFailed': 'エクスポートに失敗しました: {msg}',
},
}; };
// ── State ───────────────────────────────────────────────────────────────────── // ── State ─────────────────────────────────────────────────────────────────────
+1 -1
View File
@@ -62,7 +62,7 @@ const settings = {
seamBandWidth: 0.5, seamBandWidth: 0.5,
textureSmoothing: 0, textureSmoothing: 0,
capAngle: 20, capAngle: 20,
boundaryFalloff: 1, boundaryFalloff: 0,
symmetricDisplacement: false, symmetricDisplacement: false,
useDisplacement: false, useDisplacement: false,
}; };
+9
View File
@@ -391,6 +391,15 @@ main {
margin-bottom: 10px; margin-bottom: 10px;
} }
.panel-subsection-heading {
font-size: 9px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
margin: 14px 0 8px;
}
/* ── Preset grid ─────────────────────────────────────────────────────── */ /* ── Preset grid ─────────────────────────────────────────────────────── */
.preset-grid { .preset-grid {
display: grid; display: grid;