Files
SpineParticlesWeb/scripts/apply-project-library-i18n.mjs
tianmo 46083c8d2a 完善浏览器配置库与未保存提示
- 新增 IndexedDB 配置保存、加载、删除及批量导入导出

- 配置列表支持选中、双击加载和悬浮操作提示

- 新增未保存提示设置,默认关闭并持久化到浏览器

- 优化配置管理界面并同步九种语言文案

- 更新开发文档与生产构建产物
2026-10-23 11:48:21 +08:00

133 lines
13 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { readFile, writeFile } from 'node:fs/promises'
const local = {
'zh-CN': {
listTitle: '配置列表', empty: '浏览器中还没有保存的配置', saveTitle: '保存配置到浏览器缓存',
name: '配置名称', namePlaceholder: '例如:烟花效果', load: '加载', loadHint: '双击以加载', download: '下载', delete: '删除',
downloadCurrent: '下载当前配置', downloadAll: '下载所有配置', loadAll: '加载所有配置',
loadAllConfirm: '将导入 {count} 个配置文件,同名配置会被覆盖。是否继续?',
loadAllDone: '已从文件加载 {count} 个配置', loadAllPartial: '已导入 {imported} 个配置,{failed} 个文件失败',
overwriteSave: '“{name}”已存在,是否覆盖?',
loadOverwrite: '加载“{name}”会覆盖当前场景,未保存的修改将丢失。是否继续?',
deleteConfirm: '确定删除“{name}”吗?', nameRequired: '请输入配置名称',
nameInvalid: '配置名称不能包含 \\ / : * ? " < > |', storageUnavailable: '浏览器本地存储不可用',
saved: '已保存到浏览器:{name}', loaded: '已从浏览器加载:{name}', deleted: '已删除缓存配置:{name}',
downloadEmpty: '没有可下载的配置', downloaded: '已下载:{name}',
},
'zh-TW': {
listTitle: '設定列表', empty: '瀏覽器中尚無已儲存的設定', saveTitle: '儲存設定到瀏覽器快取',
name: '設定名稱', namePlaceholder: '例如:煙花效果', load: '載入', loadHint: '按兩下以載入', download: '下載', delete: '刪除',
downloadCurrent: '下載目前設定', downloadAll: '下載所有設定', loadAll: '載入所有設定',
loadAllConfirm: '將匯入 {count} 個設定檔,同名設定會被覆寫。是否繼續?',
loadAllDone: '已從檔案載入 {count} 個設定', loadAllPartial: '已匯入 {imported} 個設定,{failed} 個檔案失敗',
overwriteSave: '「{name}」已存在,是否覆寫?',
loadOverwrite: '載入「{name}」會覆寫目前場景,未儲存的修改將遺失。是否繼續?',
deleteConfirm: '確定刪除「{name}」嗎?', nameRequired: '請輸入設定名稱',
nameInvalid: '設定名稱不能包含 \\ / : * ? " < > |', storageUnavailable: '瀏覽器本機儲存空間無法使用',
saved: '已儲存到瀏覽器:{name}', loaded: '已從瀏覽器載入:{name}', deleted: '已刪除瀏覽器設定:{name}',
downloadEmpty: '沒有可下載的設定', downloaded: '已下載:{name}',
},
en: {
listTitle: 'Configuration List', empty: 'No configurations saved in this browser', saveTitle: 'Save configuration to browser cache',
name: 'Configuration name', namePlaceholder: 'For example: Firework effect', load: 'Load', loadHint: 'Double-click to load', download: 'Download', delete: 'Delete',
downloadCurrent: 'Download Current Configuration', downloadAll: 'Download All Configurations', loadAll: 'Load All Configurations',
loadAllConfirm: 'Import {count} configuration files? Existing configurations with the same names will be overwritten.',
loadAllDone: 'Loaded {count} configurations from files', loadAllPartial: 'Imported {imported} configurations; {failed} files failed',
overwriteSave: '“{name}” already exists. Overwrite it?',
loadOverwrite: 'Loading “{name}” will replace the current scene and discard unsaved changes. Continue?',
deleteConfirm: 'Delete “{name}”?', nameRequired: 'Enter a configuration name',
nameInvalid: 'The name cannot contain \\ / : * ? " < > |', storageUnavailable: 'Browser local storage is unavailable',
saved: 'Saved to browser: {name}', loaded: 'Loaded from browser: {name}', deleted: 'Deleted browser configuration: {name}',
downloadEmpty: 'No configurations to download', downloaded: 'Downloaded: {name}',
},
ja: {
listTitle: '設定一覧', empty: 'このブラウザに保存された設定はありません', saveTitle: '設定をブラウザキャッシュに保存',
name: '設定名', namePlaceholder: '例:花火エフェクト', load: '読み込む', loadHint: 'ダブルクリックで読み込む', download: 'ダウンロード', delete: '削除',
downloadCurrent: '現在の設定をダウンロード', downloadAll: 'すべての設定をダウンロード', loadAll: 'すべての設定を読み込む',
loadAllConfirm: '{count} 個の設定ファイルを読み込みます。同名の設定は上書きされます。続行しますか?',
loadAllDone: 'ファイルから {count} 個の設定を読み込みました', loadAllPartial: '{imported} 個の設定を読み込み、{failed} 個のファイルが失敗しました',
overwriteSave: '「{name}」は既に存在します。上書きしますか?',
loadOverwrite: '「{name}」を読み込むと現在のシーンが置き換えられ、未保存の変更は失われます。続行しますか?',
deleteConfirm: '「{name}」を削除しますか?', nameRequired: '設定名を入力してください',
nameInvalid: '設定名に \\ / : * ? " < > | は使用できません', storageUnavailable: 'ブラウザのローカルストレージを利用できません',
saved: 'ブラウザに保存しました:{name}', loaded: 'ブラウザから読み込みました:{name}', deleted: 'ブラウザの設定を削除しました:{name}',
downloadEmpty: 'ダウンロードできる設定がありません', downloaded: 'ダウンロードしました:{name}',
},
ko: {
listTitle: '설정 목록', empty: '이 브라우저에 저장된 설정이 없습니다', saveTitle: '브라우저 캐시에 설정 저장',
name: '설정 이름', namePlaceholder: '예: 폭죽 효과', load: '불러오기', loadHint: '더블클릭하여 불러오기', download: '다운로드', delete: '삭제',
downloadCurrent: '현재 설정 다운로드', downloadAll: '모든 설정 다운로드', loadAll: '모든 설정 불러오기',
loadAllConfirm: '설정 파일 {count}개를 가져옵니다. 같은 이름의 설정은 덮어씁니다. 계속할까요?',
loadAllDone: '파일에서 설정 {count}개를 불러왔습니다', loadAllPartial: '설정 {imported}개를 가져왔고 {failed}개 파일이 실패했습니다',
overwriteSave: "'{name}'이(가) 이미 있습니다. 덮어쓸까요?",
loadOverwrite: "'{name}'을(를) 불러오면 현재 장면이 교체되고 저장하지 않은 변경 사항이 사라집니다. 계속할까요?",
deleteConfirm: "'{name}'을(를) 삭제할까요?", nameRequired: '설정 이름을 입력하세요',
nameInvalid: '설정 이름에는 \\ / : * ? " < > | 문자를 사용할 수 없습니다', storageUnavailable: '브라우저 로컬 저장소를 사용할 수 없습니다',
saved: '브라우저에 저장했습니다: {name}', loaded: '브라우저에서 불러왔습니다: {name}', deleted: '브라우저 설정을 삭제했습니다: {name}',
downloadEmpty: '다운로드할 설정이 없습니다', downloaded: '다운로드했습니다: {name}',
},
fr: {
listTitle: 'Liste des configurations', empty: 'Aucune configuration enregistrée dans ce navigateur', saveTitle: 'Enregistrer la configuration dans le cache du navigateur',
name: 'Nom de la configuration', namePlaceholder: 'Par exemple : Effet de feux d’artifice', load: 'Charger', loadHint: 'Double-cliquez pour charger', download: 'Télécharger', delete: 'Supprimer',
downloadCurrent: 'Télécharger la configuration actuelle', downloadAll: 'Télécharger toutes les configurations', loadAll: 'Charger toutes les configurations',
loadAllConfirm: 'Importer {count} fichiers de configuration ? Les configurations portant le même nom seront écrasées.',
loadAllDone: '{count} configurations chargées depuis les fichiers', loadAllPartial: '{imported} configurations importées ; {failed} fichiers en échec',
overwriteSave: '« {name} » existe déjà. L’écraser ?',
loadOverwrite: 'Le chargement de « {name} » remplacera la scène actuelle et perdra les modifications non enregistrées. Continuer ?',
deleteConfirm: 'Supprimer « {name} » ?', nameRequired: 'Saisissez un nom de configuration',
nameInvalid: 'Le nom ne peut pas contenir \\ / : * ? " < > |', storageUnavailable: 'Le stockage local du navigateur est indisponible',
saved: 'Enregistré dans le navigateur : {name}', loaded: 'Chargé depuis le navigateur : {name}', deleted: 'Configuration supprimée du navigateur : {name}',
downloadEmpty: 'Aucune configuration à télécharger', downloaded: 'Téléchargé : {name}',
},
de: {
listTitle: 'Konfigurationsliste', empty: 'Keine Konfigurationen in diesem Browser gespeichert', saveTitle: 'Konfiguration im Browser-Cache speichern',
name: 'Konfigurationsname', namePlaceholder: 'Zum Beispiel: Feuerwerkseffekt', load: 'Laden', loadHint: 'Doppelklicken zum Laden', download: 'Herunterladen', delete: 'Löschen',
downloadCurrent: 'Aktuelle Konfiguration herunterladen', downloadAll: 'Alle Konfigurationen herunterladen', loadAll: 'Alle Konfigurationen laden',
loadAllConfirm: '{count} Konfigurationsdateien importieren? Gleichnamige Konfigurationen werden überschrieben.',
loadAllDone: '{count} Konfigurationen aus Dateien geladen', loadAllPartial: '{imported} Konfigurationen importiert; {failed} Dateien fehlgeschlagen',
overwriteSave: '„{name}“ existiert bereits. Überschreiben?',
loadOverwrite: 'Beim Laden von „{name}“ wird die aktuelle Szene ersetzt und ungespeicherte Änderungen gehen verloren. Fortfahren?',
deleteConfirm: '„{name}“ löschen?', nameRequired: 'Geben Sie einen Konfigurationsnamen ein',
nameInvalid: 'Der Name darf \\ / : * ? " < > | nicht enthalten', storageUnavailable: 'Der lokale Browserspeicher ist nicht verfügbar',
saved: 'Im Browser gespeichert: {name}', loaded: 'Aus dem Browser geladen: {name}', deleted: 'Browserkonfiguration gelöscht: {name}',
downloadEmpty: 'Keine Konfigurationen zum Herunterladen', downloaded: 'Heruntergeladen: {name}',
},
'pt-BR': {
listTitle: 'Lista de configurações', empty: 'Nenhuma configuração salva neste navegador', saveTitle: 'Salvar configuração no cache do navegador',
name: 'Nome da configuração', namePlaceholder: 'Por exemplo: Efeito de fogos', load: 'Carregar', loadHint: 'Clique duplo para carregar', download: 'Baixar', delete: 'Excluir',
downloadCurrent: 'Baixar configuração atual', downloadAll: 'Baixar todas as configurações', loadAll: 'Carregar todas as configurações',
loadAllConfirm: 'Importar {count} arquivos de configuração? Configurações com o mesmo nome serão substituídas.',
loadAllDone: '{count} configurações carregadas dos arquivos', loadAllPartial: '{imported} configurações importadas; {failed} arquivos falharam',
overwriteSave: '“{name}” já existe. Substituir?',
loadOverwrite: 'Carregar “{name}” substituirá a cena atual e descartará alterações não salvas. Continuar?',
deleteConfirm: 'Excluir “{name}”?', nameRequired: 'Digite um nome de configuração',
nameInvalid: 'O nome não pode conter \\ / : * ? " < > |', storageUnavailable: 'O armazenamento local do navegador não está disponível',
saved: 'Salvo no navegador: {name}', loaded: 'Carregado do navegador: {name}', deleted: 'Configuração excluída do navegador: {name}',
downloadEmpty: 'Nenhuma configuração para baixar', downloaded: 'Baixado: {name}',
},
es: {
listTitle: 'Lista de configuraciones', empty: 'No hay configuraciones guardadas en este navegador', saveTitle: 'Guardar configuración en la caché del navegador',
name: 'Nombre de la configuración', namePlaceholder: 'Por ejemplo: Efecto de fuegos artificiales', load: 'Cargar', loadHint: 'Doble clic para cargar', download: 'Descargar', delete: 'Eliminar',
downloadCurrent: 'Descargar configuración actual', downloadAll: 'Descargar todas las configuraciones', loadAll: 'Cargar todas las configuraciones',
loadAllConfirm: '¿Importar {count} archivos de configuración? Las configuraciones con el mismo nombre se sobrescribirán.',
loadAllDone: '{count} configuraciones cargadas desde archivos', loadAllPartial: '{imported} configuraciones importadas; {failed} archivos fallaron',
overwriteSave: '«{name}» ya existe. ¿Sobrescribir?',
loadOverwrite: 'Cargar «{name}» sustituirá la escena actual y descartará los cambios no guardados. ¿Continuar?',
deleteConfirm: '¿Eliminar «{name}»?', nameRequired: 'Introduce un nombre de configuración',
nameInvalid: 'El nombre no puede contener \\ / : * ? " < > |', storageUnavailable: 'El almacenamiento local del navegador no está disponible',
saved: 'Guardado en el navegador: {name}', loaded: 'Cargado desde el navegador: {name}', deleted: 'Configuración eliminada del navegador: {name}',
downloadEmpty: 'No hay configuraciones para descargar', downloaded: 'Descargado: {name}',
},
}
for (const [locale, values] of Object.entries(local)) {
const path = `src/i18n/locales/${locale}.json`
const messages = JSON.parse(await readFile(path, 'utf8'))
messages.config ||= {}
messages.config.local = values
messages.config.saveTitle = values.saveTitle
await writeFile(path, `${JSON.stringify(messages, null, 2)}\n`)
}
console.log('Applied project library translations.')