From bcceca83ce966598e00e0319d85ec11d6df9d272 Mon Sep 17 00:00:00 2001
From: Ariver <shanghai3168@gmail.com>
Date: Tue, 30 Jun 2026 03:44:54 +0800
Subject: [PATCH] Freeze TagLauncher 8.2.8 build 20260630.0128
---
src/Apptag/Localization/ar.json | 100
src/Apptag/Localization/sv.json | 100
src/Scripts/quick_search_launch_contract_qa.sh | 181 +
src/Apptag/ApptagApp.swift | 31
src/Apptag/Localization/th.json | 100
src/Apptag/Localization/nn.json | 100
src/CHANGELOG.md | 49
src/Apptag/Info.plist | 4
src/Apptag/Localization/cs.json | 100
src/Apptag/DataLayer.swift | 81
src/Release/Freeze-8.2.8-20260630.0128/SHA256SUMS.txt | 3
src/Apptag/Localization/da.json | 100
src/Apptag/Localization/id.json | 98
src/Scripts/pro_notes_quota_qa.sh | 72
src/Apptag/PreferencesView.swift | 1049 +++++++---
CODE_GOVERNANCE.md | 55
src/Scripts/theme_settings_qa.sh | 2
src/Apptag/Localization/pt-BR.json | 100
src/Scripts/pro_localization_qa.sh | 108 +
AGENTS.md | 10
src/Apptag/Localization/ko.json | 96
src/Apptag/Localization/no.json | 100
src/Scripts/pro_theme_preview_countdown_qa.sh | 6
src/Apptag/ContentView.swift | 55
src/Apptag/Localization/nl.json | 98
src/Scripts/pro_custom_hotkeys_qa.sh | 150 +
src/Apptag/Localization/fr.json | 100
src/Apptag/Localization/ru.json | 100
src/Apptag/TagNavigationView.swift | 7
src/Apptag/AppGridCollectionView.swift | 23
src/Apptag/Localization/ro.json | 100
src/Apptag/Localization/en.json | 52
src/Apptag/Localization/zh-Hant.json | 80
src/Apptag/TagEditorView.swift | 97 +
src/Apptag/Localization/pl.json | 98
src/Apptag/Localization/es.json | 100
src/Scripts/pro_display_mode_preview_qa.sh | 139 +
src/Apptag/ProEntitlement.swift | 99 +
src/Release/Freeze-8.2.8-20260630.0128/FREEZE_MANIFEST.md | 150 +
src/Apptag/Localization/ms.json | 98
src/Apptag/Localization/it.json | 98
src/Apptag/Localization/tr.json | 100
src/Scripts/pro_feature_gate_qa.sh | 123 +
src/Apptag/QuickSearch.swift | 83
src/Apptag/Localization/ja.json | 98
src/Scripts/pro_tag_custom_color_qa.sh | 64
src/Apptag/AppDefaults.swift | 2
src/Apptag/LauncherHotkeySettings.swift | 11
src/Apptag/Localization/de.json | 98
CODEGRAPH.md | 65
src/Apptag/ProAccessViews.swift | 4
src/Apptag/Localization/ar-Najdi.json | 100
src/Apptag/Localization/nb.json | 100
src/Apptag/Localization/sr-Cyrl.json | 100
src/Apptag/Localization/zh-Hans.json | 68
src/Apptag/Localization/uk.json | 100
src/Apptag/Localization/vi.json | 100
57 files changed, 4,137 insertions(+), 1,368 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index d381b36..31d854b 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -15,6 +15,16 @@
本入口文件只保留高优先级硬约束;完整执行标准以 `CODE_GOVERNANCE.md` 为准。若两者冲突,以更严格、项目本地、更具体的规则为准。
+## UI 改动开工门禁
+
+TagLauncher 的非平凡 UI 改动必须先过 UI Preview Gate,不得直接进入 SwiftUI / AppKit 源码修改。
+
+- 非平凡 UI 改动包括:布局、字体、间距、颜色、主题、material、窗口尺寸、Pro 状态、设置页、AppGrid、Quick Search、tips、hover、拖拽、点击热区、可访问性或任何用户可见视觉变化。
+- 开工前必须先产出 UI 合约;推荐使用 `/Users/ar/Projects/Taglauncher/Docs/KM2.项目管理-非业务直接相关/UI合约模板.md`,也可在当前 PRD / TODO / Round 文档中写入同等字段。
+- UI 合约必须包含目标界面、影响 surface、不做范围、状态矩阵、主题 / 语言长度矩阵、交互互斥关系、验收截图或录屏要求。
+- 非纯调查任务必须先提供高保真预览来源,例如 baoyu-design HTML / 静态 screen、Penpot / Figma frame、用户标注图或等价可审阅截图;用户确认视觉目标后,才允许修改生产 UI 源码。
+- 实现后必须提供真实 App 截图、录屏、AX 或真实点击证据;没有真实渲染或真实交互证据,不得写视觉 PASS。
+
## 源码根目录
唯一源码根目录:`/Users/ar/Projects/Taglauncher/src`
diff --git a/CODEGRAPH.md b/CODEGRAPH.md
index cd8b190..814eaab 100644
--- a/CODEGRAPH.md
+++ b/CODEGRAPH.md
@@ -1,6 +1,6 @@
# TagLauncher CODEGRAPH
-最后更新:2026-06-27
+最后更新:2026-06-30
用途:本文件是 TagLauncher 的长期工程地图。修改用户可见行为、状态模型、构建/发布入口、核心源码或 QA 入口前,应先读本文件,再读指向的真实源码。若本文件与源码不一致,以源码为准,并在同一任务内更新本文件。
@@ -22,21 +22,28 @@
- 支持外部 URL 唤起 `taglauncher://show`:只做 AppGrid show/focus,不做 toggle;冷启动时请求会排队到初始化完成后执行;不接管原生触控板手势。
- 支持从标签导航双击进入设置页的 Tags tab。
- 启动时初始化 `ProEntitlementCenter`,保证免费 / Pro / 老用户自动 Pro 状态进入全局同步快照。
- - 菜单栏下拉菜单包含免费 / Pro 当前身份状态项;免费状态点击进入 About 页的 Pro 卡片,Pro 状态使用金色皇冠图标。
+ - 菜单栏下拉菜单包含免费 / Pro 当前身份状态项;免费状态文案引导立刻升级到 `👑Pro`,点击进入 Pro 设置页,Pro 状态使用金色皇冠图标。
- `src/Apptag/OverlayWindowController.swift`
- `OverlayPanel` / `OverlayWindowController`:AppGrid 浮层窗口与显示/隐藏控制。
- `src/Apptag/ContentView.swift`
- `ContentView`:AppGrid 主界面、标签导航、编辑模式、拖拽处理、Quick Search 数据刷新、使用技巧浮层入口。
- 读取 `appGridThemeID` 和炫彩主题调色值,并负责 AppGrid 全屏主题背景渲染。
+ - 编辑模式加载 `TagDef.customColor` 并传入 AppGrid、标签导航和标签编辑器;标签显示优先使用自定义颜色,缺省回退基础色。
- 编辑模式使用 runtime theme override:任何主题下进入编辑都临时显示默认浅色毛玻璃。
- 使用最近一次完整 `AppLibrarySnapshot` 先渲染 AppGrid,再后台刷新,避免启动/重开时立刻显示转圈。
- 使用技巧关闭提醒由 `ContentView` 统一弹 modal 并写入 `hideUsageTips` / `skipUsageTipsCloseReminder`。
- Quick Search 点击 TagLauncher 自身结果时只关闭当前浮层,不走外部自启动,避免 AppGrid 被重新拉起。
- `src/Apptag/PreferencesView.swift`
- - `PreferencesView`:设置窗口、语言、通用、主题、快捷键、标签、数据、关于等设置页。
+ - `PreferencesView`:设置窗口、语言、通用、主题、快捷键、标签、数据、Pro、关于等设置页。
+ - 顶部设置页签必须保持 8 个标签总宽不超过旧 7 标签宽度;图标统一使用线型 SF Symbols,`Pro` 页签位于数据之后、关于之前,使用线型皇冠。
+ - 设置页签下方按页签渲染统一固定位置的 `settingsFixedProHeader`:通用 / 主题 / 快捷键 / 标签 / 数据 / Pro 页显示该行且位置不漂移;语言和关于页不显示该 Pro 引导行。免费态显示当前 tab 对应购买引导和解锁/恢复按钮;Pro 已解锁态只显示权益状态说明,不显示恢复购买按钮。
+ - Pro 专属主题、彩色容器 / 彩色网格、自定义快捷键、自定义标签颜色和数据导入导出入口即使已解锁,也应保留皇冠 Pro 标识。
+ - Language tab 去掉重复标题说明,语言矩阵在主内容区域上下左右居中;About tab 应用信息块也在主内容区域居中。
- Theme tab 只写视觉偏好 `appGridThemeID` 和炫彩主题调色值,炫彩滑轨只能影响 AppGrid 背景,不得改变标签、排序、备注或分类数据。
- 免费用户预览 Pro 主题时,Theme tab 状态行和当前预览主题卡片显示基于 `ProThemePreviewState.endsAt` 推导的 `MM:SS` 倒计时;倒计时到期只退出预览,不弹阻塞提示。
- - Pro 升级 / 权益卡位于 About tab;Data tab 只承载分类方案、导入导出和气泡显示位置等数据管理入口。
+ - Pro tab 展示免费版 / Pro 版对比表;对比表不显示独立标题,Pro 列标题前必须有线型皇冠标识。
+ - Pro tab 对比表包含自定义标签颜色、彩色容器 / 彩色网格、高级主题、自定义快捷键、自定义应用备注和数据导入导出 / 分类与布局备份恢复;免费列锁定功能显示“不可用”,彩色容器 / 彩色网格和高级主题显示“只可预览 5 分钟”,备注显示“免费 3 个”;Pro 列未购买时显示带勾的“支持”,备注行显示带勾的“无限备注”,已购买后功能行显示带勾的“已解锁”。表格内所有状态胶囊使用与“免费 3 个”一致的中性样式,不显示皇冠图标或黄色 Pro 背景。
+ - About tab 只保留应用信息、帮助文档和联系信息,不放 Pro 汇总卡或免费 / Pro 差异表。
## AppGrid 显示与交互
@@ -47,6 +54,7 @@
- `AppGridIconNSView`:应用图标单元、点击、hover 气泡、拖拽起点。
- 底部使用技巧是原生 AppKit overlay,不允许改成 SwiftUI;必须拦截自身点击区域。
- 不拥有 AppGrid 全屏渐变背景,只接收 theme 推导出的玻璃和文本可读性 token。
+ - 分组标题颜色从 `TagDef.customColor` 优先解析;custom color signature 参与刷新签名,避免颜色变更后 AppGrid 不刷新。
- 样式 2 / 样式 3 的瀑布流容器布局会把未分类和 Mac 自带作为底部特殊容器:未分类倒数第二、Mac 自带最后,二者横向占满;普通列末尾会补齐到特殊容器上沿,避免底部参差空隙。
- `src/Apptag/AppGridTheme.swift`
- AppGrid 主题事实源:theme id、localization key、设置页 swatch、全屏渐变背景、炫彩主题调色板、玻璃明暗、编辑模式 token。
@@ -54,16 +62,17 @@
- 主题是否需要 Pro 只通过 `ProEntitlementConfig.freeThemes` 判断,不在主题 UI 中散落规则。
- `src/Apptag/ProEntitlement.swift`
- `ProEntitlementCenter`:StoreKit 2 当前权益、购买、恢复、交易更新、离线缓存和 QA 状态注入。
- - `ProEntitlementPolicy`:数据层可同步调用的 Pro 门禁;覆盖主题、导入 / 导出、备注额度和应用排序持久化。
- - `ProEntitlementConfig`:一次性买断商品 ID、免费 + Pro 首个版本、免费主题集合、免费备注额度和 QA 环境变量的单一配置点。
+ - `ProEntitlementPolicy`:数据层可同步调用的 Pro 门禁;覆盖主题、彩色容器 / 彩色网格显示模式、导入 / 导出、备注额度、自定义标签颜色、自定义快捷键和应用排序持久化。
+ - `ProEntitlementConfig`:一次性买断商品 ID、免费 + Pro 首个版本、免费主题集合、免费 3 条备注额度和 QA 环境变量的单一配置点。
- `ProThemePreviewState` 可携带临时炫彩调色值;免费预览期间只写全局快照,不写真实 `UserDefaults`。
+ - `ProDisplayModePreviewState` 复用 Pro 主题 5 分钟体验时长;免费试用彩色容器 / 彩色网格时只写 `previewDisplayMode` 快照,过期或离开试用后按 `coloredContainer -> container`、`coloredGridContainer -> gridContainer` 回落。
- `src/Apptag/ProAccessViews.swift`
- `ProStatusPill`:高级功能入口的小型 Pro 胶囊;Pro / 已锁定高级功能使用金色皇冠体系,免费状态使用中性胶囊。
- `ProUpgradePromptView`:功能被锁时的统一解锁提示,购买 / 恢复动作由调用方闭包绑定。
- `src/Apptag/AppGridSupport.swift`
- 图标气泡、基础 metrics、气泡 placement 支撑。
- `src/Apptag/TagNavigationView.swift`
- - AppKit 标签导航栏,支持标签 hover 滚动、选中、拖放、双击进入标签设置页。
+ - AppKit 标签导航栏,支持标签 hover 滚动、选中、拖放、双击进入标签设置页;标签按钮颜色优先使用 `TagDef.customColor`。
- `src/Apptag/AppDragCoordinator.swift`
- 全局拖拽目标注册、命中判断、容器间拖放、容器外空白移除标签。
- 拖到容器外/容器之间空白区域时显示 Core Animation 碎纸预览;容器内部空白不触发解除标签预览。
@@ -74,9 +83,12 @@
- `AppInfo`:应用模型。
- `AppDisplayNameResolver`:多语言应用显示名解析。
- `AppIndexer`:扫描 `/Applications` 等应用来源,处理 bundle / wrapper / localized display name。
- - `TagGroup` / `TagColor`:标签分组与颜色。
+ - `TagGroup` / `TagColor` / `TagCustomColor`:标签分组、基础色和可选 sRGB 自定义色;`TagDef.customColor` 为可选字段,旧 JSON 缺字段时保持兼容。
- `TagDatabase`:标签、备注、隐藏状态、分类方案、导入导出、备份和持久化。
- - `TagEditor`:把数据库中的标签/备注/隐藏状态标注回扫描到的 App 列表。
+ - `TagEditor`:把数据库中的标签/备注/隐藏状态标注回扫描到的 App 列表;`setCustomColor` 是写入自定义标签颜色的唯一数据层入口,必须先过 Pro gate,基础色切换会清除自定义色。
+- `src/Apptag/TagEditorView.swift`
+ - 标签设置页编辑器,负责新建、重命名、删除、基础色选择和自定义颜色入口。
+ - 自定义颜色入口显示为横向色条叠加白色线型皇冠 Pro 图标,不显示“自定义颜色”文字;免费态点击只触发 Pro 提示,Pro 态继续通过 macOS 原生 `ColorPicker` / color well 打开颜色选择。
- `src/Apptag/AppLibraryController.swift`
- App 刷新、SmartStart 应用、系统分类方案应用、重置未分类等业务入口。
- 持有最近一次完整 `AppLibrarySnapshot`,供新建 overlay 立即复用。
@@ -92,8 +104,20 @@
- `LauncherHotkey` / `LauncherHotkeyKind`:主面板和 Quick Search 快捷键定义。
- `LauncherHotkeyRegistrationStore`:快捷键注册状态持久化。
- `QuickSearchDocument` / `QuickSearchEngine`:搜索索引与排序。
- - `QuickSearchPanelPresentationView` / `QuickSearchOverlayView` / `QuickSearchResultListHostView`:Quick Search 浮层 UI 与结果列表。
+ - `QuickSearchPanelPresentationView` / `QuickSearchOverlayView` / `QuickSearchResultListHostView`:Quick Search 浮层 UI 与结果列表;Quick Search 面板必须是可成为 key 的激活面板,不能使用 `.nonactivatingPanel`,否则 Return 可能落到前一个前台 App。
+ - `QuickSearchPanel.sendEvent` 对左键点击做 AppKit 层兜底:先通过 `hitTest` 解析 `QuickSearchResultRowView`,失败时按窗口坐标递归扫描结果行几何命中,并走同一启动路径,避免 SwiftUI / NSHostingView / NSScrollView 层级吞掉候选行点击。
- `QuickSearchResultRowView`:结果行内部文字、图标、标签区域统一命中到整行,保证点击任意可见区域都能启动并关闭浮层。
+ - `QuickSearchTextField` 同时保留 field editor command delegate 和 `NSControl.target/action` submit fallback,保证 Return / Enter 都能进入 `.submit`。
+- `src/Apptag/LauncherHotkeySettings.swift`
+ - `LauncherHotkeySettings`:Pro 自定义全局快捷键的存储、有效值、结构校验、系统保留组合和内部重复校验事实源。
+ - 自定义快捷键存储命名空间为 `customHotkeys.v1`;免费用户、无效保存值或内部重复值都回退内置默认快捷键。
+ - 修饰键校验允许 Option-only(例如 `Option+Space`),仍拒绝无修饰键、Shift-only,以及 Fn-only 非 Space。
+ - `effectiveHotkey(for:)` 不调用公开 `validationError(for:)`,避免重复校验递归。
+ - Carbon 的 F1-F12 keyCode 不连续,支持性判断必须使用显式 `functionKeyCodes` 集合,不能写 `kVK_F1...kVK_F12` 范围。
+- `src/Apptag/ApptagApp.swift`
+ - `registerConfiguredHotkeys()` 只注册 `LauncherHotkeySettings.effectiveHotkey(for:)`。
+ - `applyCustomHotkey(_:for:)` / `restoreDefaultHotkey(for:)` 是设置页写入自定义快捷键和恢复默认的唯一入口;候选快捷键必须先 Carbon 注册成功,再替换旧 ref 并持久化。
+ - 设置页录制自定义快捷键期间,`suspendConfiguredHotkeysForRecording()` 会临时注销主面板和 Quick Search 全局快捷键;录制成功、失败、取消、切 tab、窗口消失或 Pro 权益变更时通过 `resumeConfiguredHotkeysAfterRecording()` 恢复 effective hotkeys。
## 智能分类与 Apple 默认应用资料
@@ -157,6 +181,14 @@
- Quick Search 应用显示名回归。
- `src/Scripts/quick_search_system_app_qa.sh`
- Quick Search 系统应用回归。
+- `src/Scripts/quick_search_launch_contract_qa.sh`
+ - Quick Search 启动路径静态门禁;检查 in-app mouse monitor 不吞结果行点击、面板是激活 key panel、panel-level `sendEvent` 点击兜底存在、Return submit fallback 存在、点击 / submit 都接到 `NSWorkspace.openApplication` 启动路径。
+- `src/Scripts/pro_custom_hotkeys_qa.sh`
+ - Pro 自定义快捷键静态与 Carbon 运行时门禁;检查 Pro gate、录制期间暂停/恢复全局快捷键、事务式注册保存、重复校验、禁用重权限键盘 API、设置页 Pro 按钮组合和 29 语种文案。
+- `src/Scripts/pro_tag_custom_color_qa.sh`
+ - Pro 自定义标签颜色门禁;检查 `TagCustomColor` 数据模型、`TagDef.customColor` 兼容字段、Pro gate、原生颜色选择器、免费态 Pro 提示、基础色回退、横向皇冠色条入口和 AppGrid/标签导航显示传播。
+- `src/Scripts/pro_notes_quota_qa.sh`
+ - 免费 3 条应用备注 / Pro 无限备注门禁;检查新增第 4 条备注拦截、编辑已有备注不占额度、删除释放额度,以及界面文案不再出现旧 5 条额度。
- `src/Scripts/tag_navigation_hover_scroll_qa.sh`
- 标签导航 hover 滚动回归。
- `src/Scripts/tag_double_click_preferences_qa.sh`
@@ -164,11 +196,13 @@
- `src/Scripts/theme_settings_qa.sh`
- 8 个主题、Theme tab、旧深色偏好迁移、编辑模式默认浅色 override、29 语种主题文案回归。
- `src/Scripts/pro_localization_qa.sh`
- - Pro 文案 29 语种静态门禁;检查 `pro.*` 键完整、占位符完整、无生成污染和非英文语言无英文兜底复制。
+ - Pro 文案 29 语种静态门禁;检查 `pro.*`、设置页 Pro 状态/对比表、自定义标签颜色、Quick Search 快捷键页和气泡提示设置键完整、占位符完整、无生成污染和非英文语言无英文兜底复制。
- `src/Scripts/pro_feature_gate_qa.sh`
- - Pro 功能源码门禁;检查 StoreKit 权益、老用户自动 Pro、主题门禁、导入导出硬拦截、备注额度、排序预览和 Pro UI 提示。
+ - Pro 功能源码门禁;检查 StoreKit 权益、老用户自动 Pro、主题门禁、导入导出硬拦截、3 条备注额度、自定义标签颜色、自定义快捷键、排序预览、Pro UI 提示、设置页线型图标、轻量 Pro 权益行、Pro 页签、免费列“不支持”状态和 About 页不回归 Pro 汇总卡。
- `src/Scripts/pro_theme_preview_countdown_qa.sh`
- - Pro 主题预览倒计时门禁;检查状态行倒计时、当前预览卡片 `MM:SS`、到期清理、29 语种 `%time%` 占位符和禁止写死体验时长。
+ - Pro 主题 / 彩色显示模式预览倒计时门禁;检查状态行倒计时、当前预览卡片 `MM:SS`、到期清理、29 语种 `%time%` 占位符和禁止写死体验时长。
+- `src/Scripts/pro_display_mode_preview_qa.sh`
+ - Pro 彩色显示模式门禁;检查彩色容器 / 彩色网格锁定、免费态 effective 回落、5 分钟不落盘试用、设置页 Pro badge / 倒计时固定槽位和 AppGrid effective 渲染。
- `src/Scripts/appgrid_startup_loading_qa.sh`
- AppGrid 快照复用和延迟转圈回归。
- `src/Scripts/url_scheme_activation_qa.sh`
@@ -188,7 +222,8 @@
- 不得把主题、视觉偏好、窗口状态混入 `TagDatabase` 的分类/标签业务数据。
- 主题变化只允许影响 AppGrid 视觉,不得改变标签数据、排序、备注、SmartStart/category scheme、Quick Search、拖拽语义或导入导出。
- Pro 门禁不得写脏免费用户真实数据:主题预览不写 `appGridThemeID`,排序预览不写 `containerAppOrder`,第 6 个新备注不写 `appNotes` / `appNoteMetadata`,导入 / 导出拦截必须早于文件面板和文件读写。
-- Pro 升级 / 权益卡应放在 About tab;Data tab 不承载 Pro 营销卡,避免挤压数据管理布局。
+- 自定义标签颜色是 Pro 功能:免费用户可继续使用基础色,已有自定义色继续显示,不能新增或修改为新自定义色;改回基础色必须允许且会清除 `customColor`。
+- Pro 状态 UI 必须优先使用设置页签下方固定位置的统一 header;不得在各 tab 内重复塞第二条 Pro 引导。About 不承载 Pro 汇总卡或免费 / Pro 差异说明,Data 不承载营销式大卡,避免挤压数据管理布局。
- 免费主题固定为默认、深蓝、黑色;其它主题只能预览或在 Pro 解锁后持久化。
- `originalAppVersion` 早于免费 + Pro 首个版本的历史用户必须自动获得 Pro;`originalPurchaseDate` 只能作为版本不可判断时的兜底。
- 默认主题必须保留原浅色毛玻璃 AppGrid。
@@ -199,6 +234,8 @@
- AppGrid 启动或重开不应因为新 `ContentView` 初始 `allApps.isEmpty` 立刻显示转圈;应先复用最近一次完整快照,并延迟显示 loading。
- Quick Search 显示标题应优先使用解析后的 `AppInfo.displayName`,内部 bundle 名只作为搜索字段。
- Quick Search 结果行内部文字 / 图标区域不得吞掉点击;点中行内任意可见区域都应按结果启动路径处理。
+- Quick Search 打开后必须可靠接收键盘;面板不得是 non-activating panel,展示时必须激活 App 并成为 key window,Return / Enter 必须通过 command delegate 或 target/action fallback 进入 submit。
+- Quick Search 打开期间,本地 mouse monitor 不得吞掉 TagLauncher overlayWindow 内部事件;外部点击可关闭 Quick Search,结果行点击必须通过 `QuickSearchResultRowView.mouseDown` 或 `QuickSearchPanel.sendEvent` 兜底进入同一启动路径;panel 级兜底不得只依赖 `hitTest`,必须保留窗口坐标递归几何命中结果行的路径。
- Quick Search-only 点击 TagLauncher 自身结果必须关闭浮层,不得重新打开 AppGrid。
- Apple 默认应用备注必须按当前语言显示,不允许 A 语言出现 B 语言备注。
- SmartStart/default system tag 初始化标签必须按当前语言显示;升级用户启动后应重刷带 `systemCategoryID` 的系统标签,不能长期保留旧英文初始化标签。
diff --git a/CODE_GOVERNANCE.md b/CODE_GOVERNANCE.md
index 553d6ed..2305e7f 100644
--- a/CODE_GOVERNANCE.md
+++ b/CODE_GOVERNANCE.md
@@ -132,7 +132,55 @@
- 迁移、发布、构建任务必须记录可复核证据:版本/build、执行命令、关键结果、产物路径、hash 或 QA 报告。
- QA 失败不能只口头解释;必须判断是产品回归、脚本断言问题、环境问题还是迁移无关问题,并记录结论。
-## 10. 命令输出保护
+## 10. UI Preview Gate
+
+TagLauncher 的 UI 工作必须先确认视觉目标,再修改生产 SwiftUI / AppKit 源码。经验复盘见:
+
+`/Users/ar/Projects/Taglauncher/Docs/KM2.项目管理-非业务直接相关/关于TagLauncher所有UI类问题的经验与教训.md`
+
+### 10.1 触发范围
+
+以下变更默认属于非平凡 UI 改动,必须先过本门禁:
+
+- AppGrid、Settings、Theme、Pro、Quick Search、usage tips、弹窗、窗口尺寸、菜单栏、hover bubble、拖拽、点击热区或可访问性变化。
+- 布局、字号、字重、行高、间距、颜色、主题 token、material、阴影、图标、文案长度、状态提示或空态变化。
+- 会影响截图、录屏、App Store 展示、发布说明、QA 截图 smoke 或用户验收观感的变化。
+
+纯只读调查、日志定位、静态文本检索或不接触生产 UI 源码的 throwaway 原型,可以暂不进入完整门禁,但必须明确“不修改生产 UI 源码”。
+
+### 10.2 UI 合约
+
+非平凡 UI 改动开工前必须先写 UI 合约。推荐模板:
+
+`/Users/ar/Projects/Taglauncher/Docs/KM2.项目管理-非业务直接相关/UI合约模板.md`
+
+如果当前任务已有 PRD、TODO、Round 文档或 issue,也可以在该文档中写入同等字段,不强制复制模板。UI 合约至少包含:
+
+- 目标界面:目标截图、标注、Penpot / Figma frame、baoyu-design HTML / 静态 screen,或等价可审阅预览。
+- 影响 surface:具体窗口、tab、弹窗、AppGrid 区域、Quick Search 区域、tips、Pro 入口或 release screenshot。
+- 不做范围:本轮明确不改的视觉、交互、文案、数据、状态和旧行为。
+- 状态矩阵:free / Pro / legacy Pro / preview / expired / purchase pending / cancel / fail / restore fail 等相关状态。
+- 主题和语言长度矩阵:默认、黑色、深蓝、亮色、暗色炫彩、亮色炫彩,以及长语种、长标签、长备注、价格、倒计时等文本压力。
+- 交互互斥关系:tips vs 图标点击、hover scroll vs hover bubble、sorting vs empty drop、Quick Search only vs AppGrid tips、modal vs backdrop dismiss、theme preview vs persistent theme、Pro preview vs real Pro state。
+- 验收证据:需要产出的真实 App 截图、录屏、AX 读取、真实鼠标点击 / hover / 拖拽 / 滚动证据,以及对应保存路径。
+
+### 10.3 高保真预览与用户确认
+
+- 非纯调查任务必须先产出高保真预览,再进入生产 UI 源码修改。
+- 高保真预览可以来自 baoyu-design HTML / 静态 screen、Penpot / Figma frame、用户标注图、真实 App 参考截图或等价可审阅 artifact。
+- Agent 可以先产出 2-3 个候选预览;候选未被用户确认前,只能标记为 preview / candidate / experiment。
+- 用户确认视觉目标后,才允许修改 SwiftUI / AppKit 生产源码;确认范围只覆盖被确认的 surface、状态和不做范围。
+- 如果为了验证可行性需要写 throwaway 原型,必须放在非生产路径并注明不可直接发布;不得把实验代码混入正式 App 源码。
+
+### 10.4 实现与视觉验收
+
+- 实现必须保护 UI 合约的不做范围,不得借 UI 修复顺手重写已验收视觉、交互或文案。
+- 静态 QA、构建通过、脚本 PASS 只能证明静态条件,不等于视觉通过。
+- 视觉 PASS 必须有真实渲染或真实交互证据:真实 App 截图、录屏、AX 窗口 / 控件读取、真实点击、hover、拖拽、滚动或 Esc / 外部点击证据。
+- 缺少哪类证据就如实记录缺口;不得用静态 QA 替代截图、录屏、AX 或真实点击证据。
+- 用户判定视觉倒退时,必须保留失败结论;失败候选不得进入正式发布候选,不得写成防回退 QA。
+
+## 11. 命令输出保护
任何未知或可能很大的命令输出都必须 byte-cap:
@@ -144,7 +192,7 @@
- 搜索优先用 `rg` / `rg --files`。
- 不无上限打印大文件、构建日志、目录树或二进制信息。
-## 11. 禁止事项
+## 12. 禁止事项
- 禁止在 `src/` 外新增 App 源码副本。
- 禁止用外部目录长期承载源码开发。
@@ -153,8 +201,9 @@
- 禁止把证书、账号、用户数据、临时 build 缓存提交进 Git。
- 禁止把阶段性通过当成整体完成;仍有明确未完成项时必须继续推进。
- 禁止没有 QA 证据就声称可交付。
+- 禁止非平凡 UI 改动跳过 UI 合约、高保真预览、用户视觉确认或真实渲染 / 交互证据。
-## 12. 常用检查命令
+## 13. 常用检查命令
```bash
git status --short 2>&1 | head -c 6000
diff --git a/src/Apptag/AppDefaults.swift b/src/Apptag/AppDefaults.swift
index fe71510..6e62000 100644
--- a/src/Apptag/AppDefaults.swift
+++ b/src/Apptag/AppDefaults.swift
@@ -7,7 +7,7 @@
static let tagFontSize: Double = 22
static let iconSize: Double = 56
static let tagPosition = "right"
- static let displayMode = "coloredGridContainer"
+ static let displayMode = "gridContainer"
static let hideAppNames = true
static let showDockIcon = true
static let launchAtLogin = true
diff --git a/src/Apptag/AppGridCollectionView.swift b/src/Apptag/AppGridCollectionView.swift
index 8807590..ba2b864 100644
--- a/src/Apptag/AppGridCollectionView.swift
+++ b/src/Apptag/AppGridCollectionView.swift
@@ -48,6 +48,7 @@
struct AppGridCollectionView: NSViewRepresentable {
let groups: [TagGroup]
let tagColors: [String: Int]
+ let tagCustomColors: [String: TagCustomColor]
let displayMode: String
let iconSize: CGFloat
let showNames: Bool
@@ -89,6 +90,7 @@
context.coordinator.update(
groups: groups,
tagColors: tagColors,
+ tagCustomColors: tagCustomColors,
displayMode: displayMode,
iconSize: iconSize,
showNames: showNames,
@@ -122,6 +124,7 @@
final class Coordinator: NSObject, NSCollectionViewDataSource, NSCollectionViewDelegate {
var groups: [TagGroup] = []
var tagColors: [String: Int] = [:]
+ var tagCustomColors: [String: TagCustomColor] = [:]
var displayMode = AppDefaults.displayMode
var iconSize: CGFloat = AppDefaults.iconSize
var showNames = true
@@ -164,6 +167,7 @@
func update(
groups: [TagGroup],
tagColors: [String: Int],
+ tagCustomColors: [String: TagCustomColor],
displayMode: String,
iconSize: CGFloat,
showNames: Bool,
@@ -193,6 +197,7 @@
) {
self.groups = groups
self.tagColors = tagColors
+ self.tagCustomColors = tagCustomColors
self.displayMode = displayMode
self.iconSize = iconSize
self.showNames = showNames
@@ -225,6 +230,7 @@
let nextSignature = Self.signature(
tagColors: tagColors,
+ tagCustomColors: tagCustomColors,
displayMode: displayMode,
iconSize: iconSize,
showNames: showNames,
@@ -401,6 +407,7 @@
private static func signature(
tagColors: [String: Int],
+ tagCustomColors: [String: TagCustomColor],
displayMode: String,
iconSize: CGFloat,
showNames: Bool,
@@ -413,6 +420,10 @@
.sorted { $0.key < $1.key }
.map { "\($0.key)=\($0.value)" }
.joined(separator: ",")
+ let customColorPart = tagCustomColors
+ .sorted { $0.key < $1.key }
+ .map { "\($0.key)=\($0.value.signature)" }
+ .joined(separator: ",")
return [
displayMode,
"\(Int(iconSize.rounded()))",
@@ -421,8 +432,16 @@
showUncommonAppBubbles ? "uncommon" : "allbubbles",
"bottom=\(Int(bottomContentPadding.rounded()))",
colorPart,
+ customColorPart,
"rev=\(contentRevision)"
].joined(separator: "|")
+ }
+
+ func tagColor(for groupName: String) -> NSColor {
+ TagColor.nsColor(
+ for: tagColors[groupName] ?? 0,
+ customColor: tagCustomColors[groupName]
+ )
}
private static func clampedUsageTipIndex(_ index: Int, tips: [AppGridUsageTip]) -> Int {
@@ -2325,7 +2344,7 @@
override func draw(_ dirtyRect: NSRect) {
guard let coordinator, let group else { return }
let displayStyle = coordinator.displayStyle
- let tagColor = TagColor.nsColor(for: coordinator.tagColors[group.name] ?? 0)
+ let tagColor = coordinator.tagColor(for: group.name)
let isNavigationHighlighted = coordinator.highlightedGroupName == group.name
let isColorlessActive = coordinator.isColorlessContainerMode
&& (isHovered || isNavigationHighlighted)
@@ -2571,7 +2590,7 @@
let shouldShadow = coordinator.displayStyle.usesCardSurface
&& ((coordinator.isColoredContainerMode && (isHovered || isNavigationHighlighted)) || isColorlessActive)
if coordinator.appGridTheme.usesDarkGlass && coordinator.displayStyle.usesCardSurface {
- let tagColor = TagColor.nsColor(for: coordinator.tagColors[group?.name ?? ""] ?? 0)
+ let tagColor = coordinator.tagColor(for: group?.name ?? "")
let active = isHovered || isNavigationHighlighted
layer?.shadowColor = active
? tagColor.withAlphaComponent(0.82).cgColor
diff --git a/src/Apptag/ApptagApp.swift b/src/Apptag/ApptagApp.swift
index 8ce54cd..0166772 100644
--- a/src/Apptag/ApptagApp.swift
+++ b/src/Apptag/ApptagApp.swift
@@ -34,6 +34,8 @@
}
final class AppDelegate: NSObject, NSApplicationDelegate, NSMenuDelegate {
+ static private(set) weak var shared: AppDelegate?
+
private static let showDockIconKey = "showDockIcon"
private static let statusItemAutosaveName = AppIdentity.statusItemAutosaveName
private static let statusItemButtonIdentifier = NSUserInterfaceItemIdentifier("TagLauncherStatusItemButton")
@@ -63,6 +65,7 @@
private var quickSearchHotkeyRef: EventHotKeyRef?
private var overlaySpaceHotkeyRef: EventHotKeyRef?
private var hotkeyEventHandlerInstalled = false
+ private var configuredHotkeysSuspendedForRecording = false
private var isQuickSearchOpen = false
private var quickSearchShouldHideOverlayOnClose = false
private var quickSearchOnlyOverlaySession = false
@@ -77,6 +80,11 @@
private var overlayOpenedByQuickSearchOnly = false
private var didFinishLaunching = false
private var pendingShowOverlayInvocation = false
+
+ override init() {
+ super.init()
+ Self.shared = self
+ }
private lazy var overlayController = OverlayWindowController(
dependencies: OverlayWindowController.Dependencies(
@@ -1273,9 +1281,23 @@
// MARK: - Global Hotkeys
private func registerConfiguredHotkeys() {
+ guard !configuredHotkeysSuspendedForRecording else { return }
installHotkeyEventHandlerIfNeeded()
registerEffectiveHotkey(.main)
registerEffectiveHotkey(.quickSearch)
+ }
+
+ func suspendConfiguredHotkeysForRecording() {
+ guard !configuredHotkeysSuspendedForRecording else { return }
+ configuredHotkeysSuspendedForRecording = true
+ unregisterHotkey(for: .main)
+ unregisterHotkey(for: .quickSearch)
+ }
+
+ func resumeConfiguredHotkeysAfterRecording() {
+ guard configuredHotkeysSuspendedForRecording else { return }
+ configuredHotkeysSuspendedForRecording = false
+ registerConfiguredHotkeys()
}
private func registerEffectiveHotkey(_ kind: LauncherHotkeyKind) {
@@ -1918,12 +1940,7 @@
) { [weak self] event in
guard let self, self.isQuickSearchOpen else { return event }
if event.window === self.overlayWindow {
- NotificationCenter.default.post(
- name: .tagLauncherQuickSearchDismissRequested,
- object: nil,
- userInfo: ["source": QuickSearchDismissSource.mouse]
- )
- return nil
+ return event
}
return event
}
@@ -1986,7 +2003,7 @@
}
@objc private func openProStatusFromStatusMenu(_ sender: NSMenuItem) {
- openPreferences(targetTab: SettingsTabTarget.about)
+ openPreferences(targetTab: SettingsTabTarget.pro)
}
private func openPreferences(targetTab: String?) {
diff --git a/src/Apptag/ContentView.swift b/src/Apptag/ContentView.swift
index 743ec5f..4a9cd47 100644
--- a/src/Apptag/ContentView.swift
+++ b/src/Apptag/ContentView.swift
@@ -19,6 +19,7 @@
static let theme = "theme"
static let tags = "tags"
static let data = "data"
+ static let pro = "pro"
static let about = "about"
}
@@ -214,19 +215,21 @@
struct TagPill: View {
let name: String
let colorIndex: Int
+ var customColor: TagCustomColor? = nil
var dragModeActive: Bool = false
var isDragging: Bool = false
let action: () -> Void
+ private var resolvedNSColor: NSColor {
+ TagColor.nsColor(for: colorIndex, customColor: customColor)
+ }
+
private var bgColor: Color {
- Color(nsColor: TagColor.nsColor(for: colorIndex))
+ Color(nsColor: resolvedNSColor)
}
private var textColor: Color {
- if colorIndex == 0 || colorIndex == 5 {
- return .primary
- }
- return .white
+ TagColor.prefersDarkText(for: resolvedNSColor) ? .primary : .white
}
var body: some View {
@@ -253,15 +256,21 @@
struct SideTagPill: View {
let name: String
let colorIndex: Int
+ var customColor: TagCustomColor? = nil
var dragModeActive: Bool = false
var isDragging: Bool = false
let action: () -> Void
- private var bgColor: Color {
- Color(nsColor: TagColor.nsColor(for: colorIndex))
+ private var resolvedNSColor: NSColor {
+ TagColor.nsColor(for: colorIndex, customColor: customColor)
}
+
+ private var bgColor: Color {
+ Color(nsColor: resolvedNSColor)
+ }
+
private var textColor: Color {
- colorIndex == 0 || colorIndex == 5 ? .primary : .white
+ TagColor.prefersDarkText(for: resolvedNSColor) ? .primary : .white
}
var body: some View {
@@ -376,6 +385,7 @@
@State private var allApps: [AppInfo] = []
@State private var displayGroups: [TagGroup] = []
@State private var tagColors: [String: Int] = [:]
+ @State private var tagCustomColors: [String: TagCustomColor] = [:]
@State private var tagDefinitions: [String: TagDatabase.TagDef] = [:]
@State private var containerAppOrder: [String: [String]] = [:]
@State private var groupLayoutVersion = 0
@@ -499,6 +509,10 @@
)
}
+ private var renderedDisplayMode: String {
+ ProEntitlementPolicy.effectiveDisplayMode(for: displayMode)
+ }
+
private func storedThemeTuning(for theme: AppGridTheme) -> Double? {
switch theme {
case .deepBlue:
@@ -519,7 +533,7 @@
}
private var isColorlessContainerMode: Bool {
- displayMode == "container" || displayMode == "gridContainer"
+ renderedDisplayMode == "container" || renderedDisplayMode == "gridContainer"
}
private var shouldShowUsageTips: Bool {
@@ -740,6 +754,8 @@
// Always sync tag list from database when entering edit mode
let store = TagDatabase.load()
tagColors = store.tags.mapValues { $0.color }
+ tagCustomColors = store.tags.compactMapValues { $0.customColor }
+ tagDefinitions = store.tags
draggedTagNames = TagEditor.orderedTagNames()
}
editPhase = phase
@@ -1185,6 +1201,7 @@
HStack(spacing: 8) {
ForEach(tagLabels) { tag in
TagPill(name: tag.name, colorIndex: tag.colorIndex,
+ customColor: tag.customColor,
dragModeActive: tagNavDragModeActive && canReorderTag(tag.name),
isDragging: tagNavDragItem == tag.name,
action: {
@@ -1212,6 +1229,7 @@
VStack(spacing: 6) {
ForEach(tagLabels) { tag in
SideTagPill(name: tag.name, colorIndex: tag.colorIndex,
+ customColor: tag.customColor,
dragModeActive: tagNavDragModeActive && canReorderTag(tag.name),
isDragging: tagNavDragItem == tag.name,
action: {
@@ -1249,7 +1267,8 @@
AppGridCollectionView(
groups: displayGroups,
tagColors: tagColors,
- displayMode: displayMode,
+ tagCustomColors: tagCustomColors,
+ displayMode: renderedDisplayMode,
iconSize: iconSize,
showNames: !hideAppNames,
appGridTheme: renderedAppGridTheme,
@@ -1376,7 +1395,10 @@
TagEditorView(
tagColors: $tagColors,
+ tagCustomColors: $tagCustomColors,
excludedTagNames: ["Mac自带", defaultGroupName],
+ isCustomColorUnlocked: proEntitlement.isUnlocked,
+ onLockedCustomColor: { presentProPrompt(for: .customTagColors) },
onRefresh: { refreshApps() }
)
}
@@ -2009,7 +2031,13 @@
}
private var tagLabels: [TagNavigationItem] {
- displayGroups.map { TagNavigationItem(name: $0.name, colorIndex: tagColors[$0.name] ?? 0) }
+ displayGroups.map {
+ TagNavigationItem(
+ name: $0.name,
+ colorIndex: tagColors[$0.name] ?? 0,
+ customColor: tagCustomColors[$0.name]
+ )
+ }
}
private var editGroups: [TagGroup] {
@@ -2229,6 +2257,10 @@
if let preview = proEntitlement.themePreviewState {
appGridThemeID = preview.theme.rawValue
proEntitlement.stopThemePreview()
+ }
+ if let preview = proEntitlement.displayModePreviewState {
+ displayMode = preview.displayMode
+ proEntitlement.stopDisplayModePreview()
}
let hadPrompt = appGridInteraction.proPrompt != nil
@@ -2946,6 +2978,7 @@
quickSearchDocuments = snapshot.quickSearchDocuments
tagColors = snapshot.tagColors
tagDefinitions = snapshot.tagDefinitions
+ tagCustomColors = snapshot.tagDefinitions.compactMapValues { $0.customColor }
containerAppOrder = snapshot.containerAppOrder
draggedTagNames = snapshot.tagOrder
rebuildDisplayGroups(apps: snapshot.apps, tagOrder: snapshot.tagOrder)
diff --git a/src/Apptag/DataLayer.swift b/src/Apptag/DataLayer.swift
index 1357d95..2a23bbd 100644
--- a/src/Apptag/DataLayer.swift
+++ b/src/Apptag/DataLayer.swift
@@ -237,6 +237,52 @@
// MARK: - Tag Color Mapping
+struct TagCustomColor: Codable, Equatable {
+ var red: Double
+ var green: Double
+ var blue: Double
+ var alpha: Double
+
+ init(red: Double, green: Double, blue: Double, alpha: Double = 1.0) {
+ self.red = Self.clamp(red)
+ self.green = Self.clamp(green)
+ self.blue = Self.clamp(blue)
+ self.alpha = Self.clamp(alpha)
+ }
+
+ init(nsColor: NSColor) {
+ let rgbColor = nsColor.usingColorSpace(.sRGB) ?? nsColor
+ self.init(
+ red: Double(rgbColor.redComponent),
+ green: Double(rgbColor.greenComponent),
+ blue: Double(rgbColor.blueComponent),
+ alpha: Double(rgbColor.alphaComponent)
+ )
+ }
+
+ var nsColor: NSColor {
+ NSColor(
+ srgbRed: CGFloat(red),
+ green: CGFloat(green),
+ blue: CGFloat(blue),
+ alpha: CGFloat(alpha)
+ )
+ }
+
+ var signature: String {
+ [
+ String(format: "%.4f", red),
+ String(format: "%.4f", green),
+ String(format: "%.4f", blue),
+ String(format: "%.4f", alpha)
+ ].joined(separator: ":")
+ }
+
+ private static func clamp(_ value: Double) -> Double {
+ min(1.0, max(0.0, value))
+ }
+}
+
enum TagColor {
static func nsColor(for index: Int) -> NSColor {
switch index {
@@ -251,6 +297,20 @@
default: return NSColor.systemGray
}
}
+
+ static func nsColor(for index: Int, customColor: TagCustomColor?) -> NSColor {
+ customColor?.nsColor ?? nsColor(for: index)
+ }
+
+ static func prefersDarkText(for color: NSColor) -> Bool {
+ let rgbColor = color.usingColorSpace(.sRGB) ?? color
+ let red = Double(rgbColor.redComponent)
+ let green = Double(rgbColor.greenComponent)
+ let blue = Double(rgbColor.blueComponent)
+ let luminance = (0.299 * red) + (0.587 * green) + (0.114 * blue)
+ return luminance > 0.62
+ }
+
static let allIndices: [Int] = [1, 2, 3, 4, 5, 6, 7]
}
@@ -963,6 +1023,7 @@
struct TagDef: Codable, Equatable {
var color: Int
var systemCategoryID: SmartCategoryID? = nil
+ var customColor: TagCustomColor? = nil
}
struct Store: Codable {
@@ -2287,6 +2348,7 @@
let previousStore = store
var tagDef = store.tags[tag] ?? TagDatabase.TagDef(color: color, systemCategoryID: nil)
tagDef.color = color
+ tagDef.customColor = nil
store.tags[tag] = tagDef
TagDatabase.saveUserCategorySchemeMutation(
store,
@@ -2294,4 +2356,23 @@
reason: "set-tag-color"
)
}
+
+ /// Set a Pro custom color for a tag without changing its fallback base color.
+ @discardableResult
+ static func setCustomColor(_ customColor: TagCustomColor, for tag: String) -> Bool {
+ guard ProEntitlementPolicy.isUnlocked(.customTagColors) else {
+ return false
+ }
+ var store = TagDatabase.load()
+ let previousStore = store
+ var tagDef = store.tags[tag] ?? TagDatabase.TagDef(color: 0, systemCategoryID: nil)
+ tagDef.customColor = customColor
+ store.tags[tag] = tagDef
+ TagDatabase.saveUserCategorySchemeMutation(
+ store,
+ previous: previousStore,
+ reason: "set-tag-custom-color"
+ )
+ return true
+ }
}
diff --git a/src/Apptag/Info.plist b/src/Apptag/Info.plist
index 0d72ecf..8a3d01b 100644
--- a/src/Apptag/Info.plist
+++ b/src/Apptag/Info.plist
@@ -19,7 +19,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>8.2.1</string>
+ <string>8.2.8</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
- <string>20260628.2354</string>
+ <string>20260630.0128</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
diff --git a/src/Apptag/LauncherHotkeySettings.swift b/src/Apptag/LauncherHotkeySettings.swift
index f638260..8040faa 100644
--- a/src/Apptag/LauncherHotkeySettings.swift
+++ b/src/Apptag/LauncherHotkeySettings.swift
@@ -50,6 +50,10 @@
private static let allowedModifierMask = UInt32(
controlKey | optionKey | shiftKey | cmdKey | kEventKeyModifierFnMask
)
+ private static let functionKeyCodes: Set<Int> = [
+ kVK_F1, kVK_F2, kVK_F3, kVK_F4, kVK_F5, kVK_F6,
+ kVK_F7, kVK_F8, kVK_F9, kVK_F10, kVK_F11, kVK_F12
+ ]
static func defaultHotkey(for kind: LauncherHotkeyKind) -> LauncherHotkey {
kind.hotkey
@@ -185,7 +189,7 @@
private static func hasSupportedModifierCombination(_ hotkey: LauncherHotkey) -> Bool {
let modifiers = hotkey.modifiers & allowedModifierMask
guard modifiers != 0 else { return false }
- if modifiers == UInt32(shiftKey) || modifiers == UInt32(optionKey) {
+ if modifiers == UInt32(shiftKey) {
return false
}
if modifiers == UInt32(kEventKeyModifierFnMask) {
@@ -200,10 +204,9 @@
return true
case kVK_LeftArrow, kVK_RightArrow, kVK_UpArrow, kVK_DownArrow:
return true
- case kVK_F1...kVK_F12:
- return true
default:
- return LauncherHotkey.printableKeyCodes.contains(Int(keyCode))
+ let key = Int(keyCode)
+ return functionKeyCodes.contains(key) || LauncherHotkey.printableKeyCodes.contains(key)
}
}
diff --git a/src/Apptag/Localization/ar-Najdi.json b/src/Apptag/Localization/ar-Najdi.json
index ce4c4fe..d1a8eb1 100644
--- a/src/Apptag/Localization/ar-Najdi.json
+++ b/src/Apptag/Localization/ar-Najdi.json
@@ -8,8 +8,8 @@
"menu.language": "اللغة",
"menu.help": "المساعدة",
"menu.version": "الإصدار",
- "menu.proStatus.free": "أنت حالياً مستخدم مجاني (الترقية إلى Pro)",
- "menu.proStatus.unlocked": "أنت حالياً مستخدم Pro مميز",
+ "menu.proStatus.free": "أنت حاليًا مستخدم مجاني (الترقية الآن إلى 👑Pro)",
+ "menu.proStatus.unlocked": "أنت حاليًا مستخدم 👑Pro مميز",
"settings.language": "اللغة",
"settings.languagePicker": "لغة التطبيق:",
"settings.languageDesc": "اختر لغة القوائم والإعدادات.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "ما فيه نتائج تصنيف ذكي قابلة للتطبيق.",
"scheme.local": "المخطط المحلي",
"scheme.systemSmartStart": "مخطط البداية الذكي للنظام",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "إظهار تلميحات الفقاعات لـ:",
+ "settings.bubbleAllApps": "كل التطبيقات",
+ "settings.bubbleUncommonOnly": "التطبيقات غير الشائعة بس",
+ "quickSearch.title": "البحث السريع",
+ "quickSearch.placeholder": "ابحث في التطبيقات والوسوم والملاحظات",
+ "quickSearch.inputAccessibility": "حقل البحث السريع",
+ "quickSearch.emptyPrompt": "ابدأ بالكتابة عشان تبحث في التطبيقات والوسوم والملاحظات.",
+ "quickSearch.noResults": "ما لقينا تطبيقات.",
+ "quickSearch.launchFailed": "تعذر فتح هالتطبيق. جرّب مرة ثانية أو اختر تطبيق ثاني.",
+ "quickSearch.tagPrefix": "وسم",
+ "quickSearch.hotkeys": "اختصارات لوحة المفاتيح",
+ "quickSearch.mainHotkey": "قائمة التطبيقات",
+ "quickSearch.mainHotkeyDesc": "يفتح قائمة تطبيقات TagLauncher.",
+ "quickSearch.status.Active": "مفعّل",
+ "quickSearch.status.registrationFailed": "فشل التسجيل",
+ "quickSearch.status.unavailable": "الاختصار غير متاح",
+ "quickSearch.mainHotkeyUnavailableMessage": "ما نقدر نسجل %shortcut% الآن. يمكن يكون مستخدم من macOS أو طريقة إدخال أو تطبيق ثاني. اختصار قائمة التطبيقات غير متاح مؤقتًا. تحقق من اختصارات لوحة المفاتيح أو تعارضاتها، ثم أعد تشغيل TagLauncher. رمز الخطأ: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "ما نقدر نسجل %shortcut% الآن. يمكن يكون مستخدم من macOS أو طريقة إدخال أو تطبيق ثاني. البحث السريع العام غير متاح مؤقتًا. تحقق من اختصارات لوحة المفاتيح أو تعارضاتها، ثم أعد تشغيل TagLauncher. رمز الخطأ: %status%.",
+ "quickSearch.loading": "جارٍ تجهيز فهرس البحث…",
+ "quickSearch.internalHotkey": "البحث السريع (داخل TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "يشتغل بس وقائمة تطبيقات TagLauncher مفتوحة.",
+ "quickSearch.internalHotkeyStatus": "قائمة التطبيقات فقط",
+ "quickSearch.globalHotkey": "البحث السريع (عام)",
+ "quickSearch.globalHotkeyDesc": "افتح البحث السريع عامًا إذا قائمة تطبيقات TagLauncher غير ظاهرة.",
+ "quickSearch.spaceDisplay": "Space (مفتاح المسافة)",
"trackpadGesture.title": "إيماءة لوحة التعقب",
"trackpadGesture.description": "اربط إيماءة لوحة التعقب في أداة خارجية بهالرابط عشان تعرض قائمة التطبيقات.",
"trackpadGesture.status": "أداة خارجية",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "معاينة",
"pro.card.restore": "استعادة المشتريات",
- "pro.card.summary.free": "افتح السمات المميزة، واستيراد التخطيط وتصديره، وملاحظات غير محدودة، وفرز التطبيقات اليدوية المحفوظة.",
+ "pro.card.summary.free": "افتح ألوان الوسوم المخصصة والسمات المميزة واستيراد وتصدير التخطيط وملاحظات التطبيقات غير المحدودة والاختصارات المخصصة.",
"pro.card.summary.legacy": "شكرًا لدعم TagLauncher مبكرًا. وصول Pro لديك نشط بالفعل.",
- "pro.card.summary.unlocked": "Pro نشط على جهاز Mac هذا. السمات المميزة وأدوات التخطيط المتقدمة جاهزة.",
+ "pro.card.summary.unlocked": "Pro نشط على هذا الـ Mac. ألوان الوسوم والسمات المتقدمة والملاحظات غير المحدودة والاختصارات المخصصة وأدوات التخطيط جاهزة.",
"pro.card.title.free": "الترقية إلى Pro",
"pro.card.title.legacy": "مقفلة للمحترفين",
"pro.card.title.unlocked": "مقفلة للمحترفين",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "احفظ علاماتك الحالية وترتيبك وتخطيطك كنسخة احتياطية قابلة لإعادة الاستخدام.",
"pro.feature.import": "استيراد التخطيط",
"pro.feature.import.benefit": "قم باستعادة تخطيط TagLauncher المحفوظ على جهاز Mac هذا في خطوة واحدة.",
- "pro.feature.notes": "ملاحظات غير محدودة",
- "pro.feature.notes.benefit": "احفظ الملاحظات لكل تطبيق دون الحد المجاني المكون من 5 ملاحظات.",
+ "pro.feature.notes": "ملاحظات تطبيق مخصصة",
+ "pro.feature.notes.benefit": "تتضمن النسخة المجانية 3 ملاحظات تطبيق. يفتح Pro ملاحظات غير محدودة لكل التطبيقات.",
"pro.feature.sorting": "فرز التطبيقات المحفوظة",
"pro.feature.sorting.benefit": "احتفظ بترتيب التطبيق اليدوي بعد مغادرة وضع التحرير.",
"pro.feature.themes": "مواضيع متميزة",
"pro.feature.themes.benefit": "افتح جميع سمات App Grid المتقدمة واحتفظ بها بشكل دائم.",
- "pro.notes.limitReached": "يمكن للإصدار المجاني حفظ الملاحظات لما يصل إلى 5 تطبيقات. فتح Pro لحفظ الملاحظات غير المحدودة.",
+ "pro.notes.limitReached": "يمكن للنسخة المجانية حفظ حتى 3 ملاحظات تطبيق. افتح Pro لحفظ ملاحظات غير محدودة.",
"pro.notes.remaining": "يتضمن الإصدار المجاني %limit% ملاحظات للتطبيق. %remaining% المتبقية.",
"pro.operation.cancelled": "تم إلغاء الشراء.",
"pro.operation.loading": "جارٍ التحقق من الوصول الاحترافي…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "جارٍ استعادة عملية الشراء...",
"pro.prompt.export": "تصدير التخطيط هو ميزة احترافية. قم بإلغاء تأمين Pro لعمل نسخة احتياطية من العلامات والطلب والتخطيط الحالي.",
"pro.prompt.import": "يعد استيراد التخطيط ميزة احترافية. افتح Pro لاستعادة التخطيط المحفوظ على جهاز Mac هذا.",
- "pro.prompt.notes": "تعد ملاحظات التطبيق غير المحدودة جزءًا من Pro. فتح Pro لحفظ الملاحظات لكل تطبيق.",
+ "pro.prompt.notes": "يمكن للنسخة المجانية حفظ حتى 3 ملاحظات تطبيق. افتح Pro لحفظ ملاحظات لكل التطبيقات.",
"pro.prompt.sorting": "يعد الفرز اليدوي للتطبيقات المحفوظة جزءًا من Pro. فتح Pro للحفاظ على طلبك المخصص.",
"pro.prompt.themes": "هذا الموضوع هو جزء من Pro. افتح قفل Pro للاستمرار في استخدام سمات App Grid المتقدمة.",
"pro.purchase.failed": "غير قادر على إكمال عملية الشراء الآن. يرجى المحاولة مرة أخرى.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "اختصارات مخصصة",
"pro.feature.customHotkeys.benefit": "عيّن اختصارات عامة لقائمة التطبيقات و Quick Search.",
"pro.prompt.customHotkeys": "الاختصارات المخصصة جزء من Pro. افتح Pro لتعيين اختصاراتك العامة.",
- "hotkeys.customize": "تخصيص",
+ "hotkeys.customize": "غيّر الاختصار",
"hotkeys.restoreDefault": "استعادة الافتراضي",
"hotkeys.recording": "اضغط الاختصار الجديد الآن. اضغط Esc للإلغاء.",
"hotkeys.recordingInline": "تسجيل",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "هذا المفتاح غير مدعوم.",
"hotkeys.error.reserved": "هذا الاختصار محجوز بواسطة macOS أو التطبيق.",
"hotkeys.error.duplicate": "هذا الاختصار مستخدم بالفعل لإجراء آخر في TagLauncher.",
- "hotkeys.error.registrationFailed": "تعذر تسجيل الاختصار. رمز الخطأ: %status%."
+ "hotkeys.error.registrationFailed": "تعذر تسجيل الاختصار. رمز الخطأ: %status%.",
+ "pro.feature.customTagColors": "ألوان وسوم مخصصة",
+ "pro.feature.customTagColors.benefit": "عيّن أي لون لكل وسم، بما في ذلك وسوم فئات النظام SmartStart.",
+ "pro.prompt.customTagColors": "ألوان الوسوم المخصصة من ميزات Pro. افتح Pro لمنح كل وسم أي لون وجعل الفئات أسهل تمييزًا.",
+ "settings.proStatus.freeUser": "أنت حاليًا مستخدم مجاني",
+ "settings.proStatus.proUser": "أنت حاليًا مستخدم 👑Pro مميز",
+ "settings.proStatus.lockedListTitle": "ميزات Pro بانتظار الفتح",
+ "settings.proStatus.unlockedListTitle": "الميزات المفتوحة",
+ "settings.proStatus.lockedFeature": "✅ مدعوم",
+ "settings.proStatus.unlockedFeature": "✅مفتوحة",
+ "settings.proStatus.freeNotes": "3 مجانية",
+ "settings.proStatus.unlimitedNotes": "✅ ملاحظات غير محدودة",
+ "settings.proStatus.limitedFeature": "محدودة",
+ "settings.proStatus.unsupportedFeature": "غير مدعوم",
+ "settings.proFeature.appNotes": "ملاحظات تطبيق مخصصة",
+ "settings.proFeature.dataBackup": "استيراد/تصدير البيانات ونسخ التخطيط الاحتياطية",
+ "tag.customColor": "لون مخصص",
+ "settings.proBenefit.hotkeys": "اضبط اختصاراتك الخاصة لإجراءات TagLauncher.",
+ "settings.proBenefit.tags": "امنح كل وسم لونًا مخصصًا للتعرّف عليه أسرع.",
+ "settings.proBenefit.data": "انسخ الفئات والتخطيط احتياطيًا وصدّرها واستوردها واستعدها.",
+ "settings.proBenefit.about": "كل مزايا Pro مفتوحة على هذا الـ Mac.",
+ "settings.proBenefit.general": "الحاوية الملونة والشبكة الملونة الخاصة بـ Pro متاحة على هالـ Mac.",
+ "settings.proGuide.hotkeys": "الاختصارات الافتراضية متاحة. يقدر مستخدمو Pro يخصصون الاختصارات.",
+ "settings.proGuide.tags": "تتوفر 7 ألوان افتراضية. يقدر مستخدمو Pro يخصصون ألوان أكثر.",
+ "settings.proGuide.data": "يقدر مستخدمو Pro يستوردون ويصدرون بيانات الفئات والتخطيط.",
+ "settings.proCompare.title": "الفرق بين المجاني و Pro",
+ "settings.proCompare.free": "مجاني",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "غير متاح",
+ "settings.proStatus.previewFiveMinutes": "معاينة لمدة 5 دقائق فقط",
+ "settings.proGuide.general": "يمكن لمستخدمي Pro فقط استخدام الحاويات/الشبكات الملونة"
}
diff --git a/src/Apptag/Localization/ar.json b/src/Apptag/Localization/ar.json
index 4dd1c4a..8a956fb 100644
--- a/src/Apptag/Localization/ar.json
+++ b/src/Apptag/Localization/ar.json
@@ -8,8 +8,8 @@
"menu.language": "اللغة",
"menu.help": "المساعدة",
"menu.version": "الإصدار",
- "menu.proStatus.free": "أنت حالياً مستخدم مجاني (الترقية إلى Pro)",
- "menu.proStatus.unlocked": "أنت حالياً مستخدم Pro مميز",
+ "menu.proStatus.free": "أنت حاليًا مستخدم مجاني (الترقية الآن إلى 👑Pro)",
+ "menu.proStatus.unlocked": "أنت حاليًا مستخدم 👑Pro مميز",
"settings.language": "اللغة",
"settings.languagePicker": "لغة التطبيق:",
"settings.languageDesc": "اختر اللغة المستخدمة في القوائم والإعدادات.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "لا توجد نتائج تصنيف ذكي يمكن تطبيقها.",
"scheme.local": "المخطط المحلي",
"scheme.systemSmartStart": "مخطط البداية الذكي للنظام",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "إظهار تلميحات الفقاعات لـ:",
+ "settings.bubbleAllApps": "كل التطبيقات",
+ "settings.bubbleUncommonOnly": "التطبيقات غير الشائعة فقط",
+ "quickSearch.title": "البحث السريع",
+ "quickSearch.placeholder": "ابحث في التطبيقات والوسوم والملاحظات",
+ "quickSearch.inputAccessibility": "حقل البحث السريع",
+ "quickSearch.emptyPrompt": "ابدأ بالكتابة للبحث في التطبيقات والوسوم والملاحظات.",
+ "quickSearch.noResults": "لم يتم العثور على تطبيقات.",
+ "quickSearch.launchFailed": "تعذر فتح هذا التطبيق. حاول مرة أخرى أو اختر تطبيقًا آخر.",
+ "quickSearch.tagPrefix": "وسم",
+ "quickSearch.hotkeys": "اختصارات لوحة المفاتيح",
+ "quickSearch.mainHotkey": "قائمة التطبيقات",
+ "quickSearch.mainHotkeyDesc": "يفتح قائمة تطبيقات TagLauncher.",
+ "quickSearch.status.Active": "مفعّل",
+ "quickSearch.status.registrationFailed": "فشل التسجيل",
+ "quickSearch.status.unavailable": "الاختصار غير متاح",
+ "quickSearch.mainHotkeyUnavailableMessage": "لا يمكن تسجيل %shortcut% الآن. قد يكون مستخدمًا من macOS أو طريقة إدخال أو تطبيق آخر. اختصار قائمة التطبيقات غير متاح مؤقتًا. تحقق من اختصارات لوحة المفاتيح أو تعارضات الاختصارات، ثم أعد تشغيل TagLauncher. رمز الخطأ: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "لا يمكن تسجيل %shortcut% الآن. قد يكون مستخدمًا من macOS أو طريقة إدخال أو تطبيق آخر. البحث السريع العام غير متاح مؤقتًا. تحقق من اختصارات لوحة المفاتيح أو تعارضات الاختصارات، ثم أعد تشغيل TagLauncher. رمز الخطأ: %status%.",
+ "quickSearch.loading": "جارٍ إعداد فهرس البحث…",
+ "quickSearch.internalHotkey": "البحث السريع (داخل TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "يعمل فقط عندما تكون قائمة تطبيقات TagLauncher مفتوحة.",
+ "quickSearch.internalHotkeyStatus": "قائمة التطبيقات فقط",
+ "quickSearch.globalHotkey": "البحث السريع (عام)",
+ "quickSearch.globalHotkeyDesc": "افتح البحث السريع عامًا عندما لا تكون قائمة تطبيقات TagLauncher ظاهرة.",
+ "quickSearch.spaceDisplay": "Space (مفتاح المسافة)",
"trackpadGesture.title": "إيماءة لوحة التعقب",
"trackpadGesture.description": "اربط إيماءة لوحة التعقب في أداة خارجية بهذا الرابط لعرض قائمة التطبيقات.",
"trackpadGesture.status": "أداة خارجية",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "معاينة",
"pro.card.restore": "استعادة المشتريات",
- "pro.card.summary.free": "افتح السمات المميزة، واستيراد التخطيط وتصديره، وملاحظات غير محدودة، وفرز التطبيقات اليدوية المحفوظة.",
+ "pro.card.summary.free": "افتح ألوان الوسوم المخصصة والسمات المميزة واستيراد وتصدير التخطيط وملاحظات التطبيقات غير المحدودة والاختصارات المخصصة.",
"pro.card.summary.legacy": "شكرًا لدعم TagLauncher مبكرًا. وصول Pro لديك نشط بالفعل.",
- "pro.card.summary.unlocked": "Pro نشط على جهاز Mac هذا. السمات المميزة وأدوات التخطيط المتقدمة جاهزة.",
+ "pro.card.summary.unlocked": "Pro نشط على هذا الـ Mac. ألوان الوسوم والسمات المتقدمة والملاحظات غير المحدودة والاختصارات المخصصة وأدوات التخطيط جاهزة.",
"pro.card.title.free": "الترقية إلى Pro",
"pro.card.title.legacy": "مقفلة للمحترفين",
"pro.card.title.unlocked": "مقفلة للمحترفين",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "احفظ علاماتك الحالية وترتيبك وتخطيطك كنسخة احتياطية قابلة لإعادة الاستخدام.",
"pro.feature.import": "استيراد التخطيط",
"pro.feature.import.benefit": "قم باستعادة تخطيط TagLauncher المحفوظ على جهاز Mac هذا في خطوة واحدة.",
- "pro.feature.notes": "ملاحظات غير محدودة",
- "pro.feature.notes.benefit": "احفظ الملاحظات لكل تطبيق دون الحد المجاني المكون من 5 ملاحظات.",
+ "pro.feature.notes": "ملاحظات تطبيق مخصصة",
+ "pro.feature.notes.benefit": "تتضمن النسخة المجانية 3 ملاحظات تطبيق. يفتح Pro ملاحظات غير محدودة لكل التطبيقات.",
"pro.feature.sorting": "فرز التطبيقات المحفوظة",
"pro.feature.sorting.benefit": "احتفظ بترتيب التطبيق اليدوي بعد مغادرة وضع التحرير.",
"pro.feature.themes": "مواضيع متميزة",
"pro.feature.themes.benefit": "افتح جميع سمات App Grid المتقدمة واحتفظ بها بشكل دائم.",
- "pro.notes.limitReached": "يمكن للإصدار المجاني حفظ الملاحظات لما يصل إلى 5 تطبيقات. فتح Pro لحفظ الملاحظات غير المحدودة.",
+ "pro.notes.limitReached": "يمكن للنسخة المجانية حفظ حتى 3 ملاحظات تطبيق. افتح Pro لحفظ ملاحظات غير محدودة.",
"pro.notes.remaining": "يتضمن الإصدار المجاني %limit% ملاحظات للتطبيق. %remaining% المتبقية.",
"pro.operation.cancelled": "تم إلغاء الشراء.",
"pro.operation.loading": "جارٍ التحقق من الوصول الاحترافي…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "جارٍ استعادة عملية الشراء...",
"pro.prompt.export": "تصدير التخطيط هو ميزة احترافية. قم بإلغاء تأمين Pro لعمل نسخة احتياطية من العلامات والطلب والتخطيط الحالي.",
"pro.prompt.import": "يعد استيراد التخطيط ميزة احترافية. افتح Pro لاستعادة التخطيط المحفوظ على جهاز Mac هذا.",
- "pro.prompt.notes": "تعد ملاحظات التطبيق غير المحدودة جزءًا من Pro. فتح Pro لحفظ الملاحظات لكل تطبيق.",
+ "pro.prompt.notes": "يمكن للنسخة المجانية حفظ حتى 3 ملاحظات تطبيق. افتح Pro لحفظ ملاحظات لكل التطبيقات.",
"pro.prompt.sorting": "يعد الفرز اليدوي للتطبيقات المحفوظة جزءًا من Pro. فتح Pro للحفاظ على طلبك المخصص.",
"pro.prompt.themes": "هذا الموضوع هو جزء من Pro. افتح قفل Pro للاستمرار في استخدام سمات App Grid المتقدمة.",
"pro.purchase.failed": "غير قادر على إكمال عملية الشراء الآن. يرجى المحاولة مرة أخرى.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "اختصارات مخصصة",
"pro.feature.customHotkeys.benefit": "عيّن اختصارات عامة لقائمة التطبيقات و Quick Search.",
"pro.prompt.customHotkeys": "الاختصارات المخصصة جزء من Pro. افتح Pro لتعيين اختصاراتك العامة.",
- "hotkeys.customize": "تخصيص",
+ "hotkeys.customize": "تغيير الاختصار",
"hotkeys.restoreDefault": "استعادة الافتراضي",
"hotkeys.recording": "اضغط الاختصار الجديد الآن. اضغط Esc للإلغاء.",
"hotkeys.recordingInline": "تسجيل",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "هذا المفتاح غير مدعوم.",
"hotkeys.error.reserved": "هذا الاختصار محجوز بواسطة macOS أو التطبيق.",
"hotkeys.error.duplicate": "هذا الاختصار مستخدم بالفعل لإجراء آخر في TagLauncher.",
- "hotkeys.error.registrationFailed": "تعذر تسجيل الاختصار. رمز الخطأ: %status%."
+ "hotkeys.error.registrationFailed": "تعذر تسجيل الاختصار. رمز الخطأ: %status%.",
+ "pro.feature.customTagColors": "ألوان وسوم مخصصة",
+ "pro.feature.customTagColors.benefit": "عيّن أي لون لكل وسم، بما في ذلك وسوم فئات النظام SmartStart.",
+ "pro.prompt.customTagColors": "ألوان الوسوم المخصصة من ميزات Pro. افتح Pro لمنح كل وسم أي لون وجعل الفئات أسهل تمييزًا.",
+ "settings.proStatus.freeUser": "أنت حاليًا مستخدم مجاني",
+ "settings.proStatus.proUser": "أنت حاليًا مستخدم 👑Pro مميز",
+ "settings.proStatus.lockedListTitle": "ميزات Pro بانتظار الفتح",
+ "settings.proStatus.unlockedListTitle": "الميزات المفتوحة",
+ "settings.proStatus.lockedFeature": "✅ مدعوم",
+ "settings.proStatus.unlockedFeature": "✅مفتوحة",
+ "settings.proStatus.freeNotes": "3 مجانية",
+ "settings.proStatus.unlimitedNotes": "✅ ملاحظات غير محدودة",
+ "settings.proStatus.limitedFeature": "محدودة",
+ "settings.proStatus.unsupportedFeature": "غير مدعوم",
+ "settings.proFeature.appNotes": "ملاحظات تطبيق مخصصة",
+ "settings.proFeature.dataBackup": "استيراد/تصدير البيانات ونسخ التخطيط الاحتياطية",
+ "tag.customColor": "لون مخصص",
+ "settings.proBenefit.hotkeys": "اضبط اختصاراتك الخاصة لإجراءات TagLauncher.",
+ "settings.proBenefit.tags": "امنح كل وسم لونًا مخصصًا للتعرّف عليه أسرع.",
+ "settings.proBenefit.data": "انسخ الفئات والتخطيط احتياطيًا وصدّرها واستوردها واستعدها.",
+ "settings.proBenefit.about": "كل مزايا Pro مفتوحة على هذا الـ Mac.",
+ "settings.proBenefit.general": "تتوفر الحاوية الملونة والشبكة الملونة الخاصة بـ Pro على هذا الـ Mac.",
+ "settings.proGuide.hotkeys": "الاختصارات الافتراضية متاحة. يمكن لمستخدمي Pro تخصيص الاختصارات.",
+ "settings.proGuide.tags": "تتوفر 7 ألوان افتراضية. يمكن لمستخدمي Pro تخصيص مزيد من الألوان.",
+ "settings.proGuide.data": "يمكن لمستخدمي Pro استيراد وتصدير بيانات الفئات والتخطيط.",
+ "settings.proCompare.title": "الفرق بين المجاني و Pro",
+ "settings.proCompare.free": "مجاني",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "غير متاح",
+ "settings.proStatus.previewFiveMinutes": "معاينة لمدة 5 دقائق فقط",
+ "settings.proGuide.general": "يمكن لمستخدمي Pro فقط استخدام الحاويات/الشبكات الملونة"
}
diff --git a/src/Apptag/Localization/cs.json b/src/Apptag/Localization/cs.json
index 2310e39..fc04df0 100644
--- a/src/Apptag/Localization/cs.json
+++ b/src/Apptag/Localization/cs.json
@@ -8,8 +8,8 @@
"menu.language": "Jazyk",
"menu.help": "Nápověda",
"menu.version": "Verze",
- "menu.proStatus.free": "Nyní jste uživatel bezplatné verze (upgradovat na Pro)",
- "menu.proStatus.unlocked": "Nyní jste vážený uživatel verze Pro",
+ "menu.proStatus.free": "Právě jste uživatel bezplatné verze (upgradovat hned na 👑Pro)",
+ "menu.proStatus.unlocked": "Právě jste vážený uživatel 👑Pro",
"settings.language": "Jazyk",
"settings.languagePicker": "Jazyk aplikace:",
"settings.languageDesc": "Vyberte jazyk používaný v nabídkách a nastaveních.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Nejsou k dispozici žádné výsledky chytré klasifikace.",
"scheme.local": "Místní schéma",
"scheme.systemSmartStart": "Chytré počáteční schéma systému",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Bublinové tipy zobrazit pro:",
+ "settings.bubbleAllApps": "Všechny aplikace",
+ "settings.bubbleUncommonOnly": "Jen méně používané aplikace",
+ "quickSearch.title": "Rychlé hledání",
+ "quickSearch.placeholder": "Hledat aplikace, štítky a poznámky",
+ "quickSearch.inputAccessibility": "Vstup rychlého hledání",
+ "quickSearch.emptyPrompt": "Začněte psát a hledejte aplikace, štítky a poznámky.",
+ "quickSearch.noResults": "Nebyly nalezeny žádné aplikace.",
+ "quickSearch.launchFailed": "Tuto aplikaci nelze otevřít. Zkuste to znovu nebo vyberte jinou aplikaci.",
+ "quickSearch.tagPrefix": "Štítek",
+ "quickSearch.hotkeys": "Klávesové zkratky",
+ "quickSearch.mainHotkey": "Seznam aplikací",
+ "quickSearch.mainHotkeyDesc": "Otevře seznam aplikací TagLauncher.",
+ "quickSearch.status.Active": "Aktivní",
+ "quickSearch.status.registrationFailed": "Registrace selhala",
+ "quickSearch.status.unavailable": "Zkratka není dostupná",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% teď nelze zaregistrovat. Může ji používat macOS, metoda zadávání nebo jiná aplikace. Zkratka seznamu aplikací je dočasně nedostupná. Zkontrolujte klávesové zkratky nebo konflikty zkratek a restartujte TagLauncher. Kód chyby: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% teď nelze zaregistrovat. Může ji používat macOS, metoda zadávání nebo jiná aplikace. Globální rychlé hledání je dočasně nedostupné. Zkontrolujte klávesové zkratky nebo konflikty zkratek a restartujte TagLauncher. Kód chyby: %status%.",
+ "quickSearch.loading": "Připravuje se index hledání…",
+ "quickSearch.internalHotkey": "Rychlé hledání (v TagLauncheru)",
+ "quickSearch.internalHotkeyDesc": "Funguje jen, když je otevřený seznam aplikací TagLauncher.",
+ "quickSearch.internalHotkeyStatus": "Pouze seznam aplikací",
+ "quickSearch.globalHotkey": "Rychlé hledání (globální)",
+ "quickSearch.globalHotkeyDesc": "Otevře rychlé hledání globálně, když není seznam aplikací TagLauncher viditelný.",
+ "quickSearch.spaceDisplay": "Space (mezerník)",
"trackpadGesture.title": "Gesto trackpadu",
"trackpadGesture.description": "Namapujte gesto trackpadu v nástroji třetí strany na tuto URL a zobrazte seznam aplikací.",
"trackpadGesture.status": "Externí nástroj",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Náhled",
"pro.card.restore": "Obnovit nákupy",
- "pro.card.summary.free": "Odemkněte prémiová témata, import a export rozložení, neomezený počet poznámek a uložené ruční řazení aplikací.",
+ "pro.card.summary.free": "Odemkněte vlastní barvy štítků, prémiová témata, import a export rozvržení, neomezené poznámky k aplikacím a vlastní zkratky.",
"pro.card.summary.legacy": "Děkujeme za včasnou podporu TagLauncher. Váš přístup Pro je již aktivní.",
- "pro.card.summary.unlocked": "Pro je na tomto Macu aktivní. Prémiové motivy a pokročilé nástroje pro rozvržení jsou připraveny.",
+ "pro.card.summary.unlocked": "Pro je na tomto Macu aktivní. Vlastní barvy štítků, pokročilá témata, neomezené poznámky, vlastní zkratky a nástroje rozvržení jsou připravené.",
"pro.card.title.free": "Upgradujte na Pro",
"pro.card.title.legacy": "Pro odemčeno",
"pro.card.title.unlocked": "Pro odemčeno",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Uložte své aktuální značky, pořadí a rozvržení jako opakovaně použitelnou zálohu.",
"pro.feature.import": "Import rozložení",
"pro.feature.import.benefit": "Obnovte uložené rozložení TagLauncher na tomto Macu v jednom kroku.",
- "pro.feature.notes": "Neomezené poznámky",
- "pro.feature.notes.benefit": "Ukládejte poznámky pro každou aplikaci bez bezplatného limitu 5 poznámek.",
+ "pro.feature.notes": "Vlastní poznámky aplikací",
+ "pro.feature.notes.benefit": "Bezplatná verze obsahuje 3 poznámky aplikací. Pro odemkne neomezené poznámky pro všechny aplikace.",
"pro.feature.sorting": "Uložené řazení aplikací",
"pro.feature.sorting.benefit": "Po opuštění režimu úprav si ponechte ruční objednávku aplikací.",
"pro.feature.themes": "Prémiová témata",
"pro.feature.themes.benefit": "Odemkněte všechna pokročilá témata App Grid a ponechte si je trvale.",
- "pro.notes.limitReached": "Bezplatná verze dokáže uložit poznámky až pro 5 aplikací. Odemkněte Pro a uložte neomezené poznámky.",
+ "pro.notes.limitReached": "Bezplatná verze uloží až 3 poznámky aplikací. Odemkněte Pro pro neomezené poznámky.",
"pro.notes.remaining": "Bezplatná verze obsahuje %limit% poznámek k aplikaci. %remaining% zbývající.",
"pro.operation.cancelled": "Nákup zrušen.",
"pro.operation.loading": "Kontrola přístupu Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Obnovování nákupu…",
"pro.prompt.export": "Export rozvržení je funkce Pro. Odemkněte Pro, abyste mohli zálohovat své aktuální značky, pořadí a rozvržení.",
"pro.prompt.import": "Import rozvržení je funkce Pro. Chcete-li obnovit uložené rozvržení na tomto Macu, odemkněte Pro.",
- "pro.prompt.notes": "Neomezené poznámky k aplikaci jsou součástí Pro. Odemkněte Pro a uložte si poznámky pro každou aplikaci.",
+ "pro.prompt.notes": "Bezplatná verze uloží až 3 poznámky aplikací. Odemkněte Pro a ukládejte poznámky ke všem aplikacím.",
"pro.prompt.sorting": "Uložené ruční řazení aplikací je součástí Pro. Odemkněte Pro, abyste si zachovali vlastní pořadí.",
"pro.prompt.themes": "Toto téma je součástí Pro. Odemkněte Pro, abyste mohli nadále používat pokročilé motivy App Grid.",
"pro.purchase.failed": "Nákup nyní nelze dokončit. Zkuste to prosím znovu.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Vlastní zkratky",
"pro.feature.customHotkeys.benefit": "Nastavte globální zkratky pro seznam aplikací a Quick Search.",
"pro.prompt.customHotkeys": "Vlastní zkratky jsou součástí Pro. Odemkněte Pro a nastavte je.",
- "hotkeys.customize": "Přizpůsobit",
+ "hotkeys.customize": "Změnit zkratku",
"hotkeys.restoreDefault": "Obnovit výchozí",
"hotkeys.recording": "Stiskněte novou zkratku. Esc zruší.",
"hotkeys.recordingInline": "Nahrávání",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Tato klávesa není podporována.",
"hotkeys.error.reserved": "Tato zkratka je vyhrazena macOS nebo aplikací.",
"hotkeys.error.duplicate": "Tato zkratka už patří jiné akci TagLauncher.",
- "hotkeys.error.registrationFailed": "Zkratku se nepodařilo zaregistrovat. Kód chyby: %status%."
+ "hotkeys.error.registrationFailed": "Zkratku se nepodařilo zaregistrovat. Kód chyby: %status%.",
+ "pro.feature.customTagColors": "Vlastní barvy štítků",
+ "pro.feature.customTagColors.benefit": "Nastavte libovolnou barvu každému štítku včetně systémových kategorií SmartStart.",
+ "pro.prompt.customTagColors": "Vlastní barvy štítků jsou funkce Pro. Odemkněte Pro, dejte každému štítku libovolnou barvu a snáze rozeznáte kategorie.",
+ "settings.proStatus.freeUser": "Právě jste uživatel bezplatné verze",
+ "settings.proStatus.proUser": "Právě jste vážený uživatel 👑Pro",
+ "settings.proStatus.lockedListTitle": "Funkce Pro k odemčení",
+ "settings.proStatus.unlockedListTitle": "Odemčené funkce",
+ "settings.proStatus.lockedFeature": "✅ Podporováno",
+ "settings.proStatus.unlockedFeature": "✅Odemčeno",
+ "settings.proStatus.freeNotes": "3 zdarma",
+ "settings.proStatus.unlimitedNotes": "✅ Neomezené poznámky",
+ "settings.proStatus.limitedFeature": "Omezeno",
+ "settings.proStatus.unsupportedFeature": "Nepodporováno",
+ "settings.proFeature.appNotes": "Vlastní poznámky aplikací",
+ "settings.proFeature.dataBackup": "Import/export dat a zálohy rozvržení",
+ "tag.customColor": "Vlastní barva",
+ "settings.proBenefit.hotkeys": "Nastavte vlastní zkratky pro akce TagLauncheru.",
+ "settings.proBenefit.tags": "Dejte každému štítku vlastní barvu pro rychlejší rozpoznání.",
+ "settings.proBenefit.data": "Zálohujte, exportujte, importujte a obnovujte kategorie a rozvržení.",
+ "settings.proBenefit.about": "Všechny výhody Pro jsou na tomto Macu odemčené.",
+ "settings.proBenefit.general": "Na tomto Macu jsou dostupné barevné kontejnery a barevná mřížka Pro.",
+ "settings.proGuide.hotkeys": "Výchozí zkratky jsou dostupné. Uživatelé Pro si mohou zkratky přizpůsobit.",
+ "settings.proGuide.tags": "K dispozici je 7 výchozích barev. Uživatelé Pro si mohou přizpůsobit další barvy.",
+ "settings.proGuide.data": "Uživatelé Pro mohou importovat a exportovat data kategorií a rozvržení.",
+ "settings.proCompare.title": "Rozdíly mezi zdarma a Pro",
+ "settings.proCompare.free": "Zdarma",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Nedostupné",
+ "settings.proStatus.previewFiveMinutes": "Pouze 5minutový náhled",
+ "settings.proGuide.general": "Barevné kontejnery / mřížky mohou používat jen uživatelé Pro"
}
diff --git a/src/Apptag/Localization/da.json b/src/Apptag/Localization/da.json
index 2ea860a..e84964f 100644
--- a/src/Apptag/Localization/da.json
+++ b/src/Apptag/Localization/da.json
@@ -8,8 +8,8 @@
"menu.language": "Sprog",
"menu.help": "Hjælp",
"menu.version": "Version",
- "menu.proStatus.free": "Du er i øjeblikket gratisbruger (opgrader til Pro)",
- "menu.proStatus.unlocked": "Du er i øjeblikket en værdsat Pro-bruger",
+ "menu.proStatus.free": "Du er i øjeblikket gratisbruger (opgrader nu til 👑Pro)",
+ "menu.proStatus.unlocked": "Du er i øjeblikket en værdsat 👑Pro-bruger",
"settings.language": "Sprog",
"settings.languagePicker": "Appsprog:",
"settings.languageDesc": "Vælg sproget til menuer og indstillinger.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Ingen smarte klassificeringsresultater kan anvendes.",
"scheme.local": "Lokalt skema",
"scheme.systemSmartStart": "Systemets smarte startskema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Vis bobletips for:",
+ "settings.bubbleAllApps": "Alle apps",
+ "settings.bubbleUncommonOnly": "Kun sjældent brugte apps",
+ "quickSearch.title": "Hurtigsøgning",
+ "quickSearch.placeholder": "Søg efter apps, mærker og noter",
+ "quickSearch.inputAccessibility": "Input til hurtigsøgning",
+ "quickSearch.emptyPrompt": "Begynd at skrive for at søge efter apps, mærker og noter.",
+ "quickSearch.noResults": "Ingen apps fundet.",
+ "quickSearch.launchFailed": "Denne app kunne ikke åbnes. Prøv igen, eller vælg en anden app.",
+ "quickSearch.tagPrefix": "Mærke",
+ "quickSearch.hotkeys": "Tastaturgenveje",
+ "quickSearch.mainHotkey": "Appliste",
+ "quickSearch.mainHotkeyDesc": "Åbner TagLauncher-applisten.",
+ "quickSearch.status.Active": "Aktiv",
+ "quickSearch.status.registrationFailed": "Registrering mislykkedes",
+ "quickSearch.status.unavailable": "Genvej ikke tilgængelig",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% kan ikke registreres lige nu. Den kan være brugt af macOS, en inputmetode eller en anden app. Genvejen til applisten er midlertidigt utilgængelig. Tjek tastaturgenveje eller genvejskonflikter, og genstart TagLauncher. Fejlkode: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% kan ikke registreres lige nu. Den kan være brugt af macOS, en inputmetode eller en anden app. Global hurtigsøgning er midlertidigt utilgængelig. Tjek tastaturgenveje eller genvejskonflikter, og genstart TagLauncher. Fejlkode: %status%.",
+ "quickSearch.loading": "Forbereder søgeindeks…",
+ "quickSearch.internalHotkey": "Hurtigsøgning (i TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Virker kun, mens TagLauncher-applisten er åben.",
+ "quickSearch.internalHotkeyStatus": "Kun appliste",
+ "quickSearch.globalHotkey": "Hurtigsøgning (global)",
+ "quickSearch.globalHotkeyDesc": "Åbn hurtigsøgning globalt, når TagLauncher-applisten ikke er synlig.",
+ "quickSearch.spaceDisplay": "Space (mellemrum)",
"trackpadGesture.title": "Pegefeltbevægelse",
"trackpadGesture.description": "Knyt en pegefeltbevægelse i et tredjepartsværktøj til denne URL for at vise applisten.",
"trackpadGesture.status": "Eksternt værktøj",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Forhåndsvisning",
"pro.card.restore": "Gendan køb",
- "pro.card.summary.free": "Lås op for premium-temaer, layout-import og -eksport, ubegrænset antal noter og gemt manuel app-sortering.",
+ "pro.card.summary.free": "Lås op for egne tagfarver, premium-temaer, import og eksport af layout, ubegrænsede appnoter og egne genveje.",
"pro.card.summary.legacy": "Tak for at støtte TagLauncher tidligt. Din Pro-adgang er allerede aktiv.",
- "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Premium-temaer og avancerede layoutværktøjer er klar.",
+ "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Egne tagfarver, avancerede temaer, ubegrænsede noter, egne genveje og layoutværktøjer er klar.",
"pro.card.title.free": "Opgrader til Pro",
"pro.card.title.legacy": "Pro låst op",
"pro.card.title.unlocked": "Pro låst op",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Gem dine nuværende tags, ordre og layout som en genbrugelig backup.",
"pro.feature.import": "Import af layout",
"pro.feature.import.benefit": "Gendan et gemt TagLauncher-layout på denne Mac i ét trin.",
- "pro.feature.notes": "Ubegrænsede noter",
- "pro.feature.notes.benefit": "Gem noter til hver app uden den gratis grænse på 5 noter.",
+ "pro.feature.notes": "Egne appnoter",
+ "pro.feature.notes.benefit": "Gratisversionen indeholder 3 appnoter. Pro låser op for ubegrænsede noter til alle apps.",
"pro.feature.sorting": "Gemt app-sortering",
"pro.feature.sorting.benefit": "Behold din manuelle app-rækkefølge, når du forlader redigeringstilstand.",
"pro.feature.themes": "Premium temaer",
"pro.feature.themes.benefit": "Lås op for alle avancerede App Grid-temaer, og behold dem permanent.",
- "pro.notes.limitReached": "Gratis version kan gemme noter til op til 5 apps. Lås Pro op for at gemme ubegrænsede noter.",
+ "pro.notes.limitReached": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for ubegrænsede noter.",
"pro.notes.remaining": "Gratis version inkluderer %limit% app noter. %remaining% tilbage.",
"pro.operation.cancelled": "Køb annulleret.",
"pro.operation.loading": "Kontrollerer Pro-adgang...",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Gendanner køb...",
"pro.prompt.export": "Layouteksport er en Pro-funktion. Lås Pro op for at sikkerhedskopiere dine nuværende tags, ordre og layout.",
"pro.prompt.import": "Layoutimport er en Pro-funktion. Lås Pro op for at gendanne et gemt layout på denne Mac.",
- "pro.prompt.notes": "Ubegrænsede app-noter er en del af Pro. Lås Pro op for at gemme noter til hver app.",
+ "pro.prompt.notes": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for at gemme noter til alle apps.",
"pro.prompt.sorting": "Gemt manuel app-sortering er en del af Pro. Lås Pro op for at bevare din tilpassede rækkefølge.",
"pro.prompt.themes": "Dette tema er en del af Pro. Lås Pro op for at fortsætte med at bruge avancerede App Grid-temaer.",
"pro.purchase.failed": "Kan ikke gennemføre købet lige nu. Prøv venligst igen.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Egne genveje",
"pro.feature.customHotkeys.benefit": "Indstil globale genveje til applisten og Quick Search.",
"pro.prompt.customHotkeys": "Egne genveje er en Pro-funktion. Lås Pro op for at indstille dem.",
- "hotkeys.customize": "Tilpas",
+ "hotkeys.customize": "Skift genvej",
"hotkeys.restoreDefault": "Gendan standard",
"hotkeys.recording": "Tryk på den nye genvej nu. Tryk Esc for at annullere.",
"hotkeys.recordingInline": "Optager",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Denne tast understøttes ikke.",
"hotkeys.error.reserved": "Denne genvej er reserveret af macOS eller appen.",
"hotkeys.error.duplicate": "Denne genvej bruges allerede af en anden TagLauncher-handling.",
- "hotkeys.error.registrationFailed": "Genvejen kunne ikke registreres. Fejlkode: %status%."
+ "hotkeys.error.registrationFailed": "Genvejen kunne ikke registreres. Fejlkode: %status%.",
+ "pro.feature.customTagColors": "Egne tagfarver",
+ "pro.feature.customTagColors.benefit": "Vælg en hvilken som helst farve til hvert tag, også SmartStart-systemkategorier.",
+ "pro.prompt.customTagColors": "Egne tagfarver er en Pro-funktion. Lås Pro op for at give hvert tag en valgfri farve og gøre kategorier lettere at kende.",
+ "settings.proStatus.freeUser": "Du er i øjeblikket gratisbruger",
+ "settings.proStatus.proUser": "Du er i øjeblikket en værdsat 👑Pro-bruger",
+ "settings.proStatus.lockedListTitle": "Pro-funktioner at låse op",
+ "settings.proStatus.unlockedListTitle": "Oplåste funktioner",
+ "settings.proStatus.lockedFeature": "✅ Understøttet",
+ "settings.proStatus.unlockedFeature": "✅Oplåst",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Ubegrænsede noter",
+ "settings.proStatus.limitedFeature": "Begrænset",
+ "settings.proStatus.unsupportedFeature": "Understøttes ikke",
+ "settings.proFeature.appNotes": "Egne appnoter",
+ "settings.proFeature.dataBackup": "Dataimport/-eksport og layoutbackups",
+ "tag.customColor": "Egen farve",
+ "settings.proBenefit.hotkeys": "Indstil dine egne genveje til TagLauncher-handlinger.",
+ "settings.proBenefit.tags": "Giv hvert tag en egen farve, så du hurtigere kan kende det.",
+ "settings.proBenefit.data": "Sikkerhedskopiér, eksportér, importér og gendan kategorier og layout.",
+ "settings.proBenefit.about": "Alle Pro-fordele er låst op på denne Mac.",
+ "settings.proBenefit.general": "Pro-farvecontainer og farvegitter er tilgængelige på denne Mac.",
+ "settings.proGuide.hotkeys": "Standardgenveje er tilgængelige. Pro-brugere kan tilpasse genveje.",
+ "settings.proGuide.tags": "7 standardfarver er tilgængelige. Pro-brugere kan tilpasse flere farver.",
+ "settings.proGuide.data": "Pro-brugere kan importere og eksportere kategori- og layoutdata.",
+ "settings.proCompare.title": "Forskelle mellem gratis og Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Ikke tilgængelig",
+ "settings.proStatus.previewFiveMinutes": "Kun 5 minutters forhåndsvisning",
+ "settings.proGuide.general": "Kun Pro-brugere kan bruge farvede beholdere / gitre"
}
diff --git a/src/Apptag/Localization/de.json b/src/Apptag/Localization/de.json
index c5f15de..39a8ccc 100644
--- a/src/Apptag/Localization/de.json
+++ b/src/Apptag/Localization/de.json
@@ -8,8 +8,8 @@
"menu.language": "Sprache",
"menu.help": "Hilfe",
"menu.version": "Version",
- "menu.proStatus.free": "Sie sind derzeit Nutzer der Gratisversion (Upgrade auf Pro)",
- "menu.proStatus.unlocked": "Sie sind derzeit ein geschätzter Pro-Nutzer",
+ "menu.proStatus.free": "Du bist derzeit Nutzer der Gratisversion (jetzt auf 👑Pro upgraden)",
+ "menu.proStatus.unlocked": "Du bist derzeit ein geschätzter 👑Pro-Nutzer",
"settings.language": "Sprache",
"settings.languagePicker": "App-Sprache:",
"settings.languageDesc": "Wähle die Sprache für Menüs und Einstellungen.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Es sind keine intelligenten Klassifizierungsergebnisse verfügbar.",
"scheme.local": "Lokales Schema",
"scheme.systemSmartStart": "Intelligentes System-Startschema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
+ "settings.bubbleDisplayScope": "Sprechblasen-Tipps anzeigen für:",
+ "settings.bubbleAllApps": "Alle Apps",
+ "settings.bubbleUncommonOnly": "Nur selten genutzte Apps",
+ "quickSearch.title": "Schnellsuche",
+ "quickSearch.placeholder": "Apps, Tags und Notizen suchen",
+ "quickSearch.inputAccessibility": "Eingabefeld für Schnellsuche",
+ "quickSearch.emptyPrompt": "Tippen Sie, um Apps, Tags und Notizen zu suchen.",
+ "quickSearch.noResults": "Keine Apps gefunden.",
+ "quickSearch.launchFailed": "Diese App konnte nicht geöffnet werden. Versuchen Sie es erneut oder wählen Sie eine andere App.",
"quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "quickSearch.hotkeys": "Tastaturkurzbefehle",
+ "quickSearch.mainHotkey": "App-Liste",
+ "quickSearch.mainHotkeyDesc": "Öffnet die TagLauncher-App-Liste.",
+ "quickSearch.status.Active": "Aktiv",
+ "quickSearch.status.registrationFailed": "Registrierung fehlgeschlagen",
+ "quickSearch.status.unavailable": "Kurzbefehl nicht verfügbar",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% kann derzeit nicht registriert werden. Der Kurzbefehl wird möglicherweise von macOS, einer Eingabemethode oder einer anderen App verwendet. Der Kurzbefehl für die App-Liste ist vorübergehend nicht verfügbar. Prüfen Sie Tastaturkurzbefehle oder Konflikte und starten Sie TagLauncher neu. Fehlercode: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% kann derzeit nicht registriert werden. Der Kurzbefehl wird möglicherweise von macOS, einer Eingabemethode oder einer anderen App verwendet. Die globale Schnellsuche ist vorübergehend nicht verfügbar. Prüfen Sie Tastaturkurzbefehle oder Konflikte und starten Sie TagLauncher neu. Fehlercode: %status%.",
+ "quickSearch.loading": "Suchindex wird vorbereitet…",
+ "quickSearch.internalHotkey": "Schnellsuche (in TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Funktioniert nur, solange die TagLauncher-App-Liste geöffnet ist.",
+ "quickSearch.internalHotkeyStatus": "Nur App-Liste",
+ "quickSearch.globalHotkey": "Schnellsuche (global)",
+ "quickSearch.globalHotkeyDesc": "Öffnet die Schnellsuche global, wenn die TagLauncher-App-Liste nicht sichtbar ist.",
+ "quickSearch.spaceDisplay": "Leertaste",
"trackpadGesture.title": "Trackpad-Geste",
"trackpadGesture.description": "Ordnen Sie in einem Drittanbieter-Tool eine Trackpad-Geste dieser URL zu, um die App-Liste anzuzeigen.",
"trackpadGesture.status": "Externes Tool",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Vorschau",
"pro.card.restore": "Einkäufe wiederherstellen",
- "pro.card.summary.free": "Schalten Sie Premium-Themen, Layout-Import und -Export, unbegrenzte Notizen und gespeicherte manuelle App-Sortierung frei.",
+ "pro.card.summary.free": "Schalte eigene Tag-Farben, Premium-Designs, Layout-Import und -Export, unbegrenzte App-Notizen und eigene Kurzbefehle frei.",
"pro.card.summary.legacy": "Vielen Dank, dass Sie TagLauncher frühzeitig unterstützt haben. Ihr Pro-Zugang ist bereits aktiv.",
- "pro.card.summary.unlocked": "Pro ist auf diesem Mac aktiv. Premium-Themen und erweiterte Layout-Tools stehen bereit.",
+ "pro.card.summary.unlocked": "Pro ist auf diesem Mac aktiv. Eigene Tag-Farben, Premium-Designs, unbegrenzte Notizen, eigene Kurzbefehle und Layout-Werkzeuge sind bereit.",
"pro.card.title.free": "Auf Pro upgraden",
"pro.card.title.legacy": "Pro freigeschaltet",
"pro.card.title.unlocked": "Pro freigeschaltet",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Speichern Sie Ihre aktuellen Tags, Reihenfolge und Layout als wiederverwendbares Backup.",
"pro.feature.import": "Layout-Import",
"pro.feature.import.benefit": "Stellen Sie in einem Schritt ein gespeichertes TagLauncher-Layout auf diesem Mac wieder her.",
- "pro.feature.notes": "Unbegrenzte Notizen",
- "pro.feature.notes.benefit": "Speichern Sie Notizen für jede App ohne die kostenlose Beschränkung auf 5 Notizen.",
+ "pro.feature.notes": "Eigene App-Notizen",
+ "pro.feature.notes.benefit": "Die Gratisversion enthält 3 App-Notizen. Pro schaltet unbegrenzte Notizen für jede App frei.",
"pro.feature.sorting": "Gespeicherte App-Sortierung",
"pro.feature.sorting.benefit": "Behalten Sie Ihre manuelle App-Reihenfolge bei, nachdem Sie den Bearbeitungsmodus verlassen haben.",
"pro.feature.themes": "Premium-Themen",
"pro.feature.themes.benefit": "Schalten Sie alle erweiterten App Grid-Designs frei und behalten Sie sie dauerhaft.",
- "pro.notes.limitReached": "In der kostenlosen Version können Notizen für bis zu 5 Apps gespeichert werden. Schalten Sie Pro frei, um unbegrenzt Notizen zu speichern.",
+ "pro.notes.limitReached": "Die Gratisversion kann bis zu 3 App-Notizen speichern. Mit Pro speicherst du unbegrenzt viele Notizen.",
"pro.notes.remaining": "Die kostenlose Version enthält %limit% App-Notizen. %remaining% übrig.",
"pro.operation.cancelled": "Kauf storniert.",
"pro.operation.loading": "Pro-Zugriff wird überprüft…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Kauf wird wiederhergestellt…",
"pro.prompt.export": "Der Layout-Export ist eine Pro-Funktion. Schalten Sie Pro frei, um Ihre aktuellen Tags, Reihenfolge und Layout zu sichern.",
"pro.prompt.import": "Der Layoutimport ist eine Pro-Funktion. Entsperren Sie Pro, um ein gespeichertes Layout auf diesem Mac wiederherzustellen.",
- "pro.prompt.notes": "Unbegrenzte App-Notizen sind Teil von Pro. Schalten Sie Pro frei, um Notizen für jede App zu speichern.",
+ "pro.prompt.notes": "Die Gratisversion kann bis zu 3 App-Notizen speichern. Mit Pro kannst du für jede App Notizen speichern.",
"pro.prompt.sorting": "Die gespeicherte manuelle App-Sortierung ist Teil von Pro. Schalten Sie Pro frei, um Ihre individuelle Bestellung beizubehalten.",
"pro.prompt.themes": "Dieses Thema ist Teil von Pro. Schalten Sie Pro frei, um weiterhin erweiterte App Grid-Designs zu verwenden.",
"pro.purchase.failed": "Der Kauf kann derzeit nicht abgeschlossen werden. Bitte versuchen Sie es erneut.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Eigene Kurzbefehle",
"pro.feature.customHotkeys.benefit": "Lege eigene globale Kurzbefehle für App-Liste und Quick Search fest.",
"pro.prompt.customHotkeys": "Eigene Kurzbefehle sind Teil von Pro. Schalte Pro frei, um globale Kurzbefehle anzupassen.",
- "hotkeys.customize": "Anpassen",
+ "hotkeys.customize": "Kurzbefehl ändern",
"hotkeys.restoreDefault": "Standard wiederherstellen",
"hotkeys.recording": "Drücke jetzt den neuen Kurzbefehl. Mit Esc abbrechen.",
"hotkeys.recordingInline": "Aufnahme",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Diese Taste wird nicht unterstützt.",
"hotkeys.error.reserved": "Dieser Kurzbefehl ist von macOS oder der App reserviert.",
"hotkeys.error.duplicate": "Dieser Kurzbefehl gehört bereits zu einer anderen TagLauncher-Aktion.",
- "hotkeys.error.registrationFailed": "Kurzbefehl konnte nicht registriert werden. Fehlercode: %status%."
+ "hotkeys.error.registrationFailed": "Kurzbefehl konnte nicht registriert werden. Fehlercode: %status%.",
+ "pro.feature.customTagColors": "Eigene Tag-Farben",
+ "pro.feature.customTagColors.benefit": "Lege für jedes Tag eine beliebige Farbe fest, auch für SmartStart-Systemkategorien.",
+ "pro.prompt.customTagColors": "Eigene Tag-Farben sind eine Pro-Funktion. Mit Pro gibst du jedem Tag eine beliebige Farbe und erkennst Kategorien leichter.",
+ "settings.proStatus.freeUser": "Du bist derzeit Nutzer der Gratisversion",
+ "settings.proStatus.proUser": "Du bist derzeit ein geschätzter 👑Pro-Nutzer",
+ "settings.proStatus.lockedListTitle": "Freizuschaltende Pro-Funktionen",
+ "settings.proStatus.unlockedListTitle": "Freigeschaltete Funktionen",
+ "settings.proStatus.lockedFeature": "✅ Unterstützt",
+ "settings.proStatus.unlockedFeature": "✅Freigeschaltet",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Unbegrenzte Notizen",
+ "settings.proStatus.limitedFeature": "Begrenzt",
+ "settings.proStatus.unsupportedFeature": "Nicht unterstützt",
+ "settings.proFeature.appNotes": "Eigene App-Notizen",
+ "settings.proFeature.dataBackup": "Datenimport/-export und Layout-Backups",
+ "tag.customColor": "Eigene Farbe",
+ "settings.proBenefit.hotkeys": "Lege eigene Kurzbefehle für TagLauncher-Aktionen fest.",
+ "settings.proBenefit.tags": "Gib jedem Tag eine eigene Farbe, damit du es schneller erkennst.",
+ "settings.proBenefit.data": "Sichere, exportiere, importiere und stelle Kategorien und Layout wieder her.",
+ "settings.proBenefit.about": "Alle Pro-Vorteile sind auf diesem Mac freigeschaltet.",
+ "settings.proBenefit.general": "Pro-Farbcontainer und Farbraster sind auf diesem Mac verfügbar.",
+ "settings.proGuide.hotkeys": "Standardkurzbefehle sind verfügbar. Pro-Nutzer können eigene Kurzbefehle festlegen.",
+ "settings.proGuide.tags": "7 Standardfarben sind verfügbar. Pro-Nutzer können weitere Farben anpassen.",
+ "settings.proGuide.data": "Pro-Nutzer können Kategorie- und Layoutdaten importieren und exportieren.",
+ "settings.proCompare.title": "Gratis und Pro im Vergleich",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Nicht verfügbar",
+ "settings.proStatus.previewFiveMinutes": "Nur 5 Minuten Vorschau",
+ "settings.proGuide.general": "Nur Pro-Nutzer können farbige Container / Raster verwenden"
}
diff --git a/src/Apptag/Localization/en.json b/src/Apptag/Localization/en.json
index b08b243..11306b9 100644
--- a/src/Apptag/Localization/en.json
+++ b/src/Apptag/Localization/en.json
@@ -8,8 +8,8 @@
"menu.language": "Language",
"menu.help": "Help",
"menu.version": "Version",
- "menu.proStatus.free": "You are currently a Free user (upgrade to Pro)",
- "menu.proStatus.unlocked": "You are currently a valued Pro user",
+ "menu.proStatus.free": "You are currently a Free user (upgrade to 👑Pro now)",
+ "menu.proStatus.unlocked": "You are currently a valued 👑Pro user",
"settings.language": "Language",
"settings.languagePicker": "App language:",
"settings.languageDesc": "Choose the language used by menus and settings.",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Preview",
"pro.card.restore": "Restore Purchases",
- "pro.card.summary.free": "Unlock premium themes, layout import and export, unlimited notes, and saved manual app sorting.",
+ "pro.card.summary.free": "Unlock custom tag colors, premium themes, layout import and export, unlimited app notes, and custom shortcuts.",
"pro.card.summary.legacy": "Thanks for supporting TagLauncher early. Your Pro access is already active.",
- "pro.card.summary.unlocked": "Pro is active on this Mac. Premium themes and advanced layout tools are ready.",
+ "pro.card.summary.unlocked": "Pro is active on this Mac. Custom tag colors, advanced themes, unlimited notes, custom shortcuts, and layout tools are ready.",
"pro.card.title.free": "Upgrade to Pro",
"pro.card.title.legacy": "Pro unlocked",
"pro.card.title.unlocked": "Pro unlocked",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Save your current tags, order, and layout as a reusable backup.",
"pro.feature.import": "Layout import",
"pro.feature.import.benefit": "Restore a saved TagLauncher layout on this Mac in one step.",
- "pro.feature.notes": "Unlimited notes",
- "pro.feature.notes.benefit": "Save notes for every app without the free 5-note limit.",
+ "pro.feature.notes": "Custom app notes",
+ "pro.feature.notes.benefit": "Free version includes 3 app notes. Pro unlocks unlimited notes for every app.",
"pro.feature.sorting": "Saved app sorting",
"pro.feature.sorting.benefit": "Keep your manual app order after you leave editing mode.",
"pro.feature.themes": "Premium themes",
"pro.feature.themes.benefit": "Unlock every advanced App Grid theme and keep it permanently.",
- "pro.notes.limitReached": "Free version can save notes for up to 5 apps. Unlock Pro to save unlimited notes.",
+ "pro.notes.limitReached": "Free version can save up to 3 app notes. Unlock Pro to save unlimited notes.",
"pro.notes.remaining": "Free version includes %limit% app notes. %remaining% remaining.",
"pro.operation.cancelled": "Purchase cancelled.",
"pro.operation.loading": "Checking Pro access…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Restoring purchase…",
"pro.prompt.export": "Layout export is a Pro feature. Unlock Pro to back up your current tags, order, and layout.",
"pro.prompt.import": "Layout import is a Pro feature. Unlock Pro to restore a saved layout on this Mac.",
- "pro.prompt.notes": "Unlimited app notes are part of Pro. Unlock Pro to save notes for every app.",
+ "pro.prompt.notes": "Free version can save up to 3 app notes. Unlock Pro to save notes for every app.",
"pro.prompt.sorting": "Saved manual app sorting is part of Pro. Unlock Pro to keep your custom order.",
"pro.prompt.themes": "This theme is part of Pro. Unlock Pro to keep using advanced App Grid themes.",
"pro.purchase.failed": "Unable to complete the purchase right now. Please try again.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Custom shortcuts",
"pro.feature.customHotkeys.benefit": "Set your own global shortcuts for the app list and Quick Search.",
"pro.prompt.customHotkeys": "Custom shortcuts are part of Pro. Unlock Pro to set your own global shortcuts.",
- "hotkeys.customize": "Customize",
+ "hotkeys.customize": "Change shortcut",
"hotkeys.restoreDefault": "Restore default",
"hotkeys.recording": "Press the new shortcut now. Press Esc to cancel.",
"hotkeys.recordingInline": "Recording",
@@ -309,9 +309,39 @@
"hotkeys.saved": "Shortcut saved.",
"hotkeys.restored": "Default shortcut restored.",
"hotkeys.proRequired": "Unlock Pro to customize shortcuts.",
- "hotkeys.error.modifierRequired": "Use at least Command, Control, or two modifiers.",
+ "hotkeys.error.modifierRequired": "Use at least Command, Control, Option, or two modifiers.",
"hotkeys.error.unsupportedKey": "This key is not supported.",
"hotkeys.error.reserved": "This shortcut is reserved by macOS or the app.",
"hotkeys.error.duplicate": "This shortcut already belongs to another TagLauncher action.",
- "hotkeys.error.registrationFailed": "Shortcut could not be registered. Error code: %status%."
+ "hotkeys.error.registrationFailed": "Shortcut could not be registered. Error code: %status%.",
+ "pro.feature.customTagColors": "Custom tag colors",
+ "pro.feature.customTagColors.benefit": "Set any color for every tag, including SmartStart system category tags.",
+ "pro.prompt.customTagColors": "Custom tag colors are a Pro feature. Unlock Pro to give every tag any color and make categories easier to recognize.",
+ "settings.proStatus.freeUser": "You are currently a Free user",
+ "settings.proStatus.proUser": "You are currently a valued 👑Pro user",
+ "settings.proStatus.lockedListTitle": "Pro features to unlock",
+ "settings.proStatus.unlockedListTitle": "Unlocked features",
+ "settings.proStatus.lockedFeature": "✅ Supported",
+ "settings.proStatus.unlockedFeature": "✅ Unlocked",
+ "settings.proStatus.freeNotes": "3 free",
+ "settings.proStatus.unlimitedNotes": "✅ Unlimited notes",
+ "settings.proStatus.limitedFeature": "Limited",
+ "settings.proStatus.unsupportedFeature": "Not supported",
+ "settings.proFeature.appNotes": "Custom app notes",
+ "settings.proFeature.dataBackup": "Data import/export and layout backups",
+ "tag.customColor": "Custom color",
+ "settings.proBenefit.hotkeys": "Set your own shortcuts for TagLauncher actions.",
+ "settings.proBenefit.tags": "Give every tag a custom color for faster recognition.",
+ "settings.proBenefit.data": "Back up, export, import, and restore your categories and layout.",
+ "settings.proBenefit.about": "All Pro benefits are unlocked on this Mac.",
+ "settings.proBenefit.general": "Pro-only colored container and colored grid are available on this Mac.",
+ "settings.proGuide.hotkeys": "Default shortcuts are available. Pro users can customize shortcuts.",
+ "settings.proGuide.tags": "7 default colors are available. Pro users can customize more colors.",
+ "settings.proGuide.data": "Pro users can import and export category and layout data.",
+ "settings.proCompare.title": "Free vs Pro benefits",
+ "settings.proCompare.free": "Free",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Unavailable",
+ "settings.proStatus.previewFiveMinutes": "5-minute preview only",
+ "settings.proGuide.general": "Only Pro users can use colored containers / colored grids"
}
diff --git a/src/Apptag/Localization/es.json b/src/Apptag/Localization/es.json
index 691f036..c4ef53d 100644
--- a/src/Apptag/Localization/es.json
+++ b/src/Apptag/Localization/es.json
@@ -8,8 +8,8 @@
"menu.language": "Idioma",
"menu.help": "Ayuda",
"menu.version": "Versión",
- "menu.proStatus.free": "Actualmente eres usuario gratuito (actualizar a Pro)",
- "menu.proStatus.unlocked": "Actualmente eres un usuario Pro distinguido",
+ "menu.proStatus.free": "Actualmente eres usuario gratuito (actualiza ahora a 👑Pro)",
+ "menu.proStatus.unlocked": "Actualmente eres un usuario 👑Pro distinguido",
"settings.language": "Idioma",
"settings.languagePicker": "Idioma de la app:",
"settings.languageDesc": "Elige el idioma usado en los menús y ajustes.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "No hay resultados de clasificación inteligente para aplicar.",
"scheme.local": "Esquema local",
"scheme.systemSmartStart": "Esquema inicial inteligente del sistema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Mostrar consejos emergentes para:",
+ "settings.bubbleAllApps": "Todas las apps",
+ "settings.bubbleUncommonOnly": "Solo apps poco usadas",
+ "quickSearch.title": "Búsqueda rápida",
+ "quickSearch.placeholder": "Buscar apps, etiquetas y notas",
+ "quickSearch.inputAccessibility": "Campo de búsqueda rápida",
+ "quickSearch.emptyPrompt": "Empieza a escribir para buscar apps, etiquetas y notas.",
+ "quickSearch.noResults": "No se encontraron apps.",
+ "quickSearch.launchFailed": "No se pudo abrir esta app. Inténtalo de nuevo o elige otra app.",
+ "quickSearch.tagPrefix": "Etiqueta",
+ "quickSearch.hotkeys": "Atajos de teclado",
+ "quickSearch.mainHotkey": "Lista de apps",
+ "quickSearch.mainHotkeyDesc": "Abre la lista de apps de TagLauncher.",
+ "quickSearch.status.Active": "Activo",
+ "quickSearch.status.registrationFailed": "Error al registrar",
+ "quickSearch.status.unavailable": "Atajo no disponible",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% no se puede registrar ahora. Puede estar usado por macOS, un método de entrada u otra app. El atajo de la lista de apps no está disponible temporalmente. Revisa los atajos de teclado o los conflictos y reinicia TagLauncher. Código de error: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% no se puede registrar ahora. Puede estar usado por macOS, un método de entrada u otra app. La búsqueda rápida global no está disponible temporalmente. Revisa los atajos de teclado o los conflictos y reinicia TagLauncher. Código de error: %status%.",
+ "quickSearch.loading": "Preparando índice de búsqueda…",
+ "quickSearch.internalHotkey": "Búsqueda rápida (dentro de TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Funciona solo mientras la lista de apps de TagLauncher está abierta.",
+ "quickSearch.internalHotkeyStatus": "Solo lista de apps",
+ "quickSearch.globalHotkey": "Búsqueda rápida (global)",
+ "quickSearch.globalHotkeyDesc": "Abre la búsqueda rápida global cuando la lista de apps de TagLauncher no está visible.",
+ "quickSearch.spaceDisplay": "Space (barra espaciadora)",
"trackpadGesture.title": "Gesto del trackpad",
"trackpadGesture.description": "Asigna un gesto del trackpad en una herramienta de terceros a esta URL para mostrar la lista de apps.",
"trackpadGesture.status": "Herramienta externa",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Avance",
"pro.card.restore": "Restaurar compras",
- "pro.card.summary.free": "Desbloquee temas premium, importación y exportación de diseños, notas ilimitadas y clasificación manual de aplicaciones guardadas.",
+ "pro.card.summary.free": "Desbloquea colores personalizados de etiquetas, temas premium, importación y exportación de diseños, notas ilimitadas y atajos personalizados.",
"pro.card.summary.legacy": "Gracias por apoyar TagLauncher desde el principio. Tu acceso Pro ya está activo.",
- "pro.card.summary.unlocked": "Pro está activo en esta Mac. Los temas premium y las herramientas de diseño avanzadas están listos.",
+ "pro.card.summary.unlocked": "Pro está activo en este Mac. Ya están listos los colores personalizados, temas avanzados, notas ilimitadas, atajos personalizados y herramientas de diseño.",
"pro.card.title.free": "Actualízate a Pro",
"pro.card.title.legacy": "Pro desbloqueado",
"pro.card.title.unlocked": "Pro desbloqueado",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Guarde sus etiquetas, orden y diseño actuales como una copia de seguridad reutilizable.",
"pro.feature.import": "Importación de diseño",
"pro.feature.import.benefit": "Restaure un diseño de TagLauncher guardado en esta Mac en un solo paso.",
- "pro.feature.notes": "Notas ilimitadas",
- "pro.feature.notes.benefit": "Guarde notas para cada aplicación sin el límite gratuito de 5 notas.",
+ "pro.feature.notes": "Notas personalizadas de apps",
+ "pro.feature.notes.benefit": "La versión gratuita incluye 3 notas de apps. Pro desbloquea notas ilimitadas para todas las apps.",
"pro.feature.sorting": "Clasificación de aplicaciones guardadas",
"pro.feature.sorting.benefit": "Mantenga el orden manual de sus aplicaciones después de salir del modo de edición.",
"pro.feature.themes": "Temas premium",
"pro.feature.themes.benefit": "Desbloquea todos los temas avanzados de App Grid y consérvalos para siempre.",
- "pro.notes.limitReached": "La versión gratuita puede guardar notas de hasta 5 aplicaciones. Desbloquea Pro para guardar notas ilimitadas.",
+ "pro.notes.limitReached": "La versión gratuita puede guardar hasta 3 notas de apps. Desbloquea Pro para guardar notas ilimitadas.",
"pro.notes.remaining": "La versión gratuita incluye %limit% notas de la aplicación. Quedan %remaining%.",
"pro.operation.cancelled": "Compra cancelada.",
"pro.operation.loading": "Comprobando acceso Pro...",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Restaurando compra...",
"pro.prompt.export": "La exportación de diseño es una característica Pro. Desbloquee Pro para hacer una copia de seguridad de sus etiquetas, orden y diseño actuales.",
"pro.prompt.import": "La importación de diseños es una función Pro. Desbloquea Pro para restaurar un diseño guardado en esta Mac.",
- "pro.prompt.notes": "Las notas de aplicaciones ilimitadas son parte de Pro. Desbloquea Pro para guardar notas para cada aplicación.",
+ "pro.prompt.notes": "La versión gratuita puede guardar hasta 3 notas de apps. Desbloquea Pro para guardar notas en todas las apps.",
"pro.prompt.sorting": "La clasificación manual de aplicaciones guardadas es parte de Pro. Desbloquea Pro para mantener tu pedido personalizado.",
"pro.prompt.themes": "Este tema es parte de Pro. Desbloquea Pro para seguir usando temas avanzados de App Grid.",
"pro.purchase.failed": "No se puede completar la compra en este momento. Por favor inténtalo de nuevo.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Atajos personalizados",
"pro.feature.customHotkeys.benefit": "Define tus propios atajos globales para la lista de apps y Quick Search.",
"pro.prompt.customHotkeys": "Los atajos personalizados son parte de Pro. Desbloquea Pro para definir atajos globales.",
- "hotkeys.customize": "Personalizar",
+ "hotkeys.customize": "Cambiar atajo",
"hotkeys.restoreDefault": "Restaurar predeterminado",
"hotkeys.recording": "Pulsa ahora el nuevo atajo. Pulsa Esc para cancelar.",
"hotkeys.recordingInline": "Grabando",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Esta tecla no es compatible.",
"hotkeys.error.reserved": "Este atajo está reservado por macOS o por la app.",
"hotkeys.error.duplicate": "Este atajo ya pertenece a otra acción de TagLauncher.",
- "hotkeys.error.registrationFailed": "No se pudo registrar el atajo. Código de error: %status%."
+ "hotkeys.error.registrationFailed": "No se pudo registrar el atajo. Código de error: %status%.",
+ "pro.feature.customTagColors": "Colores personalizados de etiquetas",
+ "pro.feature.customTagColors.benefit": "Elige cualquier color para cada etiqueta, incluidas las categorías del sistema SmartStart.",
+ "pro.prompt.customTagColors": "Los colores personalizados de etiquetas son una función Pro. Desbloquea Pro para dar cualquier color a cada etiqueta y reconocer mejor tus categorías.",
+ "settings.proStatus.freeUser": "Actualmente eres usuario gratuito",
+ "settings.proStatus.proUser": "Actualmente eres un usuario 👑Pro distinguido",
+ "settings.proStatus.lockedListTitle": "Funciones Pro por desbloquear",
+ "settings.proStatus.unlockedListTitle": "Funciones desbloqueadas",
+ "settings.proStatus.lockedFeature": "✅ Compatible",
+ "settings.proStatus.unlockedFeature": "✅Desbloqueado",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Notas ilimitadas",
+ "settings.proStatus.limitedFeature": "Limitado",
+ "settings.proStatus.unsupportedFeature": "No compatible",
+ "settings.proFeature.appNotes": "Notas personalizadas de apps",
+ "settings.proFeature.dataBackup": "Importar/exportar datos y copias de diseño",
+ "tag.customColor": "Color personalizado",
+ "settings.proBenefit.hotkeys": "Configura tus propios atajos para acciones de TagLauncher.",
+ "settings.proBenefit.tags": "Da a cada etiqueta un color personalizado para reconocerla más rápido.",
+ "settings.proBenefit.data": "Crea copias, exporta, importa y restaura tus categorías y diseño.",
+ "settings.proBenefit.about": "Todos los beneficios Pro están desbloqueados en este Mac.",
+ "settings.proBenefit.general": "El contenedor de color y la cuadrícula de color Pro están disponibles en este Mac.",
+ "settings.proGuide.hotkeys": "Los atajos predeterminados están disponibles. Los usuarios Pro pueden personalizarlos.",
+ "settings.proGuide.tags": "Hay 7 colores predeterminados disponibles. Los usuarios Pro pueden personalizar más colores.",
+ "settings.proGuide.data": "Los usuarios Pro pueden importar y exportar datos de categorías y diseño.",
+ "settings.proCompare.title": "Diferencias entre Gratis y Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "No disponible",
+ "settings.proStatus.previewFiveMinutes": "Solo vista previa de 5 minutos",
+ "settings.proGuide.general": "Solo los usuarios Pro pueden usar contenedores / cuadrículas de color"
}
diff --git a/src/Apptag/Localization/fr.json b/src/Apptag/Localization/fr.json
index ea99e61..41cae04 100644
--- a/src/Apptag/Localization/fr.json
+++ b/src/Apptag/Localization/fr.json
@@ -8,8 +8,8 @@
"menu.language": "Langue",
"menu.help": "Aide",
"menu.version": "Version",
- "menu.proStatus.free": "Vous utilisez actuellement la version gratuite (passer à Pro)",
- "menu.proStatus.unlocked": "Vous êtes actuellement un utilisateur Pro privilégié",
+ "menu.proStatus.free": "Vous êtes actuellement utilisateur gratuit (passer maintenant à 👑Pro)",
+ "menu.proStatus.unlocked": "Vous êtes actuellement un utilisateur 👑Pro privilégié",
"settings.language": "Langue",
"settings.languagePicker": "Langue de l'app :",
"settings.languageDesc": "Choisissez la langue utilisée par les menus et les réglages.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Aucun résultat de classification intelligente à appliquer.",
"scheme.local": "Schéma local",
"scheme.systemSmartStart": "Schéma initial intelligent du système",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Afficher les bulles d’aide pour :",
+ "settings.bubbleAllApps": "Toutes les apps",
+ "settings.bubbleUncommonOnly": "Apps peu utilisées seulement",
+ "quickSearch.title": "Recherche rapide",
+ "quickSearch.placeholder": "Rechercher apps, étiquettes et notes",
+ "quickSearch.inputAccessibility": "Champ de recherche rapide",
+ "quickSearch.emptyPrompt": "Commencez à saisir pour rechercher des apps, des étiquettes et des notes.",
+ "quickSearch.noResults": "Aucune app trouvée.",
+ "quickSearch.launchFailed": "Impossible d’ouvrir cette app. Réessayez ou choisissez une autre app.",
+ "quickSearch.tagPrefix": "Étiquette",
+ "quickSearch.hotkeys": "Raccourcis clavier",
+ "quickSearch.mainHotkey": "Liste des apps",
+ "quickSearch.mainHotkeyDesc": "Ouvre la liste des apps TagLauncher.",
+ "quickSearch.status.Active": "Actif",
+ "quickSearch.status.registrationFailed": "Échec de l’enregistrement",
+ "quickSearch.status.unavailable": "Raccourci indisponible",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% ne peut pas être enregistré pour le moment. Il est peut-être utilisé par macOS, une méthode de saisie ou une autre app. Le raccourci de la liste des apps est temporairement indisponible. Vérifiez les raccourcis clavier ou les conflits, puis redémarrez TagLauncher. Code d’erreur : %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% ne peut pas être enregistré pour le moment. Il est peut-être utilisé par macOS, une méthode de saisie ou une autre app. La recherche rapide globale est temporairement indisponible. Vérifiez les raccourcis clavier ou les conflits, puis redémarrez TagLauncher. Code d’erreur : %status%.",
+ "quickSearch.loading": "Préparation de l’index de recherche…",
+ "quickSearch.internalHotkey": "Recherche rapide (dans TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Fonctionne uniquement lorsque la liste des apps TagLauncher est ouverte.",
+ "quickSearch.internalHotkeyStatus": "Liste des apps uniquement",
+ "quickSearch.globalHotkey": "Recherche rapide (globale)",
+ "quickSearch.globalHotkeyDesc": "Ouvre la recherche rapide globale lorsque la liste des apps TagLauncher n’est pas visible.",
+ "quickSearch.spaceDisplay": "Space (barre d’espace)",
"trackpadGesture.title": "Geste du trackpad",
"trackpadGesture.description": "Associez un geste du trackpad dans un outil tiers à cette URL pour afficher la liste des apps.",
"trackpadGesture.status": "Outil tiers",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Aperçu",
"pro.card.restore": "Restaurer les achats",
- "pro.card.summary.free": "Débloquez des thèmes premium, l'importation et l'exportation de mises en page, des notes illimitées et le tri manuel des applications enregistrées.",
+ "pro.card.summary.free": "Débloquez les couleurs personnalisées de tags, les thèmes premium, l’import/export de disposition, les notes illimitées et les raccourcis personnalisés.",
"pro.card.summary.legacy": "Merci d'avoir soutenu TagLauncher dès le début. Votre accès Pro est déjà actif.",
- "pro.card.summary.unlocked": "Pro est actif sur ce Mac. Les thèmes premium et les outils de mise en page avancés sont prêts.",
+ "pro.card.summary.unlocked": "Pro est actif sur ce Mac. Les couleurs de tags, thèmes avancés, notes illimitées, raccourcis personnalisés et outils de disposition sont prêts.",
"pro.card.title.free": "Passer à Pro",
"pro.card.title.legacy": "Pro débloqué",
"pro.card.title.unlocked": "Pro débloqué",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Enregistrez vos balises, votre commande et votre mise en page actuelles en tant que sauvegarde réutilisable.",
"pro.feature.import": "Importation de mise en page",
"pro.feature.import.benefit": "Restaurez une mise en page TagLauncher enregistrée sur ce Mac en une seule étape.",
- "pro.feature.notes": "Notes illimitées",
- "pro.feature.notes.benefit": "Enregistrez des notes pour chaque application sans la limite gratuite de 5 notes.",
+ "pro.feature.notes": "Notes d’app personnalisées",
+ "pro.feature.notes.benefit": "La version gratuite inclut 3 notes d’app. Pro débloque les notes illimitées pour chaque app.",
"pro.feature.sorting": "Tri des applications enregistrées",
"pro.feature.sorting.benefit": "Conservez l’ordre manuel de vos applications après avoir quitté le mode édition.",
"pro.feature.themes": "Thèmes premium",
"pro.feature.themes.benefit": "Débloquez tous les thèmes App Grid avancés et conservez-les en permanence.",
- "pro.notes.limitReached": "La version gratuite peut enregistrer des notes pour jusqu'à 5 applications. Débloquez Pro pour enregistrer un nombre illimité de notes.",
+ "pro.notes.limitReached": "La version gratuite peut enregistrer jusqu’à 3 notes d’app. Débloquez Pro pour des notes illimitées.",
"pro.notes.remaining": "La version gratuite comprend %limit% notes d'application. %remaining% restant.",
"pro.operation.cancelled": "Achat annulé.",
"pro.operation.loading": "Vérification de l'accès Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Restauration de l'achat…",
"pro.prompt.export": "L'exportation de mise en page est une fonctionnalité Pro. Débloquez Pro pour sauvegarder vos balises, votre commande et votre mise en page actuelles.",
"pro.prompt.import": "L'importation de mise en page est une fonctionnalité Pro. Déverrouillez Pro pour restaurer une mise en page enregistrée sur ce Mac.",
- "pro.prompt.notes": "Les notes d'application illimitées font partie de Pro. Débloquez Pro pour enregistrer des notes pour chaque application.",
+ "pro.prompt.notes": "La version gratuite peut enregistrer jusqu’à 3 notes d’app. Débloquez Pro pour noter chaque app.",
"pro.prompt.sorting": "Le tri manuel des applications enregistrées fait partie de Pro. Débloquez Pro pour conserver votre commande personnalisée.",
"pro.prompt.themes": "Ce thème fait partie de Pro. Débloquez Pro pour continuer à utiliser les thèmes App Grid avancés.",
"pro.purchase.failed": "Impossible de finaliser l'achat pour le moment. Veuillez réessayer.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Raccourcis personnalisés",
"pro.feature.customHotkeys.benefit": "Définissez vos raccourcis globaux pour la liste d’apps et Quick Search.",
"pro.prompt.customHotkeys": "Les raccourcis personnalisés font partie de Pro. Déverrouillez Pro pour définir vos raccourcis globaux.",
- "hotkeys.customize": "Personnaliser",
+ "hotkeys.customize": "Modifier le raccourci",
"hotkeys.restoreDefault": "Rétablir par défaut",
"hotkeys.recording": "Appuyez maintenant sur le nouveau raccourci. Esc pour annuler.",
"hotkeys.recordingInline": "Enregistrement",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Cette touche n’est pas prise en charge.",
"hotkeys.error.reserved": "Ce raccourci est réservé par macOS ou par l’app.",
"hotkeys.error.duplicate": "Ce raccourci est déjà utilisé par une autre action TagLauncher.",
- "hotkeys.error.registrationFailed": "Le raccourci n’a pas pu être enregistré. Code d’erreur : %status%."
+ "hotkeys.error.registrationFailed": "Le raccourci n’a pas pu être enregistré. Code d’erreur : %status%.",
+ "pro.feature.customTagColors": "Couleurs de tags personnalisées",
+ "pro.feature.customTagColors.benefit": "Choisissez n’importe quelle couleur pour chaque tag, y compris les catégories système SmartStart.",
+ "pro.prompt.customTagColors": "Les couleurs de tags personnalisées sont une fonction Pro. Débloquez Pro pour donner toute couleur à chaque tag et mieux reconnaître les catégories.",
+ "settings.proStatus.freeUser": "Vous êtes actuellement utilisateur gratuit",
+ "settings.proStatus.proUser": "Vous êtes actuellement un utilisateur 👑Pro privilégié",
+ "settings.proStatus.lockedListTitle": "Fonctions Pro à débloquer",
+ "settings.proStatus.unlockedListTitle": "Fonctions débloquées",
+ "settings.proStatus.lockedFeature": "✅ Pris en charge",
+ "settings.proStatus.unlockedFeature": "✅Débloqué",
+ "settings.proStatus.freeNotes": "3 gratuites",
+ "settings.proStatus.unlimitedNotes": "✅ Notes illimitées",
+ "settings.proStatus.limitedFeature": "Limité",
+ "settings.proStatus.unsupportedFeature": "Non pris en charge",
+ "settings.proFeature.appNotes": "Notes d’app personnalisées",
+ "settings.proFeature.dataBackup": "Import/export de données et sauvegardes de disposition",
+ "tag.customColor": "Couleur personnalisée",
+ "settings.proBenefit.hotkeys": "Définissez vos propres raccourcis pour les actions TagLauncher.",
+ "settings.proBenefit.tags": "Attribuez une couleur personnalisée à chaque tag pour le reconnaître plus vite.",
+ "settings.proBenefit.data": "Sauvegardez, exportez, importez et restaurez vos catégories et dispositions.",
+ "settings.proBenefit.about": "Tous les avantages Pro sont débloqués sur ce Mac.",
+ "settings.proBenefit.general": "Le conteneur couleur et la grille couleur Pro sont disponibles sur ce Mac.",
+ "settings.proGuide.hotkeys": "Les raccourcis par défaut sont disponibles. Les utilisateurs Pro peuvent les personnaliser.",
+ "settings.proGuide.tags": "7 couleurs par défaut sont disponibles. Les utilisateurs Pro peuvent personnaliser plus de couleurs.",
+ "settings.proGuide.data": "Les utilisateurs Pro peuvent importer et exporter les données de catégories et de disposition.",
+ "settings.proCompare.title": "Différences entre Gratuit et Pro",
+ "settings.proCompare.free": "Gratuit",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Indisponible",
+ "settings.proStatus.previewFiveMinutes": "Aperçu de 5 minutes seulement",
+ "settings.proGuide.general": "Seuls les utilisateurs Pro peuvent utiliser les conteneurs / grilles colorés"
}
diff --git a/src/Apptag/Localization/id.json b/src/Apptag/Localization/id.json
index a00bbb0..2332c92 100644
--- a/src/Apptag/Localization/id.json
+++ b/src/Apptag/Localization/id.json
@@ -8,8 +8,8 @@
"menu.language": "Bahasa",
"menu.help": "Bantuan",
"menu.version": "Versi",
- "menu.proStatus.free": "Saat ini Anda pengguna Gratis (tingkatkan ke Pro)",
- "menu.proStatus.unlocked": "Saat ini Anda pengguna Pro istimewa",
+ "menu.proStatus.free": "Saat ini Anda pengguna Gratis (tingkatkan sekarang ke 👑Pro)",
+ "menu.proStatus.unlocked": "Saat ini Anda pengguna 👑Pro istimewa",
"settings.language": "Bahasa",
"settings.languagePicker": "Bahasa aplikasi:",
"settings.languageDesc": "Pilih bahasa yang digunakan untuk menu dan pengaturan.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Tidak ada hasil klasifikasi pintar yang dapat diterapkan.",
"scheme.local": "Skema lokal",
"scheme.systemSmartStart": "Skema awal pintar sistem",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
+ "settings.bubbleDisplayScope": "Tampilkan tips gelembung untuk:",
+ "settings.bubbleAllApps": "Semua app",
+ "settings.bubbleUncommonOnly": "Hanya app yang jarang dipakai",
+ "quickSearch.title": "Pencarian cepat",
+ "quickSearch.placeholder": "Cari app, tag, dan catatan",
+ "quickSearch.inputAccessibility": "Input pencarian cepat",
+ "quickSearch.emptyPrompt": "Mulai mengetik untuk mencari app, tag, dan catatan.",
+ "quickSearch.noResults": "Tidak ada app ditemukan.",
+ "quickSearch.launchFailed": "App ini tidak dapat dibuka. Coba lagi atau pilih app lain.",
"quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "quickSearch.hotkeys": "Pintasan keyboard",
+ "quickSearch.mainHotkey": "Daftar app",
+ "quickSearch.mainHotkeyDesc": "Membuka daftar app TagLauncher.",
+ "quickSearch.status.Active": "Aktif",
+ "quickSearch.status.registrationFailed": "Pendaftaran gagal",
+ "quickSearch.status.unavailable": "Pintasan tidak tersedia",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% tidak dapat didaftarkan sekarang. Mungkin digunakan oleh macOS, metode input, atau app lain. Pintasan daftar app sementara tidak tersedia. Periksa pintasan keyboard atau konflik pintasan, lalu mulai ulang TagLauncher. Kode kesalahan: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% tidak dapat didaftarkan sekarang. Mungkin digunakan oleh macOS, metode input, atau app lain. Pencarian cepat global sementara tidak tersedia. Periksa pintasan keyboard atau konflik pintasan, lalu mulai ulang TagLauncher. Kode kesalahan: %status%.",
+ "quickSearch.loading": "Menyiapkan indeks pencarian…",
+ "quickSearch.internalHotkey": "Pencarian cepat (di dalam TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Hanya berfungsi saat daftar app TagLauncher terbuka.",
+ "quickSearch.internalHotkeyStatus": "Hanya daftar app",
+ "quickSearch.globalHotkey": "Pencarian cepat (global)",
+ "quickSearch.globalHotkeyDesc": "Buka pencarian cepat global saat daftar app TagLauncher tidak terlihat.",
+ "quickSearch.spaceDisplay": "Space (spasi)",
"trackpadGesture.title": "Gestur trackpad",
"trackpadGesture.description": "Petakan gestur trackpad di alat pihak ketiga ke URL ini untuk menampilkan daftar app.",
"trackpadGesture.status": "Alat eksternal",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Pratinjau",
"pro.card.restore": "Pulihkan Pembelian",
- "pro.card.summary.free": "Buka kunci tema premium, impor dan ekspor tata letak, catatan tak terbatas, dan penyortiran aplikasi manual yang tersimpan.",
+ "pro.card.summary.free": "Buka warna tag khusus, tema premium, impor dan ekspor tata letak, catatan app tanpa batas, dan pintasan khusus.",
"pro.card.summary.legacy": "Terima kasih telah mendukung TagLauncher lebih awal. Akses Pro Anda sudah aktif.",
- "pro.card.summary.unlocked": "Pro aktif di Mac ini. Tema premium dan alat tata letak tingkat lanjut sudah siap.",
+ "pro.card.summary.unlocked": "Pro aktif di Mac ini. Warna tag khusus, tema lanjutan, catatan tanpa batas, pintasan khusus, dan alat tata letak siap digunakan.",
"pro.card.title.free": "Tingkatkan ke Pro",
"pro.card.title.legacy": "Pro tidak terkunci",
"pro.card.title.unlocked": "Pro tidak terkunci",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Simpan tag, urutan, dan tata letak Anda saat ini sebagai cadangan yang dapat digunakan kembali.",
"pro.feature.import": "Impor tata letak",
"pro.feature.import.benefit": "Pulihkan tata letak TagLauncher yang disimpan di Mac ini dalam satu langkah.",
- "pro.feature.notes": "Catatan tanpa batas",
- "pro.feature.notes.benefit": "Simpan catatan untuk setiap aplikasi tanpa batas 5 nada gratis.",
+ "pro.feature.notes": "Catatan app khusus",
+ "pro.feature.notes.benefit": "Versi gratis menyertakan 3 catatan app. Pro membuka catatan tanpa batas untuk semua app.",
"pro.feature.sorting": "Penyortiran aplikasi tersimpan",
"pro.feature.sorting.benefit": "Simpan urutan aplikasi manual Anda setelah Anda keluar dari mode pengeditan.",
"pro.feature.themes": "Tema premium",
"pro.feature.themes.benefit": "Buka kunci setiap tema App Grid tingkat lanjut dan simpan secara permanen.",
- "pro.notes.limitReached": "Versi gratis dapat menyimpan catatan hingga 5 aplikasi. Buka kunci Pro untuk menyimpan catatan tanpa batas.",
+ "pro.notes.limitReached": "Versi gratis dapat menyimpan hingga 3 catatan app. Buka Pro untuk catatan tanpa batas.",
"pro.notes.remaining": "Versi gratis mencakup %limit% catatan aplikasi. %remaining% tersisa.",
"pro.operation.cancelled": "Pembelian dibatalkan.",
"pro.operation.loading": "Memeriksa akses Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Memulihkan pembelian…",
"pro.prompt.export": "Ekspor tata letak adalah fitur Pro. Buka kunci Pro untuk mencadangkan tag, urutan, dan tata letak Anda saat ini.",
"pro.prompt.import": "Impor tata letak adalah fitur Pro. Buka kunci Pro untuk memulihkan tata letak yang disimpan di Mac ini.",
- "pro.prompt.notes": "Catatan aplikasi tanpa batas adalah bagian dari Pro. Buka kunci Pro untuk menyimpan catatan untuk setiap aplikasi.",
+ "pro.prompt.notes": "Versi gratis dapat menyimpan hingga 3 catatan app. Buka Pro untuk menyimpan catatan untuk semua app.",
"pro.prompt.sorting": "Penyortiran aplikasi manual yang disimpan adalah bagian dari Pro. Buka kunci Pro untuk menyimpan pesanan khusus Anda.",
"pro.prompt.themes": "Tema ini adalah bagian dari Pro. Buka kunci Pro untuk terus menggunakan tema App Grid tingkat lanjut.",
"pro.purchase.failed": "Tidak dapat menyelesaikan pembelian saat ini. Silakan coba lagi.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Pintasan khusus",
"pro.feature.customHotkeys.benefit": "Atur pintasan global untuk daftar app dan Quick Search.",
"pro.prompt.customHotkeys": "Pintasan khusus adalah fitur Pro. Buka Pro untuk mengatur pintasan global.",
- "hotkeys.customize": "Sesuaikan",
+ "hotkeys.customize": "Ubah pintasan",
"hotkeys.restoreDefault": "Pulihkan bawaan",
"hotkeys.recording": "Tekan pintasan baru sekarang. Tekan Esc untuk membatalkan.",
"hotkeys.recordingInline": "Merekam",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Tombol ini tidak didukung.",
"hotkeys.error.reserved": "Pintasan ini dicadangkan oleh macOS atau app.",
"hotkeys.error.duplicate": "Pintasan ini sudah dipakai oleh tindakan TagLauncher lain.",
- "hotkeys.error.registrationFailed": "Pintasan tidak dapat didaftarkan. Kode kesalahan: %status%."
+ "hotkeys.error.registrationFailed": "Pintasan tidak dapat didaftarkan. Kode kesalahan: %status%.",
+ "pro.feature.customTagColors": "Warna tag khusus",
+ "pro.feature.customTagColors.benefit": "Atur warna apa pun untuk tiap tag, termasuk tag kategori sistem SmartStart.",
+ "pro.prompt.customTagColors": "Warna tag khusus adalah fitur Pro. Buka Pro untuk memberi tiap tag warna apa pun agar kategori lebih mudah dikenali.",
+ "settings.proStatus.freeUser": "Saat ini Anda pengguna Gratis",
+ "settings.proStatus.proUser": "Saat ini Anda pengguna 👑Pro istimewa",
+ "settings.proStatus.lockedListTitle": "Fitur Pro untuk dibuka",
+ "settings.proStatus.unlockedListTitle": "Fitur yang terbuka",
+ "settings.proStatus.lockedFeature": "✅ Didukung",
+ "settings.proStatus.unlockedFeature": "✅Terbuka",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Catatan tanpa batas",
+ "settings.proStatus.limitedFeature": "Terbatas",
+ "settings.proStatus.unsupportedFeature": "Tidak didukung",
+ "settings.proFeature.appNotes": "Catatan app khusus",
+ "settings.proFeature.dataBackup": "Impor/ekspor data dan cadangan tata letak",
+ "tag.customColor": "Warna khusus",
+ "settings.proBenefit.hotkeys": "Atur pintasan sendiri untuk tindakan TagLauncher.",
+ "settings.proBenefit.tags": "Beri setiap tag warna khusus agar lebih cepat dikenali.",
+ "settings.proBenefit.data": "Cadangkan, ekspor, impor, dan pulihkan kategori serta tata letak.",
+ "settings.proBenefit.about": "Semua manfaat Pro terbuka di Mac ini.",
+ "settings.proBenefit.general": "Kontainer berwarna dan kisi berwarna Pro tersedia di Mac ini.",
+ "settings.proGuide.hotkeys": "Pintasan bawaan tersedia. Pengguna Pro dapat menyesuaikan pintasan.",
+ "settings.proGuide.tags": "7 warna bawaan tersedia. Pengguna Pro dapat menyesuaikan lebih banyak warna.",
+ "settings.proGuide.data": "Pengguna Pro dapat mengimpor dan mengekspor data kategori dan tata letak.",
+ "settings.proCompare.title": "Perbedaan Gratis dan Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Tidak tersedia",
+ "settings.proStatus.previewFiveMinutes": "Hanya pratinjau 5 menit",
+ "settings.proGuide.general": "Hanya pengguna Pro yang dapat memakai kontainer / kisi berwarna"
}
diff --git a/src/Apptag/Localization/it.json b/src/Apptag/Localization/it.json
index c562e8a..5d5c87c 100644
--- a/src/Apptag/Localization/it.json
+++ b/src/Apptag/Localization/it.json
@@ -8,8 +8,8 @@
"menu.language": "Lingua",
"menu.help": "Aiuto",
"menu.version": "Versione",
- "menu.proStatus.free": "Attualmente sei un utente gratuito (passa a Pro)",
- "menu.proStatus.unlocked": "Attualmente sei un utente Pro privilegiato",
+ "menu.proStatus.free": "Al momento sei un utente gratuito (passa subito a 👑Pro)",
+ "menu.proStatus.unlocked": "Al momento sei un utente 👑Pro privilegiato",
"settings.language": "Lingua",
"settings.languagePicker": "Lingua app:",
"settings.languageDesc": "Scegli la lingua usata da menu e impostazioni.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Nessun risultato di classificazione intelligente disponibile.",
"scheme.local": "Schema locale",
"scheme.systemSmartStart": "Schema iniziale intelligente di sistema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
+ "settings.bubbleDisplayScope": "Mostra suggerimenti a fumetto per:",
+ "settings.bubbleAllApps": "Tutte le app",
+ "settings.bubbleUncommonOnly": "Solo app poco usate",
+ "quickSearch.title": "Ricerca rapida",
+ "quickSearch.placeholder": "Cerca app, tag e note",
+ "quickSearch.inputAccessibility": "Campo di ricerca rapida",
+ "quickSearch.emptyPrompt": "Inizia a digitare per cercare app, tag e note.",
+ "quickSearch.noResults": "Nessuna app trovata.",
+ "quickSearch.launchFailed": "Impossibile aprire questa app. Riprova o scegli un’altra app.",
"quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "quickSearch.hotkeys": "Scorciatoie da tastiera",
+ "quickSearch.mainHotkey": "Elenco app",
+ "quickSearch.mainHotkeyDesc": "Apre l’elenco app di TagLauncher.",
+ "quickSearch.status.Active": "Attiva",
+ "quickSearch.status.registrationFailed": "Registrazione non riuscita",
+ "quickSearch.status.unavailable": "Scorciatoia non disponibile",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% non può essere registrata ora. Potrebbe essere usata da macOS, da un metodo di input o da un’altra app. La scorciatoia dell’elenco app è temporaneamente non disponibile. Controlla le scorciatoie da tastiera o i conflitti, poi riavvia TagLauncher. Codice errore: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% non può essere registrata ora. Potrebbe essere usata da macOS, da un metodo di input o da un’altra app. La ricerca rapida globale è temporaneamente non disponibile. Controlla le scorciatoie da tastiera o i conflitti, poi riavvia TagLauncher. Codice errore: %status%.",
+ "quickSearch.loading": "Preparazione dell’indice di ricerca…",
+ "quickSearch.internalHotkey": "Ricerca rapida (in TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Funziona solo mentre l’elenco app di TagLauncher è aperto.",
+ "quickSearch.internalHotkeyStatus": "Solo elenco app",
+ "quickSearch.globalHotkey": "Ricerca rapida (globale)",
+ "quickSearch.globalHotkeyDesc": "Apri la ricerca rapida globale quando l’elenco app di TagLauncher non è visibile.",
+ "quickSearch.spaceDisplay": "Space (barra spaziatrice)",
"trackpadGesture.title": "Gesto del trackpad",
"trackpadGesture.description": "Associa un gesto del trackpad in uno strumento di terze parti a questo URL per mostrare l’elenco delle app.",
"trackpadGesture.status": "Strumento esterno",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Anteprima",
"pro.card.restore": "Ripristina gli acquisti",
- "pro.card.summary.free": "Sblocca temi premium, importazione ed esportazione di layout, note illimitate e ordinamento manuale delle app salvate.",
+ "pro.card.summary.free": "Sblocca colori tag personalizzati, temi premium, importazione ed esportazione layout, note app illimitate e scorciatoie personalizzate.",
"pro.card.summary.legacy": "Grazie per aver supportato subito TagLauncher. Il tuo accesso Pro è già attivo.",
- "pro.card.summary.unlocked": "Pro è attivo su questo Mac. Temi premium e strumenti di layout avanzati sono pronti.",
+ "pro.card.summary.unlocked": "Pro è attivo su questo Mac. Colori tag personalizzati, temi avanzati, note illimitate, scorciatoie personalizzate e strumenti layout sono pronti.",
"pro.card.title.free": "Aggiorna a Pro",
"pro.card.title.legacy": "Pro sbloccato",
"pro.card.title.unlocked": "Pro sbloccato",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Salva i tag, l'ordine e il layout correnti come backup riutilizzabile.",
"pro.feature.import": "Importazione del layout",
"pro.feature.import.benefit": "Ripristina un layout TagLauncher salvato su questo Mac in un solo passaggio.",
- "pro.feature.notes": "Note illimitate",
- "pro.feature.notes.benefit": "Salva note per ogni app senza il limite gratuito di 5 note.",
+ "pro.feature.notes": "Note app personalizzate",
+ "pro.feature.notes.benefit": "La versione gratuita include 3 note app. Pro sblocca note illimitate per ogni app.",
"pro.feature.sorting": "Ordinamento delle app salvate",
"pro.feature.sorting.benefit": "Mantieni l'ordine manuale delle app dopo aver abbandonato la modalità di modifica.",
"pro.feature.themes": "Temi premium",
"pro.feature.themes.benefit": "Sblocca tutti i temi App Grid avanzati e mantienili in modo permanente.",
- "pro.notes.limitReached": "La versione gratuita può salvare note per un massimo di 5 app. Sblocca Pro per salvare note illimitate.",
+ "pro.notes.limitReached": "La versione gratuita può salvare fino a 3 note app. Sblocca Pro per note illimitate.",
"pro.notes.remaining": "La versione gratuita include %limit% note sull'app. %remaining% rimanenti.",
"pro.operation.cancelled": "Acquisto annullato.",
"pro.operation.loading": "Verifica dell'accesso a Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Ripristino dell'acquisto…",
"pro.prompt.export": "L'esportazione del layout è una funzionalità di Pro. Sblocca Pro per eseguire il backup dei tag, dell'ordine e del layout attuali.",
"pro.prompt.import": "L'importazione del layout è una funzionalità Pro. Sblocca Pro per ripristinare un layout salvato su questo Mac.",
- "pro.prompt.notes": "Le note sull'app illimitate fanno parte di Pro. Sblocca Pro per salvare le note per ogni app.",
+ "pro.prompt.notes": "La versione gratuita può salvare fino a 3 note app. Sblocca Pro per salvare note per ogni app.",
"pro.prompt.sorting": "L'ordinamento manuale delle app salvate fa parte di Pro. Sblocca Pro per mantenere il tuo ordine personalizzato.",
"pro.prompt.themes": "Questo tema fa parte di Pro. Sblocca Pro per continuare a utilizzare i temi App Grid avanzati.",
"pro.purchase.failed": "Impossibile completare l'acquisto in questo momento. Per favore riprova.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Scorciatoie personalizzate",
"pro.feature.customHotkeys.benefit": "Imposta scorciatoie globali per elenco app e Quick Search.",
"pro.prompt.customHotkeys": "Le scorciatoie personalizzate fanno parte di Pro. Sblocca Pro per impostarle.",
- "hotkeys.customize": "Personalizza",
+ "hotkeys.customize": "Cambia scorciatoia",
"hotkeys.restoreDefault": "Ripristina predefinito",
"hotkeys.recording": "Premi ora la nuova scorciatoia. Premi Esc per annullare.",
"hotkeys.recordingInline": "Registrazione",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Questo tasto non è supportato.",
"hotkeys.error.reserved": "Questa scorciatoia è riservata da macOS o dall’app.",
"hotkeys.error.duplicate": "Questa scorciatoia è già usata da un’altra azione TagLauncher.",
- "hotkeys.error.registrationFailed": "Impossibile registrare la scorciatoia. Codice errore: %status%."
+ "hotkeys.error.registrationFailed": "Impossibile registrare la scorciatoia. Codice errore: %status%.",
+ "pro.feature.customTagColors": "Colori tag personalizzati",
+ "pro.feature.customTagColors.benefit": "Imposta qualsiasi colore per ogni tag, incluse le categorie di sistema SmartStart.",
+ "pro.prompt.customTagColors": "I colori tag personalizzati sono una funzione Pro. Sblocca Pro per dare qualsiasi colore a ogni tag e riconoscere meglio le categorie.",
+ "settings.proStatus.freeUser": "Al momento sei un utente gratuito",
+ "settings.proStatus.proUser": "Al momento sei un utente 👑Pro privilegiato",
+ "settings.proStatus.lockedListTitle": "Funzioni Pro da sbloccare",
+ "settings.proStatus.unlockedListTitle": "Funzioni sbloccate",
+ "settings.proStatus.lockedFeature": "✅ Supportato",
+ "settings.proStatus.unlockedFeature": "✅Sbloccata",
+ "settings.proStatus.freeNotes": "3 gratuite",
+ "settings.proStatus.unlimitedNotes": "✅ Note illimitate",
+ "settings.proStatus.limitedFeature": "Limitata",
+ "settings.proStatus.unsupportedFeature": "Non supportato",
+ "settings.proFeature.appNotes": "Note app personalizzate",
+ "settings.proFeature.dataBackup": "Import/export dati e backup layout",
+ "tag.customColor": "Colore personalizzato",
+ "settings.proBenefit.hotkeys": "Imposta scorciatoie personali per le azioni di TagLauncher.",
+ "settings.proBenefit.tags": "Dai a ogni tag un colore personalizzato per riconoscerlo più velocemente.",
+ "settings.proBenefit.data": "Esegui backup, esporta, importa e ripristina categorie e layout.",
+ "settings.proBenefit.about": "Tutti i vantaggi Pro sono sbloccati su questo Mac.",
+ "settings.proBenefit.general": "Contenitore colorato e griglia colorata Pro sono disponibili su questo Mac.",
+ "settings.proGuide.hotkeys": "Le scorciatoie predefinite sono disponibili. Gli utenti Pro possono personalizzarle.",
+ "settings.proGuide.tags": "Sono disponibili 7 colori predefiniti. Gli utenti Pro possono personalizzare altri colori.",
+ "settings.proGuide.data": "Gli utenti Pro possono importare ed esportare dati di categorie e layout.",
+ "settings.proCompare.title": "Differenze tra Gratis e Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Non disponibile",
+ "settings.proStatus.previewFiveMinutes": "Solo anteprima di 5 minuti",
+ "settings.proGuide.general": "Solo gli utenti Pro possono usare contenitori / griglie colorati"
}
diff --git a/src/Apptag/Localization/ja.json b/src/Apptag/Localization/ja.json
index c7de802..b0ee7ef 100644
--- a/src/Apptag/Localization/ja.json
+++ b/src/Apptag/Localization/ja.json
@@ -8,8 +8,8 @@
"menu.language": "言語",
"menu.help": "ヘルプ",
"menu.version": "バージョン",
- "menu.proStatus.free": "現在は無料版ユーザーです(Pro にアップグレード)",
- "menu.proStatus.unlocked": "現在は特別な Pro ユーザーです",
+ "menu.proStatus.free": "現在は無料版ユーザーです(今すぐ 👑Pro にアップグレード)",
+ "menu.proStatus.unlocked": "現在は特別な 👑Pro ユーザーです",
"settings.language": "言語",
"settings.languagePicker": "アプリの言語:",
"settings.languageDesc": "メニューと設定で使う言語を選択します。",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "適用できるスマート分類結果がありませんでした。",
"scheme.local": "ローカル分類スキーム",
"scheme.systemSmartStart": "システム初期スマート分類",
- "settings.bubbleDisplayScope": "吹き出しの表示対象:",
+ "settings.bubbleDisplayScope": "バブルヒントの表示対象:",
"settings.bubbleAllApps": "すべてのアプリ",
- "settings.bubbleUncommonOnly": "あまり使わないアプリのみ",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleUncommonOnly": "使用頻度の低いアプリのみ",
+ "quickSearch.title": "クイック検索",
+ "quickSearch.placeholder": "アプリ、タグ、メモを検索",
+ "quickSearch.inputAccessibility": "クイック検索入力欄",
+ "quickSearch.emptyPrompt": "入力を開始してアプリ、タグ、メモを検索します。",
+ "quickSearch.noResults": "アプリが見つかりません。",
+ "quickSearch.launchFailed": "このアプリを開けません。もう一度試すか、別のアプリを選択してください。",
+ "quickSearch.tagPrefix": "タグ",
+ "quickSearch.hotkeys": "キーボードショートカット",
+ "quickSearch.mainHotkey": "アプリ一覧",
+ "quickSearch.mainHotkeyDesc": "TagLauncher のアプリ一覧を開きます。",
+ "quickSearch.status.Active": "有効",
+ "quickSearch.status.registrationFailed": "登録に失敗",
+ "quickSearch.status.unavailable": "ショートカットを使用できません",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% は現在登録できません。macOS、入力方式、または別のアプリで使用されている可能性があります。アプリ一覧のショートカットは一時的に使用できません。キーボードショートカットや競合を確認してから TagLauncher を再起動してください。エラーコード: %status%。",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% は現在登録できません。macOS、入力方式、または別のアプリで使用されている可能性があります。グローバルクイック検索は一時的に使用できません。キーボードショートカットや競合を確認してから TagLauncher を再起動してください。エラーコード: %status%。",
+ "quickSearch.loading": "検索インデックスを準備中…",
+ "quickSearch.internalHotkey": "クイック検索(TagLauncher 内)",
+ "quickSearch.internalHotkeyDesc": "TagLauncher のアプリ一覧が開いている間のみ動作します。",
+ "quickSearch.internalHotkeyStatus": "アプリ一覧のみ",
+ "quickSearch.globalHotkey": "クイック検索(グローバル)",
+ "quickSearch.globalHotkeyDesc": "TagLauncher のアプリ一覧が表示されていないときに、グローバルにクイック検索を開きます。",
+ "quickSearch.spaceDisplay": "Space(スペースキー)",
"trackpadGesture.title": "トラックパッドジェスチャ",
"trackpadGesture.description": "サードパーティ製ツールでトラックパッドジェスチャをこのURLに割り当てると、アプリ一覧を表示できます。",
"trackpadGesture.status": "外部ツール",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "プレビュー",
"pro.card.restore": "購入を復元",
- "pro.card.summary.free": "プレミアム テーマ、レイアウトのインポートとエクスポート、無制限のメモ、および保存された手動アプリの並べ替えのロックを解除します。",
+ "pro.card.summary.free": "カスタムタグ色、プレミアムテーマ、レイアウトの読み書き、無制限のアプリメモ、カスタムショートカットを解除します。",
"pro.card.summary.legacy": "早期に TagLauncher をサポートしていただきありがとうございます。 Pro アクセスはすでにアクティブです。",
- "pro.card.summary.unlocked": "Pro はこの Mac 上でアクティブです。プレミアム テーマと高度なレイアウト ツールが用意されています。",
+ "pro.card.summary.unlocked": "この Mac で Pro が有効です。カスタムタグ色、高度なテーマ、無制限メモ、カスタムショートカット、レイアウトツールを利用できます。",
"pro.card.title.free": "Pro にアップグレード",
"pro.card.title.legacy": "Pro ロック解除",
"pro.card.title.unlocked": "Pro ロック解除",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "現在のタグ、順序、レイアウトを再利用可能なバックアップとして保存します。",
"pro.feature.import": "レイアウト インポート",
"pro.feature.import.benefit": "保存されている TagLauncher レイアウトをこの Mac にワンステップで復元します。",
- "pro.feature.notes": "無制限メモ",
- "pro.feature.notes.benefit": "無料の 5 メモ制限なしで、すべてのアプリのメモを保存します。",
+ "pro.feature.notes": "カスタムアプリメモ",
+ "pro.feature.notes.benefit": "無料版ではアプリメモを 3 件まで保存できます。Pro ではすべてのアプリに無制限で保存できます。",
"pro.feature.sorting": "保存したアプリの並べ替え",
"pro.feature.sorting.benefit": "編集モードを終了した後も、手動でアプリの順序を維持します。",
"pro.feature.themes": "プレミアム テーマ",
"pro.feature.themes.benefit": "すべての高度な App Grid のロックを解除します",
- "pro.notes.limitReached": "無料版では、最大 5 つのアプリのメモを保存できます。 Pro のロックを解除すると、メモを無制限に保存できます。",
+ "pro.notes.limitReached": "無料版で保存できるアプリメモは 3 件までです。Pro を解除すると無制限に保存できます。",
"pro.notes.remaining": "無料版には %limit% 個のアプリ メモが含まれています。残り %remaining% が残っています。",
"pro.operation.cancelled": "購入はキャンセルされました。",
"pro.operation.loading": "Pro アクセスを確認中…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "購入を復元中…",
"pro.prompt.export": "レイアウトのエクスポートは Pro 機能です。 Pro のロックを解除して、現在のタグ、順序、レイアウトをバックアップします。",
"pro.prompt.import": "レイアウトのインポートは Pro 機能です。 Pro のロックを解除して、この Mac に保存されたレイアウトを復元します。",
- "pro.prompt.notes": "無制限のアプリ ノートは Pro の一部です。 Pro のロックを解除して、すべてのアプリのメモを保存します。",
+ "pro.prompt.notes": "無料版で保存できるアプリメモは 3 件までです。Pro を解除するとすべてのアプリにメモを保存できます。",
"pro.prompt.sorting": "保存されたアプリの手動並べ替えは Pro の一部です。カスタム オーダーを維持するには、Pro のロックを解除してください。",
"pro.prompt.themes": "このテーマは Pro の一部です。高度な App Grid テーマを引き続き使用するには、Pro のロックを解除してください。",
"pro.purchase.failed": "現在購入を完了できません。もう一度お試しください。",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "カスタムショートカット",
"pro.feature.customHotkeys.benefit": "アプリ一覧と Quick Search のグローバルショートカットを設定できます。",
"pro.prompt.customHotkeys": "カスタムショートカットは Pro 機能です。Pro を解除すると設定できます。",
- "hotkeys.customize": "カスタマイズ",
+ "hotkeys.customize": "ショートカットを変更",
"hotkeys.restoreDefault": "デフォルトに戻す",
"hotkeys.recording": "新しいショートカットを押してください。Esc でキャンセル。",
"hotkeys.recordingInline": "録画中",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "このキーはサポートされていません。",
"hotkeys.error.reserved": "このショートカットは macOS またはアプリで予約されています。",
"hotkeys.error.duplicate": "このショートカットは別の TagLauncher 操作で使用済みです。",
- "hotkeys.error.registrationFailed": "ショートカットを登録できませんでした。エラーコード:%status%。"
+ "hotkeys.error.registrationFailed": "ショートカットを登録できませんでした。エラーコード:%status%。",
+ "pro.feature.customTagColors": "カスタムタグ色",
+ "pro.feature.customTagColors.benefit": "SmartStart のシステムカテゴリタグを含め、各タグに任意の色を設定できます。",
+ "pro.prompt.customTagColors": "カスタムタグ色は Pro 機能です。Pro を解除すると各タグに任意の色を設定でき、カテゴリを見分けやすくなります。",
+ "settings.proStatus.freeUser": "現在は無料版ユーザーです",
+ "settings.proStatus.proUser": "現在は特別な 👑Pro ユーザーです",
+ "settings.proStatus.lockedListTitle": "解除待ちの Pro 機能",
+ "settings.proStatus.unlockedListTitle": "解除済み機能",
+ "settings.proStatus.lockedFeature": "✅ 対応",
+ "settings.proStatus.unlockedFeature": "✅解除済み",
+ "settings.proStatus.freeNotes": "無料 3 件",
+ "settings.proStatus.unlimitedNotes": "✅ 無制限メモ",
+ "settings.proStatus.limitedFeature": "制限あり",
+ "settings.proStatus.unsupportedFeature": "非対応",
+ "settings.proFeature.appNotes": "カスタムアプリメモ",
+ "settings.proFeature.dataBackup": "データ読み書きとレイアウトバックアップ",
+ "tag.customColor": "カスタム色",
+ "settings.proBenefit.hotkeys": "TagLauncher の操作に独自のショートカットを設定できます。",
+ "settings.proBenefit.tags": "各タグにカスタム色を付けて、すばやく見分けられます。",
+ "settings.proBenefit.data": "カテゴリとレイアウトをバックアップ、書き出し、読み込み、復元できます。",
+ "settings.proBenefit.about": "この Mac ではすべての Pro 特典が解除されています。",
+ "settings.proBenefit.general": "この Mac で Pro 専用のカラーコンテナとカラーグリッドを使用できます。",
+ "settings.proGuide.hotkeys": "既定のショートカットは利用できます。Pro ユーザーはショートカットをカスタマイズできます。",
+ "settings.proGuide.tags": "既定の 7 色は利用できます。Pro ユーザーはさらに多くの色をカスタマイズできます。",
+ "settings.proGuide.data": "Pro ユーザーはカテゴリとレイアウトデータを読み込み、書き出せます。",
+ "settings.proCompare.title": "無料版と Pro 版の違い",
+ "settings.proCompare.free": "無料版",
+ "settings.proCompare.pro": "Pro 版",
+ "settings.proStatus.unavailableFeature": "利用不可",
+ "settings.proStatus.previewFiveMinutes": "5分間だけプレビュー",
+ "settings.proGuide.general": "カラーコンテナ / カラーグリッドは Pro ユーザーのみ利用できます"
}
diff --git a/src/Apptag/Localization/ko.json b/src/Apptag/Localization/ko.json
index d649ebc..5339ab2 100644
--- a/src/Apptag/Localization/ko.json
+++ b/src/Apptag/Localization/ko.json
@@ -8,8 +8,8 @@
"menu.language": "언어",
"menu.help": "도움말",
"menu.version": "버전",
- "menu.proStatus.free": "현재 무료 사용자입니다(Pro로 업그레이드)",
- "menu.proStatus.unlocked": "현재 특별 Pro 사용자입니다",
+ "menu.proStatus.free": "현재 무료 사용자입니다(지금 👑Pro로 업그레이드)",
+ "menu.proStatus.unlocked": "현재 특별 👑Pro 사용자입니다",
"settings.language": "언어",
"settings.languagePicker": "앱 언어:",
"settings.languageDesc": "메뉴와 설정에서 사용할 언어를 선택합니다.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "적용할 수 있는 스마트 분류 결과가 없습니다.",
"scheme.local": "로컬 분류 방식",
"scheme.systemSmartStart": "시스템 스마트 초기 분류",
- "settings.bubbleDisplayScope": "말풍선 표시 대상:",
+ "settings.bubbleDisplayScope": "말풍선 팁 표시 대상:",
"settings.bubbleAllApps": "모든 앱",
"settings.bubbleUncommonOnly": "자주 쓰지 않는 앱만",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "quickSearch.title": "빠른 검색",
+ "quickSearch.placeholder": "앱, 태그, 메모 검색",
+ "quickSearch.inputAccessibility": "빠른 검색 입력란",
+ "quickSearch.emptyPrompt": "앱, 태그, 메모를 검색하려면 입력을 시작하세요.",
+ "quickSearch.noResults": "앱을 찾을 수 없습니다.",
+ "quickSearch.launchFailed": "이 앱을 열 수 없습니다. 다시 시도하거나 다른 앱을 선택하세요.",
+ "quickSearch.tagPrefix": "태그",
+ "quickSearch.hotkeys": "키보드 단축키",
+ "quickSearch.mainHotkey": "앱 목록",
+ "quickSearch.mainHotkeyDesc": "TagLauncher 앱 목록을 엽니다.",
+ "quickSearch.status.Active": "활성",
+ "quickSearch.status.registrationFailed": "등록 실패",
+ "quickSearch.status.unavailable": "단축키 사용 불가",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut%을(를) 지금 등록할 수 없습니다. macOS, 입력기 또는 다른 앱에서 사용 중일 수 있습니다. 앱 목록 단축키를 일시적으로 사용할 수 없습니다. 키보드 단축키나 단축키 충돌을 확인한 뒤 TagLauncher를 다시 시작하세요. 오류 코드: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut%을(를) 지금 등록할 수 없습니다. macOS, 입력기 또는 다른 앱에서 사용 중일 수 있습니다. 전역 빠른 검색을 일시적으로 사용할 수 없습니다. 키보드 단축키나 단축키 충돌을 확인한 뒤 TagLauncher를 다시 시작하세요. 오류 코드: %status%.",
+ "quickSearch.loading": "검색 색인을 준비하는 중…",
+ "quickSearch.internalHotkey": "빠른 검색(TagLauncher 내부)",
+ "quickSearch.internalHotkeyDesc": "TagLauncher 앱 목록이 열려 있을 때만 작동합니다.",
+ "quickSearch.internalHotkeyStatus": "앱 목록에서만",
+ "quickSearch.globalHotkey": "빠른 검색(전역)",
+ "quickSearch.globalHotkeyDesc": "TagLauncher 앱 목록이 보이지 않을 때 전역 빠른 검색을 엽니다.",
+ "quickSearch.spaceDisplay": "Space(스페이스 키)",
"trackpadGesture.title": "트랙패드 제스처",
"trackpadGesture.description": "서드파티 도구에서 트랙패드 제스처를 이 URL에 연결하면 앱 목록이 열립니다.",
"trackpadGesture.status": "외부 도구",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "미리보기",
"pro.card.restore": "구매 복원",
- "pro.card.summary.free": "프리미엄 테마, 레이아웃 가져오기 및 내보내기, 무제한 메모, 저장된 수동 앱 정렬 기능을 잠금 해제하세요.",
+ "pro.card.summary.free": "사용자 지정 태그 색상, 프리미엄 테마, 레이아웃 가져오기/내보내기, 무제한 앱 메모, 사용자 지정 단축키를 잠금 해제하세요.",
"pro.card.summary.legacy": "TagLauncher을 조기에 지원해 주셔서 감사합니다. 귀하의 Pro 액세스는 이미 활성화되어 있습니다.",
- "pro.card.summary.unlocked": "Pro은(는) 이 Mac에서 활성화되어 있습니다. 프리미엄 테마 및 고급 레이아웃 도구가 준비되었습니다.",
+ "pro.card.summary.unlocked": "이 Mac에서 Pro가 활성화되었습니다. 사용자 지정 태그 색상, 고급 테마, 무제한 메모, 사용자 지정 단축키와 레이아웃 도구를 사용할 수 있습니다.",
"pro.card.title.free": "Pro로 업그레이드",
"pro.card.title.legacy": "Pro 잠금 해제됨",
"pro.card.title.unlocked": "Pro 잠금 해제됨",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "현재 저장 태그, 순서 및 레이아웃을 재사용 가능한 백업으로 저장하세요.",
"pro.feature.import": "레이아웃 가져오기",
"pro.feature.import.benefit": "이 Mac에 저장된 TagLauncher 레이아웃을 한 번에 복원하세요.",
- "pro.feature.notes": "무제한 메모",
- "pro.feature.notes.benefit": "무료 5노트 없이 모든 앱에 대한 메모를 저장하세요 제한.",
+ "pro.feature.notes": "사용자 지정 앱 메모",
+ "pro.feature.notes.benefit": "무료 버전은 앱 메모 3개를 제공합니다. Pro는 모든 앱의 무제한 메모를 잠금 해제합니다.",
"pro.feature.sorting": "저장된 앱 정렬",
"pro.feature.sorting.benefit": "편집 모드를 종료한 후에도 수동 앱 순서를 유지하세요.",
"pro.feature.themes": "프리미엄 테마",
"pro.feature.themes.benefit": "모든 고급 App Grid 테마를 잠금 해제하고 영구적으로 유지하세요.",
- "pro.notes.limitReached": "무료 버전에서는 최대 5개의 앱에 대한 메모를 저장할 수 있습니다. 메모를 무제한으로 저장하려면 Pro을(를) 잠금 해제하세요.",
+ "pro.notes.limitReached": "무료 버전은 앱 메모를 최대 3개까지 저장할 수 있습니다. Pro로 무제한 메모를 저장하세요.",
"pro.notes.remaining": "무료 버전에는 %limit%개의 앱 메모가 포함되어 있습니다. %remaining%개 남음.",
"pro.operation.cancelled": "구매가 취소되었습니다.",
"pro.operation.loading": "Pro 액세스 확인 중…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "구매를 복원하는 중...",
"pro.prompt.export": "레이아웃 내보내기는 Pro 기능입니다. 현재 태그, 주문 및 레이아웃을 백업하려면 Pro을(를) 잠금 해제하세요.",
"pro.prompt.import": "레이아웃 가져오기는 Pro 기능입니다. 이 Mac에 저장된 레이아웃을 복원하려면 Pro을(를) 잠금 해제하세요.",
- "pro.prompt.notes": "무제한 앱 노트는 Pro의 일부입니다. Pro을(를) 잠금 해제하여 모든 앱에 대한 메모를 저장하세요.",
+ "pro.prompt.notes": "무료 버전은 앱 메모를 최대 3개까지 저장할 수 있습니다. Pro를 잠금 해제하면 모든 앱에 메모를 저장할 수 있습니다.",
"pro.prompt.sorting": "저장된 수동 앱 정렬은 Pro의 일부입니다. 맞춤 순서를 유지하려면 Pro을(를) 잠금 해제하세요.",
"pro.prompt.themes": "이 테마는 Pro의 일부입니다. 고급 App Grid 테마를 계속 사용하려면 Pro을(를) 잠금 해제하세요.",
"pro.purchase.failed": "지금은 구매를 완료할 수 없습니다. 다시 시도해 주세요.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "사용자 지정 단축키",
"pro.feature.customHotkeys.benefit": "앱 목록과 Quick Search의 전역 단축키를 직접 설정합니다.",
"pro.prompt.customHotkeys": "사용자 지정 단축키는 Pro 기능입니다. Pro를 잠금 해제해 전역 단축키를 설정하세요.",
- "hotkeys.customize": "사용자 지정",
+ "hotkeys.customize": "단축키 변경",
"hotkeys.restoreDefault": "기본값 복원",
"hotkeys.recording": "새 단축키를 지금 누르세요. Esc로 취소합니다.",
"hotkeys.recordingInline": "기록 중",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "이 키는 지원되지 않습니다.",
"hotkeys.error.reserved": "이 단축키는 macOS 또는 앱에서 예약되어 있습니다.",
"hotkeys.error.duplicate": "이 단축키는 다른 TagLauncher 동작에 이미 사용 중입니다.",
- "hotkeys.error.registrationFailed": "단축키를 등록할 수 없습니다. 오류 코드: %status%."
+ "hotkeys.error.registrationFailed": "단축키를 등록할 수 없습니다. 오류 코드: %status%.",
+ "pro.feature.customTagColors": "사용자 지정 태그 색상",
+ "pro.feature.customTagColors.benefit": "SmartStart 시스템 카테고리 태그를 포함해 모든 태그에 원하는 색상을 설정합니다.",
+ "pro.prompt.customTagColors": "사용자 지정 태그 색상은 Pro 기능입니다. Pro를 잠금 해제하면 각 태그에 원하는 색을 지정해 카테고리를 더 쉽게 구분할 수 있습니다.",
+ "settings.proStatus.freeUser": "현재 무료 사용자입니다",
+ "settings.proStatus.proUser": "현재 특별 👑Pro 사용자입니다",
+ "settings.proStatus.lockedListTitle": "잠금 해제할 Pro 기능",
+ "settings.proStatus.unlockedListTitle": "잠금 해제된 기능",
+ "settings.proStatus.lockedFeature": "✅ 지원",
+ "settings.proStatus.unlockedFeature": "✅해제됨",
+ "settings.proStatus.freeNotes": "무료 3개",
+ "settings.proStatus.unlimitedNotes": "✅ 무제한 메모",
+ "settings.proStatus.limitedFeature": "제한됨",
+ "settings.proStatus.unsupportedFeature": "지원 안 함",
+ "settings.proFeature.appNotes": "사용자 지정 앱 메모",
+ "settings.proFeature.dataBackup": "데이터 가져오기/내보내기 및 레이아웃 백업",
+ "tag.customColor": "사용자 지정 색상",
+ "settings.proBenefit.hotkeys": "TagLauncher 동작에 나만의 단축키를 설정할 수 있습니다.",
+ "settings.proBenefit.tags": "각 태그에 사용자 지정 색상을 지정해 더 빠르게 구분합니다.",
+ "settings.proBenefit.data": "카테고리와 레이아웃을 백업, 내보내기, 가져오기, 복원할 수 있습니다.",
+ "settings.proBenefit.about": "이 Mac에서 모든 Pro 혜택이 잠금 해제되었습니다.",
+ "settings.proBenefit.general": "이 Mac에서 Pro 전용 컬러 컨테이너와 컬러 그리드를 사용할 수 있습니다.",
+ "settings.proGuide.hotkeys": "기본 단축키는 사용할 수 있습니다. Pro 사용자는 단축키를 사용자 지정할 수 있습니다.",
+ "settings.proGuide.tags": "기본 7가지 색상은 사용할 수 있습니다. Pro 사용자는 더 많은 색상을 사용자 지정할 수 있습니다.",
+ "settings.proGuide.data": "Pro 사용자는 카테고리와 레이아웃 데이터를 가져오고 내보낼 수 있습니다.",
+ "settings.proCompare.title": "무료 버전과 Pro 차이",
+ "settings.proCompare.free": "무료",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "사용 불가",
+ "settings.proStatus.previewFiveMinutes": "5분 미리보기만 가능",
+ "settings.proGuide.general": "컬러 컨테이너 / 컬러 그리드는 Pro 사용자만 사용할 수 있습니다"
}
diff --git a/src/Apptag/Localization/ms.json b/src/Apptag/Localization/ms.json
index d3c7122..2be68dd 100644
--- a/src/Apptag/Localization/ms.json
+++ b/src/Apptag/Localization/ms.json
@@ -8,8 +8,8 @@
"menu.language": "Bahasa",
"menu.help": "Bantuan",
"menu.version": "Versi",
- "menu.proStatus.free": "Anda kini pengguna Percuma (naik taraf ke Pro)",
- "menu.proStatus.unlocked": "Anda kini pengguna Pro istimewa",
+ "menu.proStatus.free": "Anda kini pengguna Percuma (naik taraf sekarang ke 👑Pro)",
+ "menu.proStatus.unlocked": "Anda kini pengguna 👑Pro istimewa",
"settings.language": "Bahasa",
"settings.languagePicker": "Bahasa aplikasi:",
"settings.languageDesc": "Pilih bahasa yang digunakan untuk menu dan tetapan.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Tiada hasil pengelasan pintar untuk digunakan.",
"scheme.local": "Skema setempat",
"scheme.systemSmartStart": "Skema awal pintar sistem",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
+ "settings.bubbleDisplayScope": "Tunjukkan petua gelembung untuk:",
+ "settings.bubbleAllApps": "Semua app",
+ "settings.bubbleUncommonOnly": "App jarang digunakan sahaja",
+ "quickSearch.title": "Carian pantas",
+ "quickSearch.placeholder": "Cari app, tag dan nota",
+ "quickSearch.inputAccessibility": "Input carian pantas",
+ "quickSearch.emptyPrompt": "Mula menaip untuk mencari app, tag dan nota.",
+ "quickSearch.noResults": "Tiada app ditemui.",
+ "quickSearch.launchFailed": "App ini tidak dapat dibuka. Cuba lagi atau pilih app lain.",
"quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "quickSearch.hotkeys": "Pintasan papan kekunci",
+ "quickSearch.mainHotkey": "Senarai app",
+ "quickSearch.mainHotkeyDesc": "Membuka senarai app TagLauncher.",
+ "quickSearch.status.Active": "Aktif",
+ "quickSearch.status.registrationFailed": "Pendaftaran gagal",
+ "quickSearch.status.unavailable": "Pintasan tidak tersedia",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% tidak dapat didaftarkan sekarang. Ia mungkin digunakan oleh macOS, kaedah input atau app lain. Pintasan senarai app tidak tersedia buat sementara. Semak pintasan papan kekunci atau konflik pintasan, kemudian mulakan semula TagLauncher. Kod ralat: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% tidak dapat didaftarkan sekarang. Ia mungkin digunakan oleh macOS, kaedah input atau app lain. Carian pantas global tidak tersedia buat sementara. Semak pintasan papan kekunci atau konflik pintasan, kemudian mulakan semula TagLauncher. Kod ralat: %status%.",
+ "quickSearch.loading": "Menyediakan indeks carian…",
+ "quickSearch.internalHotkey": "Carian pantas (dalam TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Berfungsi hanya semasa senarai app TagLauncher dibuka.",
+ "quickSearch.internalHotkeyStatus": "Senarai app sahaja",
+ "quickSearch.globalHotkey": "Carian pantas (global)",
+ "quickSearch.globalHotkeyDesc": "Buka carian pantas global apabila senarai app TagLauncher tidak kelihatan.",
+ "quickSearch.spaceDisplay": "Space (bar ruang)",
"trackpadGesture.title": "Gerak isyarat pad jejak",
"trackpadGesture.description": "Petakan gerak isyarat pad jejak dalam alat pihak ketiga kepada URL ini untuk memaparkan senarai app.",
"trackpadGesture.status": "Alat luaran",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Pratonton",
"pro.card.restore": "Pulihkan Pembelian",
- "pro.card.summary.free": "Buka kunci tema premium, import dan eksport reka letak, nota tanpa had dan pengisihan apl manual yang disimpan.",
+ "pro.card.summary.free": "Buka warna tag tersuai, tema premium, import dan eksport reka letak, nota app tanpa had dan pintasan tersuai.",
"pro.card.summary.legacy": "Terima kasih kerana menyokong TagLauncher lebih awal. Akses Pro anda sudah aktif.",
- "pro.card.summary.unlocked": "Pro aktif pada Mac ini. Tema premium dan alatan susun atur lanjutan sudah sedia.",
+ "pro.card.summary.unlocked": "Pro aktif pada Mac ini. Warna tag tersuai, tema lanjutan, nota tanpa had, pintasan tersuai dan alat reka letak sudah sedia.",
"pro.card.title.free": "Tingkatkan ke Pro",
"pro.card.title.legacy": "Pro dibuka kunci",
"pro.card.title.unlocked": "Pro dibuka kunci",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Simpan teg, pesanan dan reka letak semasa anda sebagai sandaran boleh guna semula.",
"pro.feature.import": "Import reka letak",
"pro.feature.import.benefit": "Pulihkan reka letak TagLauncher yang disimpan pada Mac ini dalam satu langkah.",
- "pro.feature.notes": "Nota tanpa had",
- "pro.feature.notes.benefit": "Simpan nota untuk setiap apl tanpa had 5 nota percuma.",
+ "pro.feature.notes": "Nota app tersuai",
+ "pro.feature.notes.benefit": "Versi percuma termasuk 3 nota app. Pro membuka nota tanpa had untuk semua app.",
"pro.feature.sorting": "Pengisihan apl yang disimpan",
"pro.feature.sorting.benefit": "Simpan pesanan apl manual anda selepas anda meninggalkan mod pengeditan.",
"pro.feature.themes": "Tema premium",
"pro.feature.themes.benefit": "Buka kunci semua tema Grid Apl lanjutan dan simpannya secara kekal.",
- "pro.notes.limitReached": "Versi percuma boleh menyimpan nota untuk sehingga 5 apl. Buka kunci Pro untuk menyimpan nota tanpa had.",
+ "pro.notes.limitReached": "Versi percuma boleh menyimpan sehingga 3 nota app. Buka Pro untuk nota tanpa had.",
"pro.notes.remaining": "Versi percuma termasuk %limit% nota aplikasi. %remaining% lagi.",
"pro.operation.cancelled": "Pembelian dibatalkan.",
"pro.operation.loading": "Menyemak akses Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Memulihkan pembelian…",
"pro.prompt.export": "Eksport reka letak ialah ciri Pro. Buka kunci Pro untuk menyandarkan teg, pesanan dan reka letak semasa anda.",
"pro.prompt.import": "Import reka letak ialah ciri Pro. Buka kunci Pro untuk memulihkan reka letak yang disimpan pada Mac ini.",
- "pro.prompt.notes": "Nota apl tanpa had adalah sebahagian daripada Pro. Buka kunci Pro untuk menyimpan nota bagi setiap apl.",
+ "pro.prompt.notes": "Versi percuma boleh menyimpan sehingga 3 nota app. Buka Pro untuk menyimpan nota bagi semua app.",
"pro.prompt.sorting": "Pengisihan apl manual yang disimpan adalah sebahagian daripada Pro. Buka kunci Pro untuk mengekalkan pesanan tersuai anda.",
"pro.prompt.themes": "Tema ini adalah sebahagian daripada Pro. Buka kunci Pro untuk terus menggunakan tema Grid Apl lanjutan.",
"pro.purchase.failed": "Tidak dapat menyelesaikan pembelian sekarang. Sila cuba lagi.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Pintasan tersuai",
"pro.feature.customHotkeys.benefit": "Tetapkan pintasan global untuk senarai app dan Quick Search.",
"pro.prompt.customHotkeys": "Pintasan tersuai ialah ciri Pro. Buka Pro untuk menetapkan pintasan global.",
- "hotkeys.customize": "Sesuaikan",
+ "hotkeys.customize": "Tukar pintasan",
"hotkeys.restoreDefault": "Pulihkan lalai",
"hotkeys.recording": "Tekan pintasan baharu sekarang. Tekan Esc untuk batal.",
"hotkeys.recordingInline": "Merakam",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Kekunci ini tidak disokong.",
"hotkeys.error.reserved": "Pintasan ini dikhaskan oleh macOS atau app.",
"hotkeys.error.duplicate": "Pintasan ini sudah digunakan oleh tindakan TagLauncher lain.",
- "hotkeys.error.registrationFailed": "Pintasan tidak dapat didaftarkan. Kod ralat: %status%."
+ "hotkeys.error.registrationFailed": "Pintasan tidak dapat didaftarkan. Kod ralat: %status%.",
+ "pro.feature.customTagColors": "Warna tag tersuai",
+ "pro.feature.customTagColors.benefit": "Tetapkan sebarang warna untuk setiap tag, termasuk tag kategori sistem SmartStart.",
+ "pro.prompt.customTagColors": "Warna tag tersuai ialah ciri Pro. Buka Pro untuk memberi setiap tag sebarang warna dan mengenal pasti kategori dengan lebih mudah.",
+ "settings.proStatus.freeUser": "Anda kini pengguna Percuma",
+ "settings.proStatus.proUser": "Anda kini pengguna 👑Pro istimewa",
+ "settings.proStatus.lockedListTitle": "Ciri Pro untuk dibuka",
+ "settings.proStatus.unlockedListTitle": "Ciri dibuka",
+ "settings.proStatus.lockedFeature": "✅ Disokong",
+ "settings.proStatus.unlockedFeature": "✅Dibuka",
+ "settings.proStatus.freeNotes": "3 percuma",
+ "settings.proStatus.unlimitedNotes": "✅ Nota tanpa had",
+ "settings.proStatus.limitedFeature": "Terhad",
+ "settings.proStatus.unsupportedFeature": "Tidak disokong",
+ "settings.proFeature.appNotes": "Nota app tersuai",
+ "settings.proFeature.dataBackup": "Import/eksport data dan sandaran reka letak",
+ "tag.customColor": "Warna tersuai",
+ "settings.proBenefit.hotkeys": "Tetapkan pintasan sendiri untuk tindakan TagLauncher.",
+ "settings.proBenefit.tags": "Beri setiap tag warna tersuai supaya lebih cepat dikenali.",
+ "settings.proBenefit.data": "Sandar, eksport, import dan pulihkan kategori serta reka letak.",
+ "settings.proBenefit.about": "Semua manfaat Pro dibuka pada Mac ini.",
+ "settings.proBenefit.general": "Bekas berwarna dan grid berwarna Pro tersedia pada Mac ini.",
+ "settings.proGuide.hotkeys": "Pintasan lalai tersedia. Pengguna Pro boleh menyesuaikan pintasan.",
+ "settings.proGuide.tags": "7 warna lalai tersedia. Pengguna Pro boleh menyesuaikan lebih banyak warna.",
+ "settings.proGuide.data": "Pengguna Pro boleh mengimport dan mengeksport data kategori dan reka letak.",
+ "settings.proCompare.title": "Perbezaan Percuma dan Pro",
+ "settings.proCompare.free": "Percuma",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Tidak tersedia",
+ "settings.proStatus.previewFiveMinutes": "Pratonton 5 minit sahaja",
+ "settings.proGuide.general": "Hanya pengguna Pro boleh menggunakan bekas / grid berwarna"
}
diff --git a/src/Apptag/Localization/nb.json b/src/Apptag/Localization/nb.json
index adb9fe9..a64ffe7 100644
--- a/src/Apptag/Localization/nb.json
+++ b/src/Apptag/Localization/nb.json
@@ -8,8 +8,8 @@
"menu.language": "Språk",
"menu.help": "Hjelp",
"menu.version": "Versjon",
- "menu.proStatus.free": "Du er nå gratisbruker (oppgrader til Pro)",
- "menu.proStatus.unlocked": "Du er nå en verdsatt Pro-bruker",
+ "menu.proStatus.free": "Du er nå gratisbruker (oppgrader nå til 👑Pro)",
+ "menu.proStatus.unlocked": "Du er nå en verdsatt 👑Pro-bruker",
"settings.language": "Språk",
"settings.languagePicker": "Appspråk:",
"settings.languageDesc": "Velg språket som brukes i menyer og innstillinger.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Ingen smarte klassifiseringsresultater kan brukes.",
"scheme.local": "Lokalt skjema",
"scheme.systemSmartStart": "Systemets smarte startskjema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Vis bobletips for:",
+ "settings.bubbleAllApps": "Alle apper",
+ "settings.bubbleUncommonOnly": "Bare sjelden brukte apper",
+ "quickSearch.title": "Hurtigsøk",
+ "quickSearch.placeholder": "Søk etter apper, tagger og notater",
+ "quickSearch.inputAccessibility": "Inndata for hurtigsøk",
+ "quickSearch.emptyPrompt": "Begynn å skrive for å søke etter apper, tagger og notater.",
+ "quickSearch.noResults": "Fant ingen apper.",
+ "quickSearch.launchFailed": "Kunne ikke åpne denne appen. Prøv igjen eller velg en annen app.",
+ "quickSearch.tagPrefix": "Tagg",
+ "quickSearch.hotkeys": "Tastatursnarveier",
+ "quickSearch.mainHotkey": "Appliste",
+ "quickSearch.mainHotkeyDesc": "Åpner TagLauncher-applisten.",
+ "quickSearch.status.Active": "Aktiv",
+ "quickSearch.status.registrationFailed": "Registrering mislyktes",
+ "quickSearch.status.unavailable": "Snarvei utilgjengelig",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% kan ikke registreres akkurat nå. Den kan være brukt av macOS, en inndatametode eller en annen app. Snarveien for applisten er midlertidig utilgjengelig. Sjekk tastatursnarveier eller snarveikonflikter, og start TagLauncher på nytt. Feilkode: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% kan ikke registreres akkurat nå. Den kan være brukt av macOS, en inndatametode eller en annen app. Globalt hurtigsøk er midlertidig utilgjengelig. Sjekk tastatursnarveier eller snarveikonflikter, og start TagLauncher på nytt. Feilkode: %status%.",
+ "quickSearch.loading": "Forbereder søkeindeks…",
+ "quickSearch.internalHotkey": "Hurtigsøk (i TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Fungerer bare mens TagLauncher-applisten er åpen.",
+ "quickSearch.internalHotkeyStatus": "Bare appliste",
+ "quickSearch.globalHotkey": "Hurtigsøk (globalt)",
+ "quickSearch.globalHotkeyDesc": "Åpne hurtigsøk globalt når TagLauncher-applisten ikke er synlig.",
+ "quickSearch.spaceDisplay": "Space (mellomrom)",
"trackpadGesture.title": "Styreflatebevegelse",
"trackpadGesture.description": "Koble en styreflatebevegelse i et tredjepartsverktøy til denne URL-en for å vise applisten.",
"trackpadGesture.status": "Eksternt verktøy",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Forhåndsvisning",
"pro.card.restore": "Gjenopprett kjøp",
- "pro.card.summary.free": "Lås opp premium-temaer, import og eksport av layout, ubegrensede notater og lagret manuell appsortering.",
+ "pro.card.summary.free": "Lås op for egne tagfarver, premium-temaer, import og eksport af layout, ubegrænsede appnoter og egne genveje.",
"pro.card.summary.legacy": "Takk for at du støttet TagLauncher tidlig. Din Pro-tilgang er allerede aktiv.",
- "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Premium-temaer og avanserte layoutverktøy er klare.",
+ "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Egne tagfarver, avancerede temaer, ubegrænsede noter, egne genveje og layoutværktøjer er klar.",
"pro.card.title.free": "Oppgrader til Pro",
"pro.card.title.legacy": "Pro låst opp",
"pro.card.title.unlocked": "Pro låst opp",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Lagre gjeldende tagger, bestilling og layout som en gjenbrukbar sikkerhetskopi.",
"pro.feature.import": "Import av layout",
"pro.feature.import.benefit": "Gjenopprett et lagret TagLauncher-oppsett på denne Mac i ett trinn.",
- "pro.feature.notes": "Ubegrensede notater",
- "pro.feature.notes.benefit": "Lagre notater for hver app uten den gratis grensen på 5 noter.",
+ "pro.feature.notes": "Egne appnoter",
+ "pro.feature.notes.benefit": "Gratisversionen indeholder 3 appnoter. Pro låser op for ubegrænsede noter til alle apps.",
"pro.feature.sorting": "Lagret appsortering",
"pro.feature.sorting.benefit": "Behold den manuelle appbestillingen din etter at du forlater redigeringsmodus.",
"pro.feature.themes": "Premium-temaer",
"pro.feature.themes.benefit": "Lås opp hvert avansert App Grid-tema og behold det permanent.",
- "pro.notes.limitReached": "Gratisversjonen kan lagre notater for opptil 5 apper. Lås opp Pro for å lagre ubegrensede notater.",
+ "pro.notes.limitReached": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for ubegrænsede noter.",
"pro.notes.remaining": "Gratisversjonen inkluderer %limit% appnotater. %remaining% gjenstår.",
"pro.operation.cancelled": "Kjøp kansellert.",
"pro.operation.loading": "Sjekker Pro-tilgang …",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Gjenoppretter kjøpet …",
"pro.prompt.export": "Layouteksport er en Pro-funksjon. Lås opp Pro for å sikkerhetskopiere gjeldende tagger, rekkefølge og layout.",
"pro.prompt.import": "Layoutimport er en Pro-funksjon. Lås opp Pro for å gjenopprette et lagret oppsett på denne Mac.",
- "pro.prompt.notes": "Ubegrensede appnotater er en del av Pro. Lås opp Pro for å lagre notater for hver app.",
+ "pro.prompt.notes": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for at gemme noter til alle apps.",
"pro.prompt.sorting": "Lagret manuell appsortering er en del av Pro. Lås opp Pro for å beholde din egendefinerte rekkefølge.",
"pro.prompt.themes": "Dette temaet er en del av Pro. Lås opp Pro for å fortsette å bruke avanserte App Grid-temaer.",
"pro.purchase.failed": "Kan ikke fullføre kjøpet akkurat nå. Vennligst prøv igjen.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Egne snarveier",
"pro.feature.customHotkeys.benefit": "Angi globale snarveier for applisten og Quick Search.",
"pro.prompt.customHotkeys": "Egne snarveier er en Pro-funksjon. Lås opp Pro for å angi dem.",
- "hotkeys.customize": "Tilpass",
+ "hotkeys.customize": "Endre snarvei",
"hotkeys.restoreDefault": "Gjenopprett standard",
"hotkeys.recording": "Trykk den nye snarveien nå. Esc avbryter.",
"hotkeys.recordingInline": "Tar opp",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Denne tasten støttes ikke.",
"hotkeys.error.reserved": "Denne snarveien er reservert av macOS eller appen.",
"hotkeys.error.duplicate": "Denne snarveien tilhører allerede en annen TagLauncher-handling.",
- "hotkeys.error.registrationFailed": "Snarveien kunne ikke registreres. Feilkode: %status%."
+ "hotkeys.error.registrationFailed": "Snarveien kunne ikke registreres. Feilkode: %status%.",
+ "pro.feature.customTagColors": "Egne tagfarver",
+ "pro.feature.customTagColors.benefit": "Vælg en hvilken som helst farve til hvert tag, også SmartStart-systemkategorier.",
+ "pro.prompt.customTagColors": "Egne tagfarver er en Pro-funktion. Lås Pro op for at give hvert tag en valgfri farve og gøre kategorier lettere at kende.",
+ "settings.proStatus.freeUser": "Du er nå gratisbruker",
+ "settings.proStatus.proUser": "Du er nå en verdsatt 👑Pro-bruker",
+ "settings.proStatus.lockedListTitle": "Pro-funksjoner å låse opp",
+ "settings.proStatus.unlockedListTitle": "Opplåste funksjoner",
+ "settings.proStatus.lockedFeature": "✅ Støttet",
+ "settings.proStatus.unlockedFeature": "✅Opplåst",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Ubegrensede notater",
+ "settings.proStatus.limitedFeature": "Begrenset",
+ "settings.proStatus.unsupportedFeature": "Støttes ikke",
+ "settings.proFeature.appNotes": "Egne appnoter",
+ "settings.proFeature.dataBackup": "Dataimport/-eksport og layoutbackups",
+ "tag.customColor": "Egen farge",
+ "settings.proBenefit.hotkeys": "Still inn dine egne snarveier for TagLauncher-handlinger.",
+ "settings.proBenefit.tags": "Gi hver tagg en egen farge så du kjenner den igjen raskere.",
+ "settings.proBenefit.data": "Sikkerhetskopier, eksporter, importer og gjenopprett kategorier og layout.",
+ "settings.proBenefit.about": "Alle Pro-fordeler er låst opp på denne Macen.",
+ "settings.proBenefit.general": "Pro-fargebeholder og fargerutenett er tilgjengelig på denne Macen.",
+ "settings.proGuide.hotkeys": "Standardsnarveier er tilgjengelige. Pro-brukere kan tilpasse snarveier.",
+ "settings.proGuide.tags": "7 standardfarger er tilgjengelige. Pro-brukere kan tilpasse flere farger.",
+ "settings.proGuide.data": "Pro-brukere kan importere og eksportere kategori- og oppsettsdata.",
+ "settings.proCompare.title": "Forskjeller mellom gratis og Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Ikke tilgjengelig",
+ "settings.proStatus.previewFiveMinutes": "Kun 5 minutters forhåndsvisning",
+ "settings.proGuide.general": "Bare Pro-brukere kan bruke fargede beholdere / fargede rutenett"
}
diff --git a/src/Apptag/Localization/nl.json b/src/Apptag/Localization/nl.json
index a5dac2e..a710105 100644
--- a/src/Apptag/Localization/nl.json
+++ b/src/Apptag/Localization/nl.json
@@ -8,8 +8,8 @@
"menu.language": "Taal",
"menu.help": "Help",
"menu.version": "Versie",
- "menu.proStatus.free": "U bent momenteel een gratis gebruiker (upgrade naar Pro)",
- "menu.proStatus.unlocked": "U bent momenteel een gewaardeerde Pro-gebruiker",
+ "menu.proStatus.free": "Je bent momenteel een gratis gebruiker (upgrade nu naar 👑Pro)",
+ "menu.proStatus.unlocked": "Je bent momenteel een gewaardeerde 👑Pro-gebruiker",
"settings.language": "Taal",
"settings.languagePicker": "App-taal:",
"settings.languageDesc": "Kies de taal voor menu’s en instellingen.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Geen slimme classificatieresultaten beschikbaar om toe te passen.",
"scheme.local": "Lokaal schema",
"scheme.systemSmartStart": "Slim beginschema van systeem",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
+ "settings.bubbleDisplayScope": "Ballontips tonen voor:",
+ "settings.bubbleAllApps": "Alle apps",
+ "settings.bubbleUncommonOnly": "Alleen weinig gebruikte apps",
+ "quickSearch.title": "Snel zoeken",
+ "quickSearch.placeholder": "Zoek apps, tags en notities",
+ "quickSearch.inputAccessibility": "Invoer voor snel zoeken",
+ "quickSearch.emptyPrompt": "Begin met typen om apps, tags en notities te zoeken.",
+ "quickSearch.noResults": "Geen apps gevonden.",
+ "quickSearch.launchFailed": "Deze app kan niet worden geopend. Probeer opnieuw of kies een andere app.",
"quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "quickSearch.hotkeys": "Toetscombinaties",
+ "quickSearch.mainHotkey": "Applijst",
+ "quickSearch.mainHotkeyDesc": "Opent de TagLauncher-applijst.",
+ "quickSearch.status.Active": "Actief",
+ "quickSearch.status.registrationFailed": "Registratie mislukt",
+ "quickSearch.status.unavailable": "Toetscombinatie niet beschikbaar",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% kan nu niet worden geregistreerd. Deze wordt mogelijk gebruikt door macOS, een invoermethode of een andere app. De toetscombinatie voor de applijst is tijdelijk niet beschikbaar. Controleer toetscombinaties of conflicten en start TagLauncher opnieuw. Foutcode: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% kan nu niet worden geregistreerd. Deze wordt mogelijk gebruikt door macOS, een invoermethode of een andere app. Globaal snel zoeken is tijdelijk niet beschikbaar. Controleer toetscombinaties of conflicten en start TagLauncher opnieuw. Foutcode: %status%.",
+ "quickSearch.loading": "Zoekindex voorbereiden…",
+ "quickSearch.internalHotkey": "Snel zoeken (binnen TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Werkt alleen zolang de TagLauncher-applijst geopend is.",
+ "quickSearch.internalHotkeyStatus": "Alleen applijst",
+ "quickSearch.globalHotkey": "Snel zoeken (globaal)",
+ "quickSearch.globalHotkeyDesc": "Open snel zoeken globaal wanneer de TagLauncher-applijst niet zichtbaar is.",
+ "quickSearch.spaceDisplay": "Space (spatiebalk)",
"trackpadGesture.title": "Trackpadgebaar",
"trackpadGesture.description": "Koppel in een tool van derden een trackpadgebaar aan deze URL om de applijst te tonen.",
"trackpadGesture.status": "Externe tool",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Voorbeeld",
"pro.card.restore": "Aankopen herstellen",
- "pro.card.summary.free": "Ontgrendel premiumthema's, import en export van lay-outs, onbeperkte notities en opgeslagen handmatige app-sortering.",
+ "pro.card.summary.free": "Ontgrendel eigen tagkleuren, premiumthema’s, import en export van indelingen, onbeperkte appnotities en eigen sneltoetsen.",
"pro.card.summary.legacy": "Bedankt voor het vroegtijdig steunen van TagLauncher. Uw Pro-toegang is al actief.",
- "pro.card.summary.unlocked": "Pro is actief op deze Mac. Premiumthema's en geavanceerde lay-outtools zijn klaar.",
+ "pro.card.summary.unlocked": "Pro is actief op deze Mac. Eigen tagkleuren, geavanceerde thema’s, onbeperkte notities, eigen sneltoetsen en indelingstools zijn klaar.",
"pro.card.title.free": "Upgrade naar Pro",
"pro.card.title.legacy": "Pro ontgrendeld",
"pro.card.title.unlocked": "Pro ontgrendeld",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Bewaar uw huidige tags, bestelling en lay-out als herbruikbare back-up.",
"pro.feature.import": "Lay-out importeren",
"pro.feature.import.benefit": "Herstel een opgeslagen TagLauncher-indeling op deze Mac in één stap.",
- "pro.feature.notes": "Onbeperkt notities",
- "pro.feature.notes.benefit": "Bewaar notities voor elke app zonder de gratis limiet van vijf notities.",
+ "pro.feature.notes": "Eigen appnotities",
+ "pro.feature.notes.benefit": "De gratis versie bevat 3 appnotities. Pro ontgrendelt onbeperkte notities voor alle apps.",
"pro.feature.sorting": "Opgeslagen app-sortering",
"pro.feature.sorting.benefit": "Bewaar uw handmatige app-volgorde nadat u de bewerkingsmodus heeft verlaten.",
"pro.feature.themes": "Premium-thema's",
"pro.feature.themes.benefit": "Ontgrendel elk geavanceerd App Grid-thema en bewaar het permanent.",
- "pro.notes.limitReached": "De gratis versie kan notities opslaan voor maximaal 5 apps. Ontgrendel Pro om onbeperkt notities op te slaan.",
+ "pro.notes.limitReached": "De gratis versie kan tot 3 appnotities opslaan. Ontgrendel Pro voor onbeperkte notities.",
"pro.notes.remaining": "De gratis versie bevat %limit% app-notities. %remaining% resterend.",
"pro.operation.cancelled": "Aankoop geannuleerd.",
"pro.operation.loading": "Toegang tot Pro controleren…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Aankoop herstellen…",
"pro.prompt.export": "Lay-outexport is een Pro-functie. Ontgrendel Pro om een back-up te maken van uw huidige tags, volgorde en lay-out.",
"pro.prompt.import": "Het importeren van lay-outs is een functie van Pro. Ontgrendel Pro om een opgeslagen lay-out op deze Mac te herstellen.",
- "pro.prompt.notes": "Onbeperkte app-notities zijn onderdeel van Pro. Ontgrendel Pro om notities voor elke app op te slaan.",
+ "pro.prompt.notes": "De gratis versie kan tot 3 appnotities opslaan. Ontgrendel Pro om notities voor alle apps op te slaan.",
"pro.prompt.sorting": "Opgeslagen handmatige app-sortering is onderdeel van Pro. Ontgrendel Pro om uw aangepaste volgorde te behouden.",
"pro.prompt.themes": "Dit thema is onderdeel van Pro. Ontgrendel Pro om geavanceerde App Grid-thema's te blijven gebruiken.",
"pro.purchase.failed": "Kan de aankoop momenteel niet voltooien. Probeer het opnieuw.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Aangepaste sneltoetsen",
"pro.feature.customHotkeys.benefit": "Stel eigen globale sneltoetsen in voor de applijst en Quick Search.",
"pro.prompt.customHotkeys": "Aangepaste sneltoetsen horen bij Pro. Ontgrendel Pro om ze in te stellen.",
- "hotkeys.customize": "Aanpassen",
+ "hotkeys.customize": "Sneltoets wijzigen",
"hotkeys.restoreDefault": "Standaard herstellen",
"hotkeys.recording": "Druk nu op de nieuwe sneltoets. Druk op Esc om te annuleren.",
"hotkeys.recordingInline": "Opnemen",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Deze toets wordt niet ondersteund.",
"hotkeys.error.reserved": "Deze sneltoets is gereserveerd door macOS of de app.",
"hotkeys.error.duplicate": "Deze sneltoets hoort al bij een andere TagLauncher-actie.",
- "hotkeys.error.registrationFailed": "Sneltoets kon niet worden geregistreerd. Foutcode: %status%."
+ "hotkeys.error.registrationFailed": "Sneltoets kon niet worden geregistreerd. Foutcode: %status%.",
+ "pro.feature.customTagColors": "Eigen tagkleuren",
+ "pro.feature.customTagColors.benefit": "Stel elke kleur in voor elk tag, inclusief SmartStart-systeemcategorieën.",
+ "pro.prompt.customTagColors": "Eigen tagkleuren zijn een Pro-functie. Ontgrendel Pro om elk tag een kleur te geven en categorieën makkelijker te herkennen.",
+ "settings.proStatus.freeUser": "Je bent momenteel een gratis gebruiker",
+ "settings.proStatus.proUser": "Je bent momenteel een gewaardeerde 👑Pro-gebruiker",
+ "settings.proStatus.lockedListTitle": "Pro-functies om te ontgrendelen",
+ "settings.proStatus.unlockedListTitle": "Ontgrendelde functies",
+ "settings.proStatus.lockedFeature": "✅ Ondersteund",
+ "settings.proStatus.unlockedFeature": "✅Ontgrendeld",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Onbeperkte notities",
+ "settings.proStatus.limitedFeature": "Beperkt",
+ "settings.proStatus.unsupportedFeature": "Niet ondersteund",
+ "settings.proFeature.appNotes": "Eigen appnotities",
+ "settings.proFeature.dataBackup": "Data import/export en indelingsback-ups",
+ "tag.customColor": "Eigen kleur",
+ "settings.proBenefit.hotkeys": "Stel je eigen sneltoetsen in voor TagLauncher-acties.",
+ "settings.proBenefit.tags": "Geef elk tag een eigen kleur zodat je het sneller herkent.",
+ "settings.proBenefit.data": "Maak back-ups, exporteer, importeer en herstel categorieën en indelingen.",
+ "settings.proBenefit.about": "Alle Pro-voordelen zijn op deze Mac ontgrendeld.",
+ "settings.proBenefit.general": "De Pro-kleurencontainer en het kleurenraster zijn beschikbaar op deze Mac.",
+ "settings.proGuide.hotkeys": "Standaardsneltoetsen zijn beschikbaar. Pro-gebruikers kunnen sneltoetsen aanpassen.",
+ "settings.proGuide.tags": "7 standaardkleuren zijn beschikbaar. Pro-gebruikers kunnen meer kleuren aanpassen.",
+ "settings.proGuide.data": "Pro-gebruikers kunnen categorie- en indelingsgegevens importeren en exporteren.",
+ "settings.proCompare.title": "Verschillen tussen gratis en Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Niet beschikbaar",
+ "settings.proStatus.previewFiveMinutes": "Alleen 5 minuten voorbeeld",
+ "settings.proGuide.general": "Alleen Pro-gebruikers kunnen gekleurde containers / rasters gebruiken"
}
diff --git a/src/Apptag/Localization/nn.json b/src/Apptag/Localization/nn.json
index 0bb7c83..e633cd9 100644
--- a/src/Apptag/Localization/nn.json
+++ b/src/Apptag/Localization/nn.json
@@ -8,8 +8,8 @@
"menu.language": "Språk",
"menu.help": "Hjelp",
"menu.version": "Versjon",
- "menu.proStatus.free": "Du er no gratisbrukar (oppgrader til Pro)",
- "menu.proStatus.unlocked": "Du er no ein verdsett Pro-brukar",
+ "menu.proStatus.free": "Du er no gratisbrukar (oppgrader no til 👑Pro)",
+ "menu.proStatus.unlocked": "Du er no ein verdsett 👑Pro-brukar",
"settings.language": "Språk",
"settings.languagePicker": "Appspråk:",
"settings.languageDesc": "Velg språket som brukes i menyer og innstillinger.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Ingen smarte klassifiseringsresultater kan brukes.",
"scheme.local": "Lokalt skjema",
"scheme.systemSmartStart": "Systemets smarte startskjema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Vis bobletips for:",
+ "settings.bubbleAllApps": "Alle apper",
+ "settings.bubbleUncommonOnly": "Bare sjelden brukte apper",
+ "quickSearch.title": "Hurtigsøk",
+ "quickSearch.placeholder": "Søk etter apper, tagger og notater",
+ "quickSearch.inputAccessibility": "Inndata for hurtigsøk",
+ "quickSearch.emptyPrompt": "Begynn å skrive for å søke etter apper, tagger og notater.",
+ "quickSearch.noResults": "Fant ingen apper.",
+ "quickSearch.launchFailed": "Kunne ikke åpne denne appen. Prøv igjen eller velg en annen app.",
+ "quickSearch.tagPrefix": "Tagg",
+ "quickSearch.hotkeys": "Tastatursnarvegar",
+ "quickSearch.mainHotkey": "Appliste",
+ "quickSearch.mainHotkeyDesc": "Opnar TagLauncher-applista.",
+ "quickSearch.status.Active": "Aktiv",
+ "quickSearch.status.registrationFailed": "Registrering mislyktes",
+ "quickSearch.status.unavailable": "Snarveg utilgjengeleg",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% kan ikke registreres akkurat nå. Den kan være brukt av macOS, en inndatametode eller en annen app. Snarveien for applisten er midlertidig utilgjengelig. Sjekk tastatursnarveier eller snarveikonflikter, og start TagLauncher på nytt. Feilkode: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% kan ikke registreres akkurat nå. Den kan være brukt av macOS, en inndatametode eller en annen app. Globalt hurtigsøk er midlertidig utilgjengelig. Sjekk tastatursnarveier eller snarveikonflikter, og start TagLauncher på nytt. Feilkode: %status%.",
+ "quickSearch.loading": "Førebur søkjeindeks…",
+ "quickSearch.internalHotkey": "Hurtigsøk (i TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Fungerer berre medan TagLauncher-applista er open.",
+ "quickSearch.internalHotkeyStatus": "Berre appliste",
+ "quickSearch.globalHotkey": "Hurtigsøk (globalt)",
+ "quickSearch.globalHotkeyDesc": "Opna hurtigsøk globalt når TagLauncher-applista ikkje er synleg.",
+ "quickSearch.spaceDisplay": "Space (mellomrom)",
"trackpadGesture.title": "Styreflategest",
"trackpadGesture.description": "Kopla ein styreflategest i eit tredjepartsverktøy til denne URL-en for å visa applista.",
"trackpadGesture.status": "Eksternt verktøy",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Forhåndsvisning",
"pro.card.restore": "Gjenopprett kjøp",
- "pro.card.summary.free": "Lås opp premium-temaer, import og eksport av layout, ubegrensede notater og lagret manuell appsortering.",
+ "pro.card.summary.free": "Lås op for egne tagfarver, premium-temaer, import og eksport af layout, ubegrænsede appnoter og egne genveje.",
"pro.card.summary.legacy": "Takk for at du støttet TagLauncher tidlig. Din Pro-tilgang er allerede aktiv.",
- "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Premium-temaer og avanserte layoutverktøy er klare.",
+ "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Egne tagfarver, avancerede temaer, ubegrænsede noter, egne genveje og layoutværktøjer er klar.",
"pro.card.title.free": "Oppgrader til Pro",
"pro.card.title.legacy": "Pro låst opp",
"pro.card.title.unlocked": "Pro låst opp",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Lagre gjeldende tagger, bestilling og layout som en gjenbrukbar sikkerhetskopi.",
"pro.feature.import": "Import av layout",
"pro.feature.import.benefit": "Gjenopprett et lagret TagLauncher-oppsett på denne Mac i ett trinn.",
- "pro.feature.notes": "Ubegrensede notater",
- "pro.feature.notes.benefit": "Lagre notater for hver app uten den gratis grensen på 5 noter.",
+ "pro.feature.notes": "Egne appnoter",
+ "pro.feature.notes.benefit": "Gratisversionen indeholder 3 appnoter. Pro låser op for ubegrænsede noter til alle apps.",
"pro.feature.sorting": "Lagret appsortering",
"pro.feature.sorting.benefit": "Behold den manuelle appbestillingen din etter at du forlater redigeringsmodus.",
"pro.feature.themes": "Premium-temaer",
"pro.feature.themes.benefit": "Lås opp hvert avansert App Grid-tema og behold det permanent.",
- "pro.notes.limitReached": "Gratisversjonen kan lagre notater for opptil 5 apper. Lås opp Pro for å lagre ubegrensede notater.",
+ "pro.notes.limitReached": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for ubegrænsede noter.",
"pro.notes.remaining": "Gratisversjonen inkluderer %limit% appnotater. %remaining% gjenstår.",
"pro.operation.cancelled": "Kjøp kansellert.",
"pro.operation.loading": "Sjekker Pro-tilgang …",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Gjenoppretter kjøpet …",
"pro.prompt.export": "Layouteksport er en Pro-funksjon. Lås opp Pro for å sikkerhetskopiere gjeldende tagger, rekkefølge og layout.",
"pro.prompt.import": "Layoutimport er en Pro-funksjon. Lås opp Pro for å gjenopprette et lagret oppsett på denne Mac.",
- "pro.prompt.notes": "Ubegrensede appnotater er en del av Pro. Lås opp Pro for å lagre notater for hver app.",
+ "pro.prompt.notes": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for at gemme noter til alle apps.",
"pro.prompt.sorting": "Lagret manuell appsortering er en del av Pro. Lås opp Pro for å beholde din egendefinerte rekkefølge.",
"pro.prompt.themes": "Dette temaet er en del av Pro. Lås opp Pro for å fortsette å bruke avanserte App Grid-temaer.",
"pro.purchase.failed": "Kan ikke fullføre kjøpet akkurat nå. Vennligst prøv igjen.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Eigne snarvegar",
"pro.feature.customHotkeys.benefit": "Set globale snarvegar for applista og Quick Search.",
"pro.prompt.customHotkeys": "Eigne snarvegar er ein Pro-funksjon. Lås opp Pro for å setje dei.",
- "hotkeys.customize": "Tilpass",
+ "hotkeys.customize": "Endra snarveg",
"hotkeys.restoreDefault": "Gjenopprett standard",
"hotkeys.recording": "Trykk den nye snarveien nå. Esc avbryter.",
"hotkeys.recordingInline": "Tar opp",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Denne tasten støttes ikke.",
"hotkeys.error.reserved": "Denne snarveien er reservert av macOS eller appen.",
"hotkeys.error.duplicate": "Denne snarveien tilhører allerede en annen TagLauncher-handling.",
- "hotkeys.error.registrationFailed": "Snarveien kunne ikke registreres. Feilkode: %status%."
+ "hotkeys.error.registrationFailed": "Snarveien kunne ikke registreres. Feilkode: %status%.",
+ "pro.feature.customTagColors": "Egne tagfarver",
+ "pro.feature.customTagColors.benefit": "Vælg en hvilken som helst farve til hvert tag, også SmartStart-systemkategorier.",
+ "pro.prompt.customTagColors": "Egne tagfarver er en Pro-funktion. Lås Pro op for at give hvert tag en valgfri farve og gøre kategorier lettere at kende.",
+ "settings.proStatus.freeUser": "Du er no gratisbrukar",
+ "settings.proStatus.proUser": "Du er no ein verdsett 👑Pro-brukar",
+ "settings.proStatus.lockedListTitle": "Pro-funksjonar å låse opp",
+ "settings.proStatus.unlockedListTitle": "Opplåste funksjonar",
+ "settings.proStatus.lockedFeature": "✅ Støtta",
+ "settings.proStatus.unlockedFeature": "✅Opplåst",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Uavgrensa notat",
+ "settings.proStatus.limitedFeature": "Begrenset",
+ "settings.proStatus.unsupportedFeature": "Ikkje støtta",
+ "settings.proFeature.appNotes": "Egne appnoter",
+ "settings.proFeature.dataBackup": "Dataimport/-eksport og layoutbackups",
+ "tag.customColor": "Egen farge",
+ "settings.proBenefit.hotkeys": "Still inn eigne snarvegar for TagLauncher-handlingar.",
+ "settings.proBenefit.tags": "Gje kvar tagg ein eigen farge så du kjenner han att raskare.",
+ "settings.proBenefit.data": "Ta backup, eksporter, importer og gjenopprett kategoriar og layout.",
+ "settings.proBenefit.about": "Alle Pro-fordelar er låste opp på denne Mac-en.",
+ "settings.proBenefit.general": "Pro-fargebehaldar og fargerutenett er tilgjengelege på denne Macen.",
+ "settings.proGuide.hotkeys": "Standardsnarvegar er tilgjengelege. Pro-brukarar kan tilpasse snarvegar.",
+ "settings.proGuide.tags": "7 standardfargar er tilgjengelege. Pro-brukarar kan tilpasse fleire fargar.",
+ "settings.proGuide.data": "Pro-brukarar kan importere og eksportere kategori- og oppsettsdata.",
+ "settings.proCompare.title": "Skilnader mellom gratis og Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Ikkje tilgjengeleg",
+ "settings.proStatus.previewFiveMinutes": "Berre 5 minutt førehandsvising",
+ "settings.proGuide.general": "Berre Pro-brukarar kan bruke farga behaldarar / farga rutenett"
}
diff --git a/src/Apptag/Localization/no.json b/src/Apptag/Localization/no.json
index adb9fe9..a64ffe7 100644
--- a/src/Apptag/Localization/no.json
+++ b/src/Apptag/Localization/no.json
@@ -8,8 +8,8 @@
"menu.language": "Språk",
"menu.help": "Hjelp",
"menu.version": "Versjon",
- "menu.proStatus.free": "Du er nå gratisbruker (oppgrader til Pro)",
- "menu.proStatus.unlocked": "Du er nå en verdsatt Pro-bruker",
+ "menu.proStatus.free": "Du er nå gratisbruker (oppgrader nå til 👑Pro)",
+ "menu.proStatus.unlocked": "Du er nå en verdsatt 👑Pro-bruker",
"settings.language": "Språk",
"settings.languagePicker": "Appspråk:",
"settings.languageDesc": "Velg språket som brukes i menyer og innstillinger.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Ingen smarte klassifiseringsresultater kan brukes.",
"scheme.local": "Lokalt skjema",
"scheme.systemSmartStart": "Systemets smarte startskjema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Vis bobletips for:",
+ "settings.bubbleAllApps": "Alle apper",
+ "settings.bubbleUncommonOnly": "Bare sjelden brukte apper",
+ "quickSearch.title": "Hurtigsøk",
+ "quickSearch.placeholder": "Søk etter apper, tagger og notater",
+ "quickSearch.inputAccessibility": "Inndata for hurtigsøk",
+ "quickSearch.emptyPrompt": "Begynn å skrive for å søke etter apper, tagger og notater.",
+ "quickSearch.noResults": "Fant ingen apper.",
+ "quickSearch.launchFailed": "Kunne ikke åpne denne appen. Prøv igjen eller velg en annen app.",
+ "quickSearch.tagPrefix": "Tagg",
+ "quickSearch.hotkeys": "Tastatursnarveier",
+ "quickSearch.mainHotkey": "Appliste",
+ "quickSearch.mainHotkeyDesc": "Åpner TagLauncher-applisten.",
+ "quickSearch.status.Active": "Aktiv",
+ "quickSearch.status.registrationFailed": "Registrering mislyktes",
+ "quickSearch.status.unavailable": "Snarvei utilgjengelig",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% kan ikke registreres akkurat nå. Den kan være brukt av macOS, en inndatametode eller en annen app. Snarveien for applisten er midlertidig utilgjengelig. Sjekk tastatursnarveier eller snarveikonflikter, og start TagLauncher på nytt. Feilkode: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% kan ikke registreres akkurat nå. Den kan være brukt av macOS, en inndatametode eller en annen app. Globalt hurtigsøk er midlertidig utilgjengelig. Sjekk tastatursnarveier eller snarveikonflikter, og start TagLauncher på nytt. Feilkode: %status%.",
+ "quickSearch.loading": "Forbereder søkeindeks…",
+ "quickSearch.internalHotkey": "Hurtigsøk (i TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Fungerer bare mens TagLauncher-applisten er åpen.",
+ "quickSearch.internalHotkeyStatus": "Bare appliste",
+ "quickSearch.globalHotkey": "Hurtigsøk (globalt)",
+ "quickSearch.globalHotkeyDesc": "Åpne hurtigsøk globalt når TagLauncher-applisten ikke er synlig.",
+ "quickSearch.spaceDisplay": "Space (mellomrom)",
"trackpadGesture.title": "Styreflatebevegelse",
"trackpadGesture.description": "Koble en styreflatebevegelse i et tredjepartsverktøy til denne URL-en for å vise applisten.",
"trackpadGesture.status": "Eksternt verktøy",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Forhåndsvisning",
"pro.card.restore": "Gjenopprett kjøp",
- "pro.card.summary.free": "Lås opp premium-temaer, import og eksport av layout, ubegrensede notater og lagret manuell appsortering.",
+ "pro.card.summary.free": "Lås op for egne tagfarver, premium-temaer, import og eksport af layout, ubegrænsede appnoter og egne genveje.",
"pro.card.summary.legacy": "Takk for at du støttet TagLauncher tidlig. Din Pro-tilgang er allerede aktiv.",
- "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Premium-temaer og avanserte layoutverktøy er klare.",
+ "pro.card.summary.unlocked": "Pro er aktiv på denne Mac. Egne tagfarver, avancerede temaer, ubegrænsede noter, egne genveje og layoutværktøjer er klar.",
"pro.card.title.free": "Oppgrader til Pro",
"pro.card.title.legacy": "Pro låst opp",
"pro.card.title.unlocked": "Pro låst opp",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Lagre gjeldende tagger, bestilling og layout som en gjenbrukbar sikkerhetskopi.",
"pro.feature.import": "Import av layout",
"pro.feature.import.benefit": "Gjenopprett et lagret TagLauncher-oppsett på denne Mac i ett trinn.",
- "pro.feature.notes": "Ubegrensede notater",
- "pro.feature.notes.benefit": "Lagre notater for hver app uten den gratis grensen på 5 noter.",
+ "pro.feature.notes": "Egne appnoter",
+ "pro.feature.notes.benefit": "Gratisversionen indeholder 3 appnoter. Pro låser op for ubegrænsede noter til alle apps.",
"pro.feature.sorting": "Lagret appsortering",
"pro.feature.sorting.benefit": "Behold den manuelle appbestillingen din etter at du forlater redigeringsmodus.",
"pro.feature.themes": "Premium-temaer",
"pro.feature.themes.benefit": "Lås opp hvert avansert App Grid-tema og behold det permanent.",
- "pro.notes.limitReached": "Gratisversjonen kan lagre notater for opptil 5 apper. Lås opp Pro for å lagre ubegrensede notater.",
+ "pro.notes.limitReached": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for ubegrænsede noter.",
"pro.notes.remaining": "Gratisversjonen inkluderer %limit% appnotater. %remaining% gjenstår.",
"pro.operation.cancelled": "Kjøp kansellert.",
"pro.operation.loading": "Sjekker Pro-tilgang …",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Gjenoppretter kjøpet …",
"pro.prompt.export": "Layouteksport er en Pro-funksjon. Lås opp Pro for å sikkerhetskopiere gjeldende tagger, rekkefølge og layout.",
"pro.prompt.import": "Layoutimport er en Pro-funksjon. Lås opp Pro for å gjenopprette et lagret oppsett på denne Mac.",
- "pro.prompt.notes": "Ubegrensede appnotater er en del av Pro. Lås opp Pro for å lagre notater for hver app.",
+ "pro.prompt.notes": "Gratisversionen kan gemme op til 3 appnoter. Lås Pro op for at gemme noter til alle apps.",
"pro.prompt.sorting": "Lagret manuell appsortering er en del av Pro. Lås opp Pro for å beholde din egendefinerte rekkefølge.",
"pro.prompt.themes": "Dette temaet er en del av Pro. Lås opp Pro for å fortsette å bruke avanserte App Grid-temaer.",
"pro.purchase.failed": "Kan ikke fullføre kjøpet akkurat nå. Vennligst prøv igjen.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Egne snarveier",
"pro.feature.customHotkeys.benefit": "Angi globale snarveier for applisten og Quick Search.",
"pro.prompt.customHotkeys": "Egne snarveier er en Pro-funksjon. Lås opp Pro for å angi dem.",
- "hotkeys.customize": "Tilpass",
+ "hotkeys.customize": "Endre snarvei",
"hotkeys.restoreDefault": "Gjenopprett standard",
"hotkeys.recording": "Trykk den nye snarveien nå. Esc avbryter.",
"hotkeys.recordingInline": "Tar opp",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Denne tasten støttes ikke.",
"hotkeys.error.reserved": "Denne snarveien er reservert av macOS eller appen.",
"hotkeys.error.duplicate": "Denne snarveien tilhører allerede en annen TagLauncher-handling.",
- "hotkeys.error.registrationFailed": "Snarveien kunne ikke registreres. Feilkode: %status%."
+ "hotkeys.error.registrationFailed": "Snarveien kunne ikke registreres. Feilkode: %status%.",
+ "pro.feature.customTagColors": "Egne tagfarver",
+ "pro.feature.customTagColors.benefit": "Vælg en hvilken som helst farve til hvert tag, også SmartStart-systemkategorier.",
+ "pro.prompt.customTagColors": "Egne tagfarver er en Pro-funktion. Lås Pro op for at give hvert tag en valgfri farve og gøre kategorier lettere at kende.",
+ "settings.proStatus.freeUser": "Du er nå gratisbruker",
+ "settings.proStatus.proUser": "Du er nå en verdsatt 👑Pro-bruker",
+ "settings.proStatus.lockedListTitle": "Pro-funksjoner å låse opp",
+ "settings.proStatus.unlockedListTitle": "Opplåste funksjoner",
+ "settings.proStatus.lockedFeature": "✅ Støttet",
+ "settings.proStatus.unlockedFeature": "✅Opplåst",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Ubegrensede notater",
+ "settings.proStatus.limitedFeature": "Begrenset",
+ "settings.proStatus.unsupportedFeature": "Støttes ikke",
+ "settings.proFeature.appNotes": "Egne appnoter",
+ "settings.proFeature.dataBackup": "Dataimport/-eksport og layoutbackups",
+ "tag.customColor": "Egen farge",
+ "settings.proBenefit.hotkeys": "Still inn dine egne snarveier for TagLauncher-handlinger.",
+ "settings.proBenefit.tags": "Gi hver tagg en egen farge så du kjenner den igjen raskere.",
+ "settings.proBenefit.data": "Sikkerhetskopier, eksporter, importer og gjenopprett kategorier og layout.",
+ "settings.proBenefit.about": "Alle Pro-fordeler er låst opp på denne Macen.",
+ "settings.proBenefit.general": "Pro-fargebeholder og fargerutenett er tilgjengelig på denne Macen.",
+ "settings.proGuide.hotkeys": "Standardsnarveier er tilgjengelige. Pro-brukere kan tilpasse snarveier.",
+ "settings.proGuide.tags": "7 standardfarger er tilgjengelige. Pro-brukere kan tilpasse flere farger.",
+ "settings.proGuide.data": "Pro-brukere kan importere og eksportere kategori- og oppsettsdata.",
+ "settings.proCompare.title": "Forskjeller mellom gratis og Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Ikke tilgjengelig",
+ "settings.proStatus.previewFiveMinutes": "Kun 5 minutters forhåndsvisning",
+ "settings.proGuide.general": "Bare Pro-brukere kan bruke fargede beholdere / fargede rutenett"
}
diff --git a/src/Apptag/Localization/pl.json b/src/Apptag/Localization/pl.json
index ceb1397..2e2a033 100644
--- a/src/Apptag/Localization/pl.json
+++ b/src/Apptag/Localization/pl.json
@@ -8,8 +8,8 @@
"menu.language": "Język",
"menu.help": "Pomoc",
"menu.version": "Wersja",
- "menu.proStatus.free": "Obecnie korzystasz z wersji bezpłatnej (uaktualnij do Pro)",
- "menu.proStatus.unlocked": "Obecnie jesteś cenionym użytkownikiem Pro",
+ "menu.proStatus.free": "Obecnie jesteś użytkownikiem bezpłatnym (uaktualnij teraz do 👑Pro)",
+ "menu.proStatus.unlocked": "Obecnie jesteś cenionym użytkownikiem 👑Pro",
"settings.language": "Język",
"settings.languagePicker": "Język aplikacji:",
"settings.languageDesc": "Wybierz język menu i ustawień.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Brak wyników inteligentnej klasyfikacji do zastosowania.",
"scheme.local": "Schemat lokalny",
"scheme.systemSmartStart": "Inteligentny schemat początkowy systemu",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
+ "settings.bubbleDisplayScope": "Pokazuj dymki podpowiedzi dla:",
+ "settings.bubbleAllApps": "Wszystkie aplikacje",
+ "settings.bubbleUncommonOnly": "Tylko rzadziej używane aplikacje",
+ "quickSearch.title": "Szybkie wyszukiwanie",
+ "quickSearch.placeholder": "Szukaj aplikacji, tagów i notatek",
+ "quickSearch.inputAccessibility": "Pole szybkiego wyszukiwania",
+ "quickSearch.emptyPrompt": "Zacznij pisać, aby szukać aplikacji, tagów i notatek.",
+ "quickSearch.noResults": "Nie znaleziono aplikacji.",
+ "quickSearch.launchFailed": "Nie można otworzyć tej aplikacji. Spróbuj ponownie lub wybierz inną aplikację.",
"quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "quickSearch.hotkeys": "Skróty klawiaturowe",
+ "quickSearch.mainHotkey": "Lista aplikacji",
+ "quickSearch.mainHotkeyDesc": "Otwiera listę aplikacji TagLauncher.",
+ "quickSearch.status.Active": "Aktywny",
+ "quickSearch.status.registrationFailed": "Rejestracja nie powiodła się",
+ "quickSearch.status.unavailable": "Skrót niedostępny",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% nie może teraz zostać zarejestrowany. Może być używany przez macOS, metodę wprowadzania lub inną aplikację. Skrót listy aplikacji jest tymczasowo niedostępny. Sprawdź skróty klawiaturowe lub konflikty skrótów, a następnie uruchom ponownie TagLauncher. Kod błędu: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% nie może teraz zostać zarejestrowany. Może być używany przez macOS, metodę wprowadzania lub inną aplikację. Globalne szybkie wyszukiwanie jest tymczasowo niedostępne. Sprawdź skróty klawiaturowe lub konflikty skrótów, a następnie uruchom ponownie TagLauncher. Kod błędu: %status%.",
+ "quickSearch.loading": "Przygotowywanie indeksu wyszukiwania…",
+ "quickSearch.internalHotkey": "Szybkie wyszukiwanie (w TagLauncherze)",
+ "quickSearch.internalHotkeyDesc": "Działa tylko wtedy, gdy lista aplikacji TagLauncher jest otwarta.",
+ "quickSearch.internalHotkeyStatus": "Tylko lista aplikacji",
+ "quickSearch.globalHotkey": "Szybkie wyszukiwanie (globalne)",
+ "quickSearch.globalHotkeyDesc": "Otwiera globalne szybkie wyszukiwanie, gdy lista aplikacji TagLauncher nie jest widoczna.",
+ "quickSearch.spaceDisplay": "Space (spacja)",
"trackpadGesture.title": "Gest gładzika",
"trackpadGesture.description": "Przypisz gest gładzika w narzędziu innej firmy do tego URL-a, aby pokazać listę aplikacji.",
"trackpadGesture.status": "Narzędzie zewnętrzne",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Zapowiedź",
"pro.card.restore": "Przywróć zakupy",
- "pro.card.summary.free": "Odblokuj motywy premium, import i eksport układu, nieograniczoną liczbę notatek i zapisane ręczne sortowanie aplikacji.",
+ "pro.card.summary.free": "Odblokuj własne kolory tagów, motywy premium, import i eksport układów, nielimitowane notatki aplikacji oraz własne skróty.",
"pro.card.summary.legacy": "Dziękujemy za wcześniejsze wsparcie TagLauncher. Twój dostęp do Pro jest już aktywny.",
- "pro.card.summary.unlocked": "Pro jest aktywny na tym Mac. Motywy premium i zaawansowane narzędzia do układania są gotowe.",
+ "pro.card.summary.unlocked": "Pro działa na tym Macu. Własne kolory tagów, zaawansowane motywy, nielimitowane notatki, własne skróty i narzędzia układu są gotowe.",
"pro.card.title.free": "Uaktualnij do Pro",
"pro.card.title.legacy": "Pro odblokowany",
"pro.card.title.unlocked": "Pro odblokowany",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Zapisz bieżące tagi, zamówienie i układ jako kopię zapasową do ponownego wykorzystania.",
"pro.feature.import": "Import układu",
"pro.feature.import.benefit": "Przywróć zapisany układ TagLauncher na tym Mac w jednym kroku.",
- "pro.feature.notes": "Nieograniczone notatki",
- "pro.feature.notes.benefit": "Zapisuj notatki dla każdej aplikacji bez bezpłatnego limitu 5 notatek.",
+ "pro.feature.notes": "Własne notatki aplikacji",
+ "pro.feature.notes.benefit": "Wersja darmowa zawiera 3 notatki aplikacji. Pro odblokowuje nielimitowane notatki dla wszystkich aplikacji.",
"pro.feature.sorting": "Sortowanie zapisanych aplikacji",
"pro.feature.sorting.benefit": "Zachowaj ręczną kolejność aplikacji po wyjściu z trybu edycji.",
"pro.feature.themes": "Motywy premium",
"pro.feature.themes.benefit": "Odblokuj każdy zaawansowany motyw App Grid i zachowaj go na stałe.",
- "pro.notes.limitReached": "Darmowa wersja może zapisywać notatki dla maksymalnie 5 aplikacji. Odblokuj Pro, aby zapisywać nieograniczoną liczbę notatek.",
+ "pro.notes.limitReached": "Wersja darmowa zapisuje do 3 notatek aplikacji. Odblokuj Pro dla nielimitowanych notatek.",
"pro.notes.remaining": "Darmowa wersja zawiera %limit% notatki dotyczące aplikacji. pozostało %remaining%.",
"pro.operation.cancelled": "Zakup anulowany.",
"pro.operation.loading": "Sprawdzam dostęp Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Przywracam zakup…",
"pro.prompt.export": "Eksport układu to funkcja Pro. Odblokuj Pro, aby utworzyć kopię zapasową bieżących tagów, kolejności i układu.",
"pro.prompt.import": "Import układu to funkcja Pro. Odblokuj Pro, aby przywrócić zapisany układ na tym Mac.",
- "pro.prompt.notes": "Nieograniczone notatki z aplikacji są częścią Pro. Odblokuj Pro, aby zapisywać notatki dla każdej aplikacji.",
+ "pro.prompt.notes": "Wersja darmowa zapisuje do 3 notatek aplikacji. Odblokuj Pro, aby zapisywać notatki dla wszystkich aplikacji.",
"pro.prompt.sorting": "Zapisane ręczne sortowanie aplikacji jest częścią Pro. Odblokuj Pro, aby zachować niestandardowe zamówienie.",
"pro.prompt.themes": "Ten motyw jest częścią Pro. Odblokuj Pro, aby nadal korzystać z zaawansowanych motywów App Grid.",
"pro.purchase.failed": "Nie można w tej chwili sfinalizować zakupu. Spróbuj ponownie.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Własne skróty",
"pro.feature.customHotkeys.benefit": "Ustaw globalne skróty dla listy aplikacji i Quick Search.",
"pro.prompt.customHotkeys": "Własne skróty są częścią Pro. Odblokuj Pro, aby je ustawić.",
- "hotkeys.customize": "Dostosuj",
+ "hotkeys.customize": "Zmień skrót",
"hotkeys.restoreDefault": "Przywróć domyślne",
"hotkeys.recording": "Naciśnij teraz nowy skrót. Esc anuluje.",
"hotkeys.recordingInline": "Nagrywanie",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Ten klawisz nie jest obsługiwany.",
"hotkeys.error.reserved": "Ten skrót jest zarezerwowany przez macOS lub aplikację.",
"hotkeys.error.duplicate": "Ten skrót jest już przypisany do innej akcji TagLauncher.",
- "hotkeys.error.registrationFailed": "Nie można zarejestrować skrótu. Kod błędu: %status%."
+ "hotkeys.error.registrationFailed": "Nie można zarejestrować skrótu. Kod błędu: %status%.",
+ "pro.feature.customTagColors": "Własne kolory tagów",
+ "pro.feature.customTagColors.benefit": "Ustaw dowolny kolor dla każdego tagu, także kategorii systemowych SmartStart.",
+ "pro.prompt.customTagColors": "Własne kolory tagów są funkcją Pro. Odblokuj Pro, nadaj każdemu tagowi dowolny kolor i łatwiej rozpoznawaj kategorie.",
+ "settings.proStatus.freeUser": "Obecnie jesteś użytkownikiem bezpłatnym",
+ "settings.proStatus.proUser": "Obecnie jesteś cenionym użytkownikiem 👑Pro",
+ "settings.proStatus.lockedListTitle": "Funkcje Pro do odblokowania",
+ "settings.proStatus.unlockedListTitle": "Odblokowane funkcje",
+ "settings.proStatus.lockedFeature": "✅ Obsługiwane",
+ "settings.proStatus.unlockedFeature": "✅Odblokowane",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Notatki bez limitu",
+ "settings.proStatus.limitedFeature": "Ograniczone",
+ "settings.proStatus.unsupportedFeature": "Nieobsługiwane",
+ "settings.proFeature.appNotes": "Własne notatki aplikacji",
+ "settings.proFeature.dataBackup": "Import/eksport danych i kopie układu",
+ "tag.customColor": "Własny kolor",
+ "settings.proBenefit.hotkeys": "Ustaw własne skróty dla działań TagLaunchera.",
+ "settings.proBenefit.tags": "Nadaj każdemu tagowi własny kolor, aby szybciej go rozpoznawać.",
+ "settings.proBenefit.data": "Twórz kopie, eksportuj, importuj i przywracaj kategorie oraz układ.",
+ "settings.proBenefit.about": "Wszystkie korzyści Pro są odblokowane na tym Macu.",
+ "settings.proBenefit.general": "Kolorowy kontener i kolorowa siatka Pro są dostępne na tym Macu.",
+ "settings.proGuide.hotkeys": "Domyślne skróty są dostępne. Użytkownicy Pro mogą dostosować skróty.",
+ "settings.proGuide.tags": "Dostępnych jest 7 domyślnych kolorów. Użytkownicy Pro mogą dostosować więcej kolorów.",
+ "settings.proGuide.data": "Użytkownicy Pro mogą importować i eksportować dane kategorii oraz układu.",
+ "settings.proCompare.title": "Różnice między darmową wersją i Pro",
+ "settings.proCompare.free": "Darmowa",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Niedostępne",
+ "settings.proStatus.previewFiveMinutes": "Tylko 5 minut podglądu",
+ "settings.proGuide.general": "Tylko użytkownicy Pro mogą używać kolorowych kontenerów / siatek"
}
diff --git a/src/Apptag/Localization/pt-BR.json b/src/Apptag/Localization/pt-BR.json
index 9ff08cb..7b563a1 100644
--- a/src/Apptag/Localization/pt-BR.json
+++ b/src/Apptag/Localization/pt-BR.json
@@ -8,8 +8,8 @@
"menu.language": "Idioma",
"menu.help": "Ajuda",
"menu.version": "Versão",
- "menu.proStatus.free": "Você está na versão gratuita (atualizar para Pro)",
- "menu.proStatus.unlocked": "Você é um usuário Pro especial",
+ "menu.proStatus.free": "Você está usando a versão gratuita (atualize agora para 👑Pro)",
+ "menu.proStatus.unlocked": "Você é um usuário 👑Pro valorizado",
"settings.language": "Idioma",
"settings.languagePicker": "Idioma do app:",
"settings.languageDesc": "Escolha o idioma usado nos menus e ajustes.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Não há resultados de classificação inteligente para aplicar.",
"scheme.local": "Esquema local",
"scheme.systemSmartStart": "Esquema inicial inteligente do sistema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Mostrar dicas em bolha para:",
+ "settings.bubbleAllApps": "Todos os apps",
+ "settings.bubbleUncommonOnly": "Somente apps pouco usados",
+ "quickSearch.title": "Busca rápida",
+ "quickSearch.placeholder": "Buscar apps, etiquetas e notas",
+ "quickSearch.inputAccessibility": "Campo de busca rápida",
+ "quickSearch.emptyPrompt": "Comece a digitar para buscar apps, etiquetas e notas.",
+ "quickSearch.noResults": "Nenhum app encontrado.",
+ "quickSearch.launchFailed": "Não foi possível abrir este app. Tente novamente ou escolha outro app.",
+ "quickSearch.tagPrefix": "Etiqueta",
+ "quickSearch.hotkeys": "Atalhos de teclado",
+ "quickSearch.mainHotkey": "Lista de apps",
+ "quickSearch.mainHotkeyDesc": "Abre a lista de apps do TagLauncher.",
+ "quickSearch.status.Active": "Ativo",
+ "quickSearch.status.registrationFailed": "Falha ao registrar",
+ "quickSearch.status.unavailable": "Atalho indisponível",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% não pode ser registrado agora. Ele pode estar sendo usado pelo macOS, por um método de entrada ou por outro app. O atalho da lista de apps está temporariamente indisponível. Verifique os atalhos de teclado ou conflitos e reinicie o TagLauncher. Código de erro: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% não pode ser registrado agora. Ele pode estar sendo usado pelo macOS, por um método de entrada ou por outro app. A busca rápida global está temporariamente indisponível. Verifique os atalhos de teclado ou conflitos e reinicie o TagLauncher. Código de erro: %status%.",
+ "quickSearch.loading": "Preparando índice de busca…",
+ "quickSearch.internalHotkey": "Busca rápida (dentro do TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Funciona somente enquanto a lista de apps do TagLauncher está aberta.",
+ "quickSearch.internalHotkeyStatus": "Somente lista de apps",
+ "quickSearch.globalHotkey": "Busca rápida (global)",
+ "quickSearch.globalHotkeyDesc": "Abra a busca rápida global quando a lista de apps do TagLauncher não estiver visível.",
+ "quickSearch.spaceDisplay": "Space (barra de espaço)",
"trackpadGesture.title": "Gesto do trackpad",
"trackpadGesture.description": "Mapeie um gesto do trackpad em uma ferramenta de terceiros para esta URL para mostrar a lista de apps.",
"trackpadGesture.status": "Ferramenta externa",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Visualização",
"pro.card.restore": "Restaurar compras",
- "pro.card.summary.free": "Desbloqueie temas premium, importação e exportação de layout, notas ilimitadas e classificação manual de aplicativos salvos.",
+ "pro.card.summary.free": "Desbloqueie cores personalizadas de etiquetas, temas premium, importação e exportação de layout, notas ilimitadas e atalhos personalizados.",
"pro.card.summary.legacy": "Obrigado por apoiar TagLauncher antecipadamente. Seu acesso Pro já está ativo.",
- "pro.card.summary.unlocked": "Pro está ativo neste Mac. Temas premium e ferramentas de layout avançadas estão prontos.",
+ "pro.card.summary.unlocked": "O Pro está ativo neste Mac. Cores personalizadas, temas avançados, notas ilimitadas, atalhos personalizados e ferramentas de layout estão prontos.",
"pro.card.title.free": "Atualizar para Pro",
"pro.card.title.legacy": "Pro desbloqueado",
"pro.card.title.unlocked": "Pro desbloqueado",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Salve suas tags, pedidos e layout atuais como um backup reutilizável.",
"pro.feature.import": "Importação de layout",
"pro.feature.import.benefit": "Restaure um layout TagLauncher salvo neste Mac em uma única etapa.",
- "pro.feature.notes": "Notas ilimitadas",
- "pro.feature.notes.benefit": "Salve notas para cada aplicativo sem o limite gratuito de 5 notas.",
+ "pro.feature.notes": "Notas personalizadas de apps",
+ "pro.feature.notes.benefit": "A versão gratuita inclui 3 notas de apps. O Pro libera notas ilimitadas para todos os apps.",
"pro.feature.sorting": "Classificação de aplicativos salvos",
"pro.feature.sorting.benefit": "Mantenha a ordem manual do aplicativo depois de sair do modo de edição.",
"pro.feature.themes": "Temas premium",
"pro.feature.themes.benefit": "Desbloqueie todos os temas avançados do App Grid e mantenha-os permanentemente.",
- "pro.notes.limitReached": "A versão gratuita pode salvar notas para até 5 aplicativos. Desbloqueie Pro para salvar notas ilimitadas.",
+ "pro.notes.limitReached": "A versão gratuita salva até 3 notas de apps. Desbloqueie o Pro para notas ilimitadas.",
"pro.notes.remaining": "A versão gratuita inclui %limit% notas do aplicativo. %remaining% restante.",
"pro.operation.cancelled": "Compra cancelada.",
"pro.operation.loading": "Verificando acesso Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Restaurando compra…",
"pro.prompt.export": "A exportação de layout é um recurso Pro. Desbloqueie Pro para fazer backup de suas tags, ordem e layout atuais.",
"pro.prompt.import": "A importação de layout é um recurso Pro. Desbloqueie Pro para restaurar um layout salvo neste Mac.",
- "pro.prompt.notes": "Notas de aplicativos ilimitadas fazem parte do Pro. Desbloqueie Pro para salvar notas para cada aplicativo.",
+ "pro.prompt.notes": "A versão gratuita salva até 3 notas de apps. Desbloqueie o Pro para salvar notas em todos os apps.",
"pro.prompt.sorting": "A classificação manual de aplicativos salvos faz parte do Pro. Desbloqueie Pro para manter seu pedido personalizado.",
"pro.prompt.themes": "Este tema faz parte do Pro. Desbloqueie Pro para continuar usando temas App Grid avançados.",
"pro.purchase.failed": "Não é possível concluir a compra no momento. Por favor, tente novamente.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Atalhos personalizados",
"pro.feature.customHotkeys.benefit": "Defina atalhos globais para a lista de apps e o Quick Search.",
"pro.prompt.customHotkeys": "Atalhos personalizados fazem parte do Pro. Desbloqueie o Pro para definir atalhos globais.",
- "hotkeys.customize": "Personalizar",
+ "hotkeys.customize": "Alterar atalho",
"hotkeys.restoreDefault": "Restaurar padrão",
"hotkeys.recording": "Pressione o novo atalho agora. Pressione Esc para cancelar.",
"hotkeys.recordingInline": "Gravando",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Esta tecla não é compatível.",
"hotkeys.error.reserved": "Este atalho é reservado pelo macOS ou pelo app.",
"hotkeys.error.duplicate": "Este atalho já pertence a outra ação do TagLauncher.",
- "hotkeys.error.registrationFailed": "Não foi possível registrar o atalho. Código de erro: %status%."
+ "hotkeys.error.registrationFailed": "Não foi possível registrar o atalho. Código de erro: %status%.",
+ "pro.feature.customTagColors": "Cores personalizadas de etiquetas",
+ "pro.feature.customTagColors.benefit": "Defina qualquer cor para cada etiqueta, incluindo categorias de sistema do SmartStart.",
+ "pro.prompt.customTagColors": "Cores personalizadas de etiquetas são um recurso Pro. Desbloqueie o Pro para dar qualquer cor a cada etiqueta e reconhecer categorias com mais facilidade.",
+ "settings.proStatus.freeUser": "Você está usando a versão gratuita",
+ "settings.proStatus.proUser": "Você é um usuário 👑Pro valorizado",
+ "settings.proStatus.lockedListTitle": "Recursos Pro para desbloquear",
+ "settings.proStatus.unlockedListTitle": "Recursos desbloqueados",
+ "settings.proStatus.lockedFeature": "✅ Compatível",
+ "settings.proStatus.unlockedFeature": "✅Desbloqueado",
+ "settings.proStatus.freeNotes": "3 grátis",
+ "settings.proStatus.unlimitedNotes": "✅ Notas ilimitadas",
+ "settings.proStatus.limitedFeature": "Limitado",
+ "settings.proStatus.unsupportedFeature": "Sem suporte",
+ "settings.proFeature.appNotes": "Notas personalizadas de apps",
+ "settings.proFeature.dataBackup": "Importação/exportação de dados e backups de layout",
+ "tag.customColor": "Cor personalizada",
+ "settings.proBenefit.hotkeys": "Defina seus próprios atalhos para ações do TagLauncher.",
+ "settings.proBenefit.tags": "Dê uma cor personalizada a cada etiqueta para reconhecer mais rápido.",
+ "settings.proBenefit.data": "Faça backup, exporte, importe e restaure categorias e layout.",
+ "settings.proBenefit.about": "Todos os benefícios Pro estão desbloqueados neste Mac.",
+ "settings.proBenefit.general": "O contêiner colorido e a grade colorida Pro estão disponíveis neste Mac.",
+ "settings.proGuide.hotkeys": "Os atalhos padrão estão disponíveis. Usuários Pro podem personalizar atalhos.",
+ "settings.proGuide.tags": "7 cores padrão estão disponíveis. Usuários Pro podem personalizar mais cores.",
+ "settings.proGuide.data": "Usuários Pro podem importar e exportar dados de categorias e layout.",
+ "settings.proCompare.title": "Diferenças entre Grátis e Pro",
+ "settings.proCompare.free": "Grátis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Indisponível",
+ "settings.proStatus.previewFiveMinutes": "Apenas prévia de 5 minutos",
+ "settings.proGuide.general": "Só usuários Pro podem usar contêineres / grades coloridos"
}
diff --git a/src/Apptag/Localization/ro.json b/src/Apptag/Localization/ro.json
index 977d478..020a93d 100644
--- a/src/Apptag/Localization/ro.json
+++ b/src/Apptag/Localization/ro.json
@@ -8,8 +8,8 @@
"menu.language": "Limbă",
"menu.help": "Ajutor",
"menu.version": "Versiune",
- "menu.proStatus.free": "În prezent sunteți utilizator gratuit (treceți la Pro)",
- "menu.proStatus.unlocked": "În prezent sunteți un utilizator Pro apreciat",
+ "menu.proStatus.free": "Ești în prezent utilizator gratuit (treci acum la 👑Pro)",
+ "menu.proStatus.unlocked": "Ești în prezent un utilizator 👑Pro apreciat",
"settings.language": "Limbă",
"settings.languagePicker": "Limba aplicației:",
"settings.languageDesc": "Alege limba folosită pentru meniuri și setări.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Nu există rezultate de clasificare inteligentă de aplicat.",
"scheme.local": "Schema locală",
"scheme.systemSmartStart": "Schema inteligentă inițială a sistemului",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Afișează baloane de ajutor pentru:",
+ "settings.bubbleAllApps": "Toate aplicațiile",
+ "settings.bubbleUncommonOnly": "Doar aplicațiile rar folosite",
+ "quickSearch.title": "Căutare rapidă",
+ "quickSearch.placeholder": "Caută aplicații, etichete și note",
+ "quickSearch.inputAccessibility": "Câmp de căutare rapidă",
+ "quickSearch.emptyPrompt": "Începe să tastezi pentru a căuta aplicații, etichete și note.",
+ "quickSearch.noResults": "Nu s-au găsit aplicații.",
+ "quickSearch.launchFailed": "Această aplicație nu poate fi deschisă. Încearcă din nou sau alege altă aplicație.",
+ "quickSearch.tagPrefix": "Etichetă",
+ "quickSearch.hotkeys": "Scurtături de la tastatură",
+ "quickSearch.mainHotkey": "Lista de aplicații",
+ "quickSearch.mainHotkeyDesc": "Deschide lista de aplicații TagLauncher.",
+ "quickSearch.status.Active": "Activ",
+ "quickSearch.status.registrationFailed": "Înregistrarea a eșuat",
+ "quickSearch.status.unavailable": "Scurtătură indisponibilă",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% nu poate fi înregistrată acum. Poate fi folosită de macOS, o metodă de introducere sau altă aplicație. Scurtătura listei de aplicații este temporar indisponibilă. Verifică scurtăturile de la tastatură sau conflictele, apoi repornește TagLauncher. Cod eroare: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% nu poate fi înregistrată acum. Poate fi folosită de macOS, o metodă de introducere sau altă aplicație. Căutarea rapidă globală este temporar indisponibilă. Verifică scurtăturile de la tastatură sau conflictele, apoi repornește TagLauncher. Cod eroare: %status%.",
+ "quickSearch.loading": "Se pregătește indexul de căutare…",
+ "quickSearch.internalHotkey": "Căutare rapidă (în TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Funcționează doar cât timp lista de aplicații TagLauncher este deschisă.",
+ "quickSearch.internalHotkeyStatus": "Doar lista de aplicații",
+ "quickSearch.globalHotkey": "Căutare rapidă (globală)",
+ "quickSearch.globalHotkeyDesc": "Deschide căutarea rapidă globală când lista de aplicații TagLauncher nu este vizibilă.",
+ "quickSearch.spaceDisplay": "Space (bara de spațiu)",
"trackpadGesture.title": "Gest trackpad",
"trackpadGesture.description": "Asociază un gest de trackpad dintr-un instrument terț cu acest URL pentru a afișa lista de aplicații.",
"trackpadGesture.status": "Instrument extern",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Previzualizare",
"pro.card.restore": "Restabiliți achizițiile",
- "pro.card.summary.free": "Deblocați teme premium, import și export de aspect, note nelimitate și sortarea manuală a aplicațiilor salvate.",
+ "pro.card.summary.free": "Deblochează culori personalizate pentru etichete, teme premium, import și export de aspect, note nelimitate pentru aplicații și scurtături personalizate.",
"pro.card.summary.legacy": "Vă mulțumim că ați susținut TagLauncher devreme. Accesul dvs. Pro este deja activ.",
- "pro.card.summary.unlocked": "Pro este activ pe acest Mac. Temele premium și instrumentele avansate de aspect sunt gata.",
+ "pro.card.summary.unlocked": "Pro este activ pe acest Mac. Culorile personalizate, temele avansate, notele nelimitate, scurtăturile personalizate și uneltele de aspect sunt gata.",
"pro.card.title.free": "Faceți upgrade la Pro",
"pro.card.title.legacy": "Pro deblocat",
"pro.card.title.unlocked": "Pro deblocat",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Salvați etichetele actuale, comanda și aspectul ca o copie de rezervă reutilizabilă.",
"pro.feature.import": "import aspect",
"pro.feature.import.benefit": "Restaurați un aspect TagLauncher salvat pe acest Mac într-un singur pas.",
- "pro.feature.notes": "Note nelimitate",
- "pro.feature.notes.benefit": "Salvați notele pentru fiecare aplicație fără limita gratuită de 5 note.",
+ "pro.feature.notes": "Note personalizate pentru aplicații",
+ "pro.feature.notes.benefit": "Versiunea gratuită include 3 note pentru aplicații. Pro deblochează note nelimitate pentru toate aplicațiile.",
"pro.feature.sorting": "sortarea aplicațiilor salvate",
"pro.feature.sorting.benefit": "Păstrați ordinea manuală a aplicațiilor după ce părăsiți modul de editare.",
"pro.feature.themes": "Teme premium",
"pro.feature.themes.benefit": "Deblocați fiecare temă avansată App Grid și păstrați-o permanent.",
- "pro.notes.limitReached": "Versiunea gratuită poate salva note pentru până la 5 aplicații. Deblocați Pro pentru a salva note nelimitate.",
+ "pro.notes.limitReached": "Versiunea gratuită poate salva până la 3 note pentru aplicații. Deblochează Pro pentru note nelimitate.",
"pro.notes.remaining": "versiunea gratuită include %limit% note de aplicație. %remaining% rămas.",
"pro.operation.cancelled": "Achiziție anulată.",
"pro.operation.loading": "Se verifică accesul Pro...",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Restabilirea achiziției...",
"pro.prompt.export": "Exportul aspectului este o caracteristică Pro. Deblocați Pro pentru a face backup pentru etichetele, ordinea și aspectul actual.",
"pro.prompt.import": "Importul aspectului este o caracteristică Pro. Deblocați Pro pentru a restabili un aspect salvat pe acest Mac.",
- "pro.prompt.notes": "Notele nelimitate ale aplicației fac parte din Pro. Deblocați Pro pentru a salva note pentru fiecare aplicație.",
+ "pro.prompt.notes": "Versiunea gratuită poate salva până la 3 note pentru aplicații. Deblochează Pro pentru a salva note pentru toate aplicațiile.",
"pro.prompt.sorting": "sortarea manuală a aplicațiilor salvate face parte din Pro. Deblocați Pro pentru a vă păstra comanda personalizată.",
"pro.prompt.themes": "Această temă face parte din Pro. Deblocați Pro pentru a continua să utilizați teme avansate App Grid.",
"pro.purchase.failed": "Nu se poate finaliza achiziția acum. Vă rugăm să încercați din nou.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Scurtături personalizate",
"pro.feature.customHotkeys.benefit": "Setează scurtături globale pentru lista de aplicații și Quick Search.",
"pro.prompt.customHotkeys": "Scurtăturile personalizate fac parte din Pro. Deblochează Pro pentru a le seta.",
- "hotkeys.customize": "Personalizează",
+ "hotkeys.customize": "Schimbă scurtătura",
"hotkeys.restoreDefault": "Revino la implicit",
"hotkeys.recording": "Apasă acum noua scurtătură. Esc anulează.",
"hotkeys.recordingInline": "Se înregistrează",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Această tastă nu este acceptată.",
"hotkeys.error.reserved": "Această scurtătură este rezervată de macOS sau aplicație.",
"hotkeys.error.duplicate": "Această scurtătură aparține deja altei acțiuni TagLauncher.",
- "hotkeys.error.registrationFailed": "Scurtătura nu a putut fi înregistrată. Cod eroare: %status%."
+ "hotkeys.error.registrationFailed": "Scurtătura nu a putut fi înregistrată. Cod eroare: %status%.",
+ "pro.feature.customTagColors": "Culori personalizate pentru etichete",
+ "pro.feature.customTagColors.benefit": "Setează orice culoare pentru fiecare etichetă, inclusiv categoriile de sistem SmartStart.",
+ "pro.prompt.customTagColors": "Culorile personalizate pentru etichete sunt o funcție Pro. Deblochează Pro pentru a colora fiecare etichetă și a recunoaște mai ușor categoriile.",
+ "settings.proStatus.freeUser": "Ești în prezent utilizator gratuit",
+ "settings.proStatus.proUser": "Ești în prezent un utilizator 👑Pro apreciat",
+ "settings.proStatus.lockedListTitle": "Funcții Pro de deblocat",
+ "settings.proStatus.unlockedListTitle": "Funcții deblocate",
+ "settings.proStatus.lockedFeature": "✅ Acceptat",
+ "settings.proStatus.unlockedFeature": "✅Deblocat",
+ "settings.proStatus.freeNotes": "3 gratuite",
+ "settings.proStatus.unlimitedNotes": "✅ Note nelimitate",
+ "settings.proStatus.limitedFeature": "Limitat",
+ "settings.proStatus.unsupportedFeature": "Neacceptat",
+ "settings.proFeature.appNotes": "Note personalizate pentru aplicații",
+ "settings.proFeature.dataBackup": "Import/export date și backupuri de aspect",
+ "tag.customColor": "Culoare personalizată",
+ "settings.proBenefit.hotkeys": "Setează scurtături proprii pentru acțiunile TagLauncher.",
+ "settings.proBenefit.tags": "Dă fiecărei etichete o culoare personalizată pentru recunoaștere rapidă.",
+ "settings.proBenefit.data": "Fă backup, exportă, importă și restaurează categorii și aspecte.",
+ "settings.proBenefit.about": "Toate beneficiile Pro sunt deblocate pe acest Mac.",
+ "settings.proBenefit.general": "Containerul colorat și grila colorată Pro sunt disponibile pe acest Mac.",
+ "settings.proGuide.hotkeys": "Scurtăturile implicite sunt disponibile. Utilizatorii Pro pot personaliza scurtăturile.",
+ "settings.proGuide.tags": "Sunt disponibile 7 culori implicite. Utilizatorii Pro pot personaliza mai multe culori.",
+ "settings.proGuide.data": "Utilizatorii Pro pot importa și exporta date de categorii și aspect.",
+ "settings.proCompare.title": "Diferențe între Gratuit și Pro",
+ "settings.proCompare.free": "Gratuit",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Indisponibil",
+ "settings.proStatus.previewFiveMinutes": "Doar previzualizare de 5 minute",
+ "settings.proGuide.general": "Doar utilizatorii Pro pot folosi containere / grile colorate"
}
diff --git a/src/Apptag/Localization/ru.json b/src/Apptag/Localization/ru.json
index e0e6345..bca49e1 100644
--- a/src/Apptag/Localization/ru.json
+++ b/src/Apptag/Localization/ru.json
@@ -8,8 +8,8 @@
"menu.language": "Язык",
"menu.help": "Справка",
"menu.version": "Версия",
- "menu.proStatus.free": "Сейчас вы пользователь бесплатной версии (перейти на Pro)",
- "menu.proStatus.unlocked": "Сейчас вы ценный пользователь Pro",
+ "menu.proStatus.free": "Сейчас вы пользователь бесплатной версии (перейти на 👑Pro сейчас)",
+ "menu.proStatus.unlocked": "Сейчас вы ценный пользователь 👑Pro",
"settings.language": "Язык",
"settings.languagePicker": "Язык приложения:",
"settings.languageDesc": "Выберите язык меню и настроек.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Нет результатов интеллектуальной классификации для применения.",
"scheme.local": "Локальная схема",
"scheme.systemSmartStart": "Интеллектуальная начальная схема системы",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Показывать подсказки для:",
+ "settings.bubbleAllApps": "Все приложения",
+ "settings.bubbleUncommonOnly": "Только редко используемые приложения",
+ "quickSearch.title": "Быстрый поиск",
+ "quickSearch.placeholder": "Искать приложения, теги и заметки",
+ "quickSearch.inputAccessibility": "Поле быстрого поиска",
+ "quickSearch.emptyPrompt": "Начните вводить, чтобы искать приложения, теги и заметки.",
+ "quickSearch.noResults": "Приложения не найдены.",
+ "quickSearch.launchFailed": "Не удалось открыть это приложение. Повторите попытку или выберите другое приложение.",
+ "quickSearch.tagPrefix": "Тег",
+ "quickSearch.hotkeys": "Сочетания клавиш",
+ "quickSearch.mainHotkey": "Список приложений",
+ "quickSearch.mainHotkeyDesc": "Открывает список приложений TagLauncher.",
+ "quickSearch.status.Active": "Активно",
+ "quickSearch.status.registrationFailed": "Не удалось зарегистрировать",
+ "quickSearch.status.unavailable": "Сочетание недоступно",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% сейчас нельзя зарегистрировать. Возможно, оно используется macOS, методом ввода или другим приложением. Сочетание для списка приложений временно недоступно. Проверьте сочетания клавиш или конфликты, затем перезапустите TagLauncher. Код ошибки: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% сейчас нельзя зарегистрировать. Возможно, оно используется macOS, методом ввода или другим приложением. Глобальный быстрый поиск временно недоступен. Проверьте сочетания клавиш или конфликты, затем перезапустите TagLauncher. Код ошибки: %status%.",
+ "quickSearch.loading": "Подготовка поискового индекса…",
+ "quickSearch.internalHotkey": "Быстрый поиск (в TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Работает только когда открыт список приложений TagLauncher.",
+ "quickSearch.internalHotkeyStatus": "Только список приложений",
+ "quickSearch.globalHotkey": "Быстрый поиск (глобально)",
+ "quickSearch.globalHotkeyDesc": "Открывает быстрый поиск глобально, когда список приложений TagLauncher не виден.",
+ "quickSearch.spaceDisplay": "Space (пробел)",
"trackpadGesture.title": "Жест трекпада",
"trackpadGesture.description": "Назначьте жест трекпада в сторонней утилите на этот URL, чтобы открыть список приложений.",
"trackpadGesture.status": "Внешний инструмент",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Предварительный просмотр",
"pro.card.restore": "Восстановить покупки",
- "pro.card.summary.free": "Разблокируйте премиум-темы, импорт и экспорт макетов, неограниченное количество заметок и сохраненную сортировку приложений вручную.",
+ "pro.card.summary.free": "Откройте собственные цвета тегов, премиум-темы, импорт и экспорт макетов, неограниченные заметки к приложениям и свои сочетания клавиш.",
"pro.card.summary.legacy": "Спасибо за раннюю поддержку TagLauncher. Ваш доступ к Pro уже активен.",
- "pro.card.summary.unlocked": "Pro активен на этом Mac. Премиум-темы и расширенные инструменты макетирования готовы.",
+ "pro.card.summary.unlocked": "Pro активен на этом Mac. Собственные цвета тегов, расширенные темы, неограниченные заметки, свои сочетания клавиш и инструменты макета готовы.",
"pro.card.title.free": "Обновите до Pro",
"pro.card.title.legacy": "Pro разблокирован",
"pro.card.title.unlocked": "Pro разблокирован",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Сохраните текущие теги, порядок и макет в качестве резервной копии многократного использования.",
"pro.feature.import": "Импорт макета",
"pro.feature.import.benefit": "Восстановите сохраненный макет TagLauncher на этом Mac за один шаг.",
- "pro.feature.notes": "Неограниченное количество заметок",
- "pro.feature.notes.benefit": "Сохраняйте заметки для каждого приложения без бесплатного ограничения в 5 заметок.",
+ "pro.feature.notes": "Пользовательские заметки приложений",
+ "pro.feature.notes.benefit": "Бесплатная версия включает 3 заметки приложений. Pro открывает неограниченные заметки для всех приложений.",
"pro.feature.sorting": "Сортировка сохраненных приложений",
"pro.feature.sorting.benefit": "Сохраняйте порядок приложений вручную после выхода из режима редактирования.",
"pro.feature.themes": "Премиум темы",
"pro.feature.themes.benefit": "Разблокируйте все расширенные темы App Grid и сохраните их навсегда.",
- "pro.notes.limitReached": "Бесплатная версия может сохранять заметки для 5 приложений. Разблокируйте Pro, чтобы сохранять неограниченное количество заметок.",
+ "pro.notes.limitReached": "Бесплатная версия может сохранить до 3 заметок приложений. Откройте Pro для неограниченных заметок.",
"pro.notes.remaining": "Бесплатная версия включает в себя %limit% заметок приложения. Осталось %remaining%.",
"pro.operation.cancelled": "Покупка отменена.",
"pro.operation.loading": "Проверка доступа к Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Восстановление покупки…",
"pro.prompt.export": "Экспорт макетов — это функция Pro. Разблокируйте Pro, чтобы создавать резервные копии текущих тегов, порядка и макета.",
"pro.prompt.import": "Импорт макетов — это функция Pro. Разблокируйте Pro, чтобы восстановить сохраненный макет на этом Mac.",
- "pro.prompt.notes": "Неограниченное количество заметок приложений является частью Pro. Разблокируйте Pro, чтобы сохранять заметки для каждого приложения.",
+ "pro.prompt.notes": "Бесплатная версия может сохранить до 3 заметок приложений. Откройте Pro, чтобы сохранять заметки для всех приложений.",
"pro.prompt.sorting": "Сохраненная сортировка приложений вручную является частью Pro. Разблокируйте Pro, чтобы сохранить свой индивидуальный заказ.",
"pro.prompt.themes": "Эта тема является частью Pro. Разблокируйте Pro, чтобы продолжать использовать расширенные темы App Grid.",
"pro.purchase.failed": "Невозможно совершить покупку прямо сейчас. Пожалуйста, попробуйте еще раз.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Свои сочетания клавиш",
"pro.feature.customHotkeys.benefit": "Настройте глобальные сочетания для списка приложений и Quick Search.",
"pro.prompt.customHotkeys": "Свои сочетания клавиш входят в Pro. Откройте Pro, чтобы настроить их.",
- "hotkeys.customize": "Настроить",
+ "hotkeys.customize": "Изменить сочетание",
"hotkeys.restoreDefault": "Вернуть стандартное",
"hotkeys.recording": "Нажмите новое сочетание. Esc — отмена.",
"hotkeys.recordingInline": "Запись",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Эта клавиша не поддерживается.",
"hotkeys.error.reserved": "Это сочетание зарезервировано macOS или приложением.",
"hotkeys.error.duplicate": "Это сочетание уже используется другим действием TagLauncher.",
- "hotkeys.error.registrationFailed": "Не удалось зарегистрировать сочетание. Код ошибки: %status%."
+ "hotkeys.error.registrationFailed": "Не удалось зарегистрировать сочетание. Код ошибки: %status%.",
+ "pro.feature.customTagColors": "Собственные цвета тегов",
+ "pro.feature.customTagColors.benefit": "Задавайте любой цвет для каждого тега, включая системные категории SmartStart.",
+ "pro.prompt.customTagColors": "Собственные цвета тегов — функция Pro. Откройте Pro, чтобы назначать любому тегу любой цвет и легче различать категории.",
+ "settings.proStatus.freeUser": "Сейчас вы пользователь бесплатной версии",
+ "settings.proStatus.proUser": "Сейчас вы ценный пользователь 👑Pro",
+ "settings.proStatus.lockedListTitle": "Функции Pro для разблокировки",
+ "settings.proStatus.unlockedListTitle": "Разблокированные функции",
+ "settings.proStatus.lockedFeature": "✅ Поддерживается",
+ "settings.proStatus.unlockedFeature": "✅Открыто",
+ "settings.proStatus.freeNotes": "3 бесплатно",
+ "settings.proStatus.unlimitedNotes": "✅ Заметки без лимита",
+ "settings.proStatus.limitedFeature": "Ограничено",
+ "settings.proStatus.unsupportedFeature": "Не поддерживается",
+ "settings.proFeature.appNotes": "Пользовательские заметки приложений",
+ "settings.proFeature.dataBackup": "Импорт/экспорт данных и резервные копии макета",
+ "tag.customColor": "Свой цвет",
+ "settings.proBenefit.hotkeys": "Настраивайте свои сочетания клавиш для действий TagLauncher.",
+ "settings.proBenefit.tags": "Задавайте каждому тегу свой цвет, чтобы быстрее его узнавать.",
+ "settings.proBenefit.data": "Создавайте резервные копии, экспортируйте, импортируйте и восстанавливайте категории и макет.",
+ "settings.proBenefit.about": "Все преимущества Pro разблокированы на этом Mac.",
+ "settings.proBenefit.general": "На этом Mac доступны цветной контейнер и цветная сетка Pro.",
+ "settings.proGuide.hotkeys": "Стандартные сочетания доступны. Пользователи Pro могут настраивать свои сочетания.",
+ "settings.proGuide.tags": "Доступны 7 стандартных цветов. Пользователи Pro могут настраивать больше цветов.",
+ "settings.proGuide.data": "Пользователи Pro могут импортировать и экспортировать данные категорий и макета.",
+ "settings.proCompare.title": "Различия бесплатной версии и Pro",
+ "settings.proCompare.free": "Бесплатно",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Недоступно",
+ "settings.proStatus.previewFiveMinutes": "Только 5 минут предпросмотра",
+ "settings.proGuide.general": "Цветные контейнеры / сетки доступны только пользователям Pro"
}
diff --git a/src/Apptag/Localization/sr-Cyrl.json b/src/Apptag/Localization/sr-Cyrl.json
index 9318498..3e8dfc3 100644
--- a/src/Apptag/Localization/sr-Cyrl.json
+++ b/src/Apptag/Localization/sr-Cyrl.json
@@ -8,8 +8,8 @@
"menu.language": "Језик",
"menu.help": "Помоћ",
"menu.version": "Верзија",
- "menu.proStatus.free": "Тренутно сте корисник бесплатне верзије (надоградите на Pro)",
- "menu.proStatus.unlocked": "Тренутно сте цењени Pro корисник",
+ "menu.proStatus.free": "Тренутно сте корисник бесплатне верзије (надоградите сада на 👑Pro)",
+ "menu.proStatus.unlocked": "Тренутно сте цењени 👑Pro корисник",
"settings.language": "Језик",
"settings.languagePicker": "Језик апликације:",
"settings.languageDesc": "Изаберите језик менија и подешавања.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Нема резултата паметне класификације за примену.",
"scheme.local": "Локална шема",
"scheme.systemSmartStart": "Паметна почетна шема система",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Прикажи облачиће савета за:",
+ "settings.bubbleAllApps": "Све апликације",
+ "settings.bubbleUncommonOnly": "Само ретко коришћене апликације",
+ "quickSearch.title": "Брза претрага",
+ "quickSearch.placeholder": "Претражи апликације, ознаке и белешке",
+ "quickSearch.inputAccessibility": "Поље брзе претраге",
+ "quickSearch.emptyPrompt": "Почните да куцате да претражите апликације, ознаке и белешке.",
+ "quickSearch.noResults": "Нема пронађених апликација.",
+ "quickSearch.launchFailed": "Ову апликацију није могуће отворити. Покушајте поново или изаберите другу апликацију.",
+ "quickSearch.tagPrefix": "Ознака",
+ "quickSearch.hotkeys": "Пречице на тастатури",
+ "quickSearch.mainHotkey": "Листа апликација",
+ "quickSearch.mainHotkeyDesc": "Отвара TagLauncher листу апликација.",
+ "quickSearch.status.Active": "Активно",
+ "quickSearch.status.registrationFailed": "Регистрација није успела",
+ "quickSearch.status.unavailable": "Пречица није доступна",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% тренутно не може да се региструје. Можда је користе macOS, начин уноса или друга апликација. Пречица листе апликација је привремено недоступна. Проверите пречице на тастатури или сукобе пречица, па поново покрените TagLauncher. Код грешке: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% тренутно не може да се региструје. Можда је користе macOS, начин уноса или друга апликација. Глобална брза претрага је привремено недоступна. Проверите пречице на тастатури или сукобе пречица, па поново покрените TagLauncher. Код грешке: %status%.",
+ "quickSearch.loading": "Припрема индекса претраге…",
+ "quickSearch.internalHotkey": "Брза претрага (у TagLauncher-у)",
+ "quickSearch.internalHotkeyDesc": "Ради само док је TagLauncher листа апликација отворена.",
+ "quickSearch.internalHotkeyStatus": "Само листа апликација",
+ "quickSearch.globalHotkey": "Брза претрага (глобално)",
+ "quickSearch.globalHotkeyDesc": "Отвара глобалну брзу претрагу када TagLauncher листа апликација није видљива.",
+ "quickSearch.spaceDisplay": "Space (размакница)",
"trackpadGesture.title": "Гест на трекпеду",
"trackpadGesture.description": "Повежите гест на трекпеду у алату треће стране са овом URL адресом да бисте приказали листу апликација.",
"trackpadGesture.status": "Спољни алат",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Преглед",
"pro.card.restore": "Ресторе Пурцхасес",
- "pro.card.summary.free": "Откључајте премијум теме, увоз и извоз изгледа, неограничене белешке и сачувано ручно сортирање апликација.",
+ "pro.card.summary.free": "Откључајте прилагођене боје ознака, премијум теме, увоз и извоз распореда, неограничене белешке апликација и прилагођене пречице.",
"pro.card.summary.legacy": "Хвала што сте рано подржали TagLauncher. Ваш Pro приступ је већ активан.",
- "pro.card.summary.unlocked": "Pro је активан на овом Mac-у. Премиум теме и напредни алати за распоред су спремни.",
+ "pro.card.summary.unlocked": "Pro је активан на овом Mac-у. Прилагођене боје ознака, напредне теме, неограничене белешке, прилагођене пречице и алати распореда су спремни.",
"pro.card.title.free": "Надоградите на Pro",
"pro.card.title.legacy": "Pro откључан",
"pro.card.title.unlocked": "Pro откључан",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Сачувајте своје тренутне ознаке, редослед и изглед као резервну копију за вишекратну употребу.",
"pro.feature.import": "Увоз распореда",
"pro.feature.import.benefit": "Вратите сачувани изглед TagLauncher-а на овом Mac-у у једном кораку.",
- "pro.feature.notes": "Неограничене белешке",
- "pro.feature.notes.benefit": "Сачувајте белешке за сваку апликацију без бесплатног ограничења од 5 нота.",
+ "pro.feature.notes": "Прилагођене белешке апликација",
+ "pro.feature.notes.benefit": "Бесплатна верзија укључује 3 белешке апликација. Pro откључава неограничене белешке за све апликације.",
"pro.feature.sorting": "Сачувано сортирање апликација",
"pro.feature.sorting.benefit": "Задржите ручну наруџбу апликација након што напустите режим уређивања.",
"pro.feature.themes": "Премиум теме",
"pro.feature.themes.benefit": "Откључајте све напредне теме App Grid и задржите их трајно.",
- "pro.notes.limitReached": "Бесплатна верзија може да сачува белешке за до 5 апликација. Откључајте Pro да бисте сачували неограничене белешке.",
+ "pro.notes.limitReached": "Бесплатна верзија може да сачува до 3 белешке апликација. Откључајте Pro за неограничене белешке.",
"pro.notes.remaining": "Бесплатна верзија укључује %limit% белешки о апликацијама. Преостало је %remaining%.",
"pro.operation.cancelled": "Куповина је отказана.",
"pro.operation.loading": "Проверава се Pro приступ…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Враћање куповине…",
"pro.prompt.export": "Извоз распореда је Pro функција. Откључајте Pro да бисте направили резервну копију тренутних ознака, редоследа и изгледа.",
"pro.prompt.import": "Увоз распореда је Pro функција. Откључајте Pro да бисте вратили сачувани изглед на овом Mac-у.",
- "pro.prompt.notes": "Неограничене белешке о апликацијама су део Pro. Откључајте Pro да бисте сачували белешке за сваку апликацију.",
+ "pro.prompt.notes": "Бесплатна верзија може да сачува до 3 белешке апликација. Откључајте Pro да чувате белешке за све апликације.",
"pro.prompt.sorting": "Сачувано ручно сортирање апликација је део Pro. Откључајте Pro да бисте задржали свој прилагођени редослед.",
"pro.prompt.themes": "Ова тема је део Pro. Откључајте Pro да бисте наставили да користите напредне теме App Grid.",
"pro.purchase.failed": "Тренутно није могуће довршити куповину. Покушајте поново.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Прилагођене пречице",
"pro.feature.customHotkeys.benefit": "Подесите глобалне пречице за листу апликација и Quick Search.",
"pro.prompt.customHotkeys": "Прилагођене пречице су Pro функција. Откључајте Pro да их подесите.",
- "hotkeys.customize": "Прилагоди",
+ "hotkeys.customize": "Промени пречицу",
"hotkeys.restoreDefault": "Врати подразумевано",
"hotkeys.recording": "Притисните нову пречицу. Esc отказује.",
"hotkeys.recordingInline": "Снимање",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Овај тастер није подржан.",
"hotkeys.error.reserved": "Ова пречица је резервисана од macOS-а или апликације.",
"hotkeys.error.duplicate": "Ова пречица већ припада другој TagLauncher радњи.",
- "hotkeys.error.registrationFailed": "Пречица није могла да се региструје. Код грешке: %status%."
+ "hotkeys.error.registrationFailed": "Пречица није могла да се региструје. Код грешке: %status%.",
+ "pro.feature.customTagColors": "Прилагођене боје ознака",
+ "pro.feature.customTagColors.benefit": "Подесите било коју боју за сваку ознаку, укључујући SmartStart системске категорије.",
+ "pro.prompt.customTagColors": "Прилагођене боје ознака су Pro функција. Откључајте Pro да свакој ознаци дате било коју боју и лакше препознате категорије.",
+ "settings.proStatus.freeUser": "Тренутно сте корисник бесплатне верзије",
+ "settings.proStatus.proUser": "Тренутно сте цењени 👑Pro корисник",
+ "settings.proStatus.lockedListTitle": "Pro функције за откључавање",
+ "settings.proStatus.unlockedListTitle": "Откључане функције",
+ "settings.proStatus.lockedFeature": "✅ Подржано",
+ "settings.proStatus.unlockedFeature": "✅Откључано",
+ "settings.proStatus.freeNotes": "3 бесплатно",
+ "settings.proStatus.unlimitedNotes": "✅ Неограничене белешке",
+ "settings.proStatus.limitedFeature": "Ограничено",
+ "settings.proStatus.unsupportedFeature": "Није подржано",
+ "settings.proFeature.appNotes": "Прилагођене белешке апликација",
+ "settings.proFeature.dataBackup": "Увоз/извоз података и резерве распореда",
+ "tag.customColor": "Прилагођена боја",
+ "settings.proBenefit.hotkeys": "Подесите своје пречице за TagLauncher радње.",
+ "settings.proBenefit.tags": "Дајте свакој ознаци прилагођену боју за брже препознавање.",
+ "settings.proBenefit.data": "Правите резерве, извозите, увозите и враћајте категорије и распоред.",
+ "settings.proBenefit.about": "Све Pro погодности су откључане на овом Mac-у.",
+ "settings.proBenefit.general": "Pro контејнер у боји и мрежа у боји доступни су на овом Mac-у.",
+ "settings.proGuide.hotkeys": "Подразумеване пречице су доступне. Pro корисници могу да прилагоде пречице.",
+ "settings.proGuide.tags": "Доступно је 7 подразумеваних боја. Pro корисници могу да прилагоде више боја.",
+ "settings.proGuide.data": "Pro корисници могу да увозе и извозе податке категорија и распореда.",
+ "settings.proCompare.title": "Разлике између бесплатног и Pro",
+ "settings.proCompare.free": "Бесплатно",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Недоступно",
+ "settings.proStatus.previewFiveMinutes": "Само 5 минута прегледа",
+ "settings.proGuide.general": "Само Pro корисници могу да користе обојене контејнере / мреже"
}
diff --git a/src/Apptag/Localization/sv.json b/src/Apptag/Localization/sv.json
index 4a6efde..b51c235 100644
--- a/src/Apptag/Localization/sv.json
+++ b/src/Apptag/Localization/sv.json
@@ -8,8 +8,8 @@
"menu.language": "Språk",
"menu.help": "Hjälp",
"menu.version": "Version",
- "menu.proStatus.free": "Du är för närvarande gratisanvändare (uppgradera till Pro)",
- "menu.proStatus.unlocked": "Du är för närvarande en uppskattad Pro-användare",
+ "menu.proStatus.free": "Du är för närvarande gratisanvändare (uppgradera nu till 👑Pro)",
+ "menu.proStatus.unlocked": "Du är för närvarande en uppskattad 👑Pro-användare",
"settings.language": "Språk",
"settings.languagePicker": "Appspråk:",
"settings.languageDesc": "Välj språket som används i menyer och inställningar.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Inga smarta klassificeringsresultat kunde tillämpas.",
"scheme.local": "Lokalt schema",
"scheme.systemSmartStart": "Systemets smarta startschema",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Visa bubbelips för:",
+ "settings.bubbleAllApps": "Alla appar",
+ "settings.bubbleUncommonOnly": "Endast sällan använda appar",
+ "quickSearch.title": "Snabbsökning",
+ "quickSearch.placeholder": "Sök appar, taggar och anteckningar",
+ "quickSearch.inputAccessibility": "Inmatning för snabbsökning",
+ "quickSearch.emptyPrompt": "Börja skriva för att söka appar, taggar och anteckningar.",
+ "quickSearch.noResults": "Inga appar hittades.",
+ "quickSearch.launchFailed": "Det gick inte att öppna appen. Försök igen eller välj en annan app.",
+ "quickSearch.tagPrefix": "Tagg",
+ "quickSearch.hotkeys": "Kortkommandon",
+ "quickSearch.mainHotkey": "Applista",
+ "quickSearch.mainHotkeyDesc": "Öppnar TagLauncher-applistan.",
+ "quickSearch.status.Active": "Aktiv",
+ "quickSearch.status.registrationFailed": "Registrering misslyckades",
+ "quickSearch.status.unavailable": "Kortkommando inte tillgängligt",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% kan inte registreras just nu. Det kan användas av macOS, en inmatningsmetod eller en annan app. Kortkommandot för applistan är tillfälligt otillgängligt. Kontrollera kortkommandon eller konflikter och starta om TagLauncher. Felkod: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% kan inte registreras just nu. Det kan användas av macOS, en inmatningsmetod eller en annan app. Global snabbsökning är tillfälligt otillgänglig. Kontrollera kortkommandon eller konflikter och starta om TagLauncher. Felkod: %status%.",
+ "quickSearch.loading": "Förbereder sökindex…",
+ "quickSearch.internalHotkey": "Snabbsökning (i TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Fungerar bara när TagLauncher-applistan är öppen.",
+ "quickSearch.internalHotkeyStatus": "Endast applista",
+ "quickSearch.globalHotkey": "Snabbsökning (global)",
+ "quickSearch.globalHotkeyDesc": "Öppna snabbsökning globalt när TagLauncher-applistan inte visas.",
+ "quickSearch.spaceDisplay": "Space (mellanslag)",
"trackpadGesture.title": "Styrplattegest",
"trackpadGesture.description": "Koppla en styrplattegest i ett tredjepartsverktyg till denna URL för att visa applistan.",
"trackpadGesture.status": "Externt verktyg",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Förhandsvisning",
"pro.card.restore": "Återställ inköp",
- "pro.card.summary.free": "Lås upp premiumteman, layoutimport och export, obegränsat antal anteckningar och sparad manuell appsortering.",
+ "pro.card.summary.free": "Lås upp egna taggfärger, premiumteman, import och export av layout, obegränsade appanteckningar och egna kortkommandon.",
"pro.card.summary.legacy": "Tack för att du stödde TagLauncher tidigt. Din Pro-åtkomst är redan aktiv.",
- "pro.card.summary.unlocked": "Pro är aktiv på denna Mac. Premiumteman och avancerade layoutverktyg är klara.",
+ "pro.card.summary.unlocked": "Pro är aktivt på denna Mac. Egna taggfärger, avancerade teman, obegränsade anteckningar, egna kortkommandon och layoutverktyg är redo.",
"pro.card.title.free": "Uppgradera till Pro",
"pro.card.title.legacy": "Pro upplåst",
"pro.card.title.unlocked": "Pro upplåst",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Spara dina nuvarande taggar, beställning och layout som en återanvändbar backup.",
"pro.feature.import": "Layoutimport",
"pro.feature.import.benefit": "Återställ en sparad TagLauncher layout på denna Mac i ett steg.",
- "pro.feature.notes": "Obegränsade anteckningar",
- "pro.feature.notes.benefit": "Spara anteckningar för varje app utan den kostnadsfria gränsen på 5 noter.",
+ "pro.feature.notes": "Egna appanteckningar",
+ "pro.feature.notes.benefit": "Gratisversionen innehåller 3 appanteckningar. Pro låser upp obegränsade anteckningar för alla appar.",
"pro.feature.sorting": "Sparad appsortering",
"pro.feature.sorting.benefit": "Behåll din manuella appordning efter att du lämnat redigeringsläget.",
"pro.feature.themes": "Premium-teman",
"pro.feature.themes.benefit": "Lås upp alla avancerade App Grid-tema och behåll dem permanent.",
- "pro.notes.limitReached": "Gratisversionen kan spara anteckningar för upp till 5 appar. Lås upp Pro för att spara obegränsade anteckningar.",
+ "pro.notes.limitReached": "Gratisversionen kan spara upp till 3 appanteckningar. Lås upp Pro för obegränsade anteckningar.",
"pro.notes.remaining": "Gratisversionen inkluderar %limit% appanteckningar. %remaining% återstår.",
"pro.operation.cancelled": "Köpet annullerats.",
"pro.operation.loading": "Kontrollerar åtkomst till Pro...",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Återställer köp...",
"pro.prompt.export": "Layoutexport är en Pro-funktion. Lås upp Pro för att säkerhetskopiera dina nuvarande taggar, beställning och layout.",
"pro.prompt.import": "Layoutimport är en Pro-funktion. Lås upp Pro för att återställa en sparad layout på denna Mac.",
- "pro.prompt.notes": "Obegränsade appanteckningar är en del av Pro. Lås upp Pro för att spara anteckningar för varje app.",
+ "pro.prompt.notes": "Gratisversionen kan spara upp till 3 appanteckningar. Lås upp Pro för att spara anteckningar för alla appar.",
"pro.prompt.sorting": "Sparad manuell appsortering är en del av Pro. Lås upp Pro för att behålla din anpassade ordning.",
"pro.prompt.themes": "Detta tema är en del av Pro. Lås upp Pro för att fortsätta använda avancerade App Grid-teman.",
"pro.purchase.failed": "Det går inte att slutföra köpet just nu. Försök igen.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Egna kortkommandon",
"pro.feature.customHotkeys.benefit": "Ställ in globala kortkommandon för applistan och Quick Search.",
"pro.prompt.customHotkeys": "Egna kortkommandon ingår i Pro. Lås upp Pro för att ställa in dem.",
- "hotkeys.customize": "Anpassa",
+ "hotkeys.customize": "Ändra kortkommando",
"hotkeys.restoreDefault": "Återställ standard",
"hotkeys.recording": "Tryck på det nya kortkommandot nu. Esc avbryter.",
"hotkeys.recordingInline": "Spelar in",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Den här tangenten stöds inte.",
"hotkeys.error.reserved": "Det här kortkommandot är reserverat av macOS eller appen.",
"hotkeys.error.duplicate": "Det här kortkommandot används redan av en annan TagLauncher-åtgärd.",
- "hotkeys.error.registrationFailed": "Kortkommandot kunde inte registreras. Felkod: %status%."
+ "hotkeys.error.registrationFailed": "Kortkommandot kunde inte registreras. Felkod: %status%.",
+ "pro.feature.customTagColors": "Egna taggfärger",
+ "pro.feature.customTagColors.benefit": "Ange valfri färg för varje tagg, inklusive SmartStart-systemkategorier.",
+ "pro.prompt.customTagColors": "Egna taggfärger är en Pro-funktion. Lås upp Pro för att ge varje tagg valfri färg och göra kategorier lättare att känna igen.",
+ "settings.proStatus.freeUser": "Du är för närvarande gratisanvändare",
+ "settings.proStatus.proUser": "Du är för närvarande en uppskattad 👑Pro-användare",
+ "settings.proStatus.lockedListTitle": "Pro-funktioner att låsa upp",
+ "settings.proStatus.unlockedListTitle": "Upplåsta funktioner",
+ "settings.proStatus.lockedFeature": "✅ Stöds",
+ "settings.proStatus.unlockedFeature": "✅Upplåst",
+ "settings.proStatus.freeNotes": "3 gratis",
+ "settings.proStatus.unlimitedNotes": "✅ Obegränsade anteckningar",
+ "settings.proStatus.limitedFeature": "Begränsat",
+ "settings.proStatus.unsupportedFeature": "Stöds inte",
+ "settings.proFeature.appNotes": "Egna appanteckningar",
+ "settings.proFeature.dataBackup": "Dataimport/-export och layoutbackuper",
+ "tag.customColor": "Egen färg",
+ "settings.proBenefit.hotkeys": "Ställ in egna kortkommandon för TagLauncher-åtgärder.",
+ "settings.proBenefit.tags": "Ge varje tagg en egen färg så att du känner igen den snabbare.",
+ "settings.proBenefit.data": "Säkerhetskopiera, exportera, importera och återställ kategorier och layout.",
+ "settings.proBenefit.about": "Alla Pro-fördelar är upplåsta på denna Mac.",
+ "settings.proBenefit.general": "Pro-färgbehållare och färgrutnät är tillgängliga på denna Mac.",
+ "settings.proGuide.hotkeys": "Standardgenvägar är tillgängliga. Pro-användare kan anpassa genvägar.",
+ "settings.proGuide.tags": "7 standardfärger är tillgängliga. Pro-användare kan anpassa fler färger.",
+ "settings.proGuide.data": "Pro-användare kan importera och exportera kategori- och layoutdata.",
+ "settings.proCompare.title": "Skillnader mellan gratis och Pro",
+ "settings.proCompare.free": "Gratis",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Inte tillgängligt",
+ "settings.proStatus.previewFiveMinutes": "Endast 5 minuters förhandsvisning",
+ "settings.proGuide.general": "Endast Pro-användare kan använda färgade behållare / rutnät"
}
diff --git a/src/Apptag/Localization/th.json b/src/Apptag/Localization/th.json
index 112c479..3923975 100644
--- a/src/Apptag/Localization/th.json
+++ b/src/Apptag/Localization/th.json
@@ -8,8 +8,8 @@
"menu.language": "ภาษา",
"menu.help": "ช่วยเหลือ",
"menu.version": "เวอร์ชัน",
- "menu.proStatus.free": "ตอนนี้คุณเป็นผู้ใช้ฟรี (อัปเกรดเป็น Pro)",
- "menu.proStatus.unlocked": "ตอนนี้คุณเป็นผู้ใช้ Pro ระดับพิเศษ",
+ "menu.proStatus.free": "ตอนนี้คุณเป็นผู้ใช้ฟรี (อัปเกรดเป็น 👑Pro ตอนนี้)",
+ "menu.proStatus.unlocked": "ตอนนี้คุณเป็นผู้ใช้ 👑Pro ระดับพิเศษ",
"settings.language": "ภาษา",
"settings.languagePicker": "ภาษาของแอป:",
"settings.languageDesc": "เลือกภาษาที่ใช้ในเมนูและการตั้งค่า",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "ไม่มีผลการจัดหมวดหมู่อัจฉริยะให้ใช้",
"scheme.local": "ชุดภายในเครื่อง",
"scheme.systemSmartStart": "ชุดเริ่มต้นอัจฉริยะของระบบ",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "แสดงคำแนะนำแบบฟองสำหรับ:",
+ "settings.bubbleAllApps": "แอปทั้งหมด",
+ "settings.bubbleUncommonOnly": "เฉพาะแอปที่ใช้น้อย",
+ "quickSearch.title": "ค้นหาอย่างรวดเร็ว",
+ "quickSearch.placeholder": "ค้นหาแอป แท็ก และบันทึก",
+ "quickSearch.inputAccessibility": "ช่องค้นหาอย่างรวดเร็ว",
+ "quickSearch.emptyPrompt": "เริ่มพิมพ์เพื่อค้นหาแอป แท็ก และบันทึก",
+ "quickSearch.noResults": "ไม่พบแอป",
+ "quickSearch.launchFailed": "ไม่สามารถเปิดแอปนี้ได้ ลองอีกครั้งหรือเลือกแอปอื่น",
+ "quickSearch.tagPrefix": "แท็ก",
+ "quickSearch.hotkeys": "แป้นพิมพ์ลัด",
+ "quickSearch.mainHotkey": "รายการแอป",
+ "quickSearch.mainHotkeyDesc": "เปิดรายการแอปของ TagLauncher",
+ "quickSearch.status.Active": "เปิดใช้งาน",
+ "quickSearch.status.registrationFailed": "ลงทะเบียนไม่สำเร็จ",
+ "quickSearch.status.unavailable": "ปุ่มลัดไม่พร้อมใช้งาน",
+ "quickSearch.mainHotkeyUnavailableMessage": "ไม่สามารถลงทะเบียน %shortcut% ได้ในขณะนี้ อาจถูกใช้โดย macOS วิธีป้อนข้อมูล หรือแอปอื่น ปุ่มลัดรายการแอปไม่พร้อมใช้งานชั่วคราว ตรวจสอบแป้นพิมพ์ลัดหรือความขัดแย้งของปุ่มลัด แล้วเริ่ม TagLauncher ใหม่ รหัสข้อผิดพลาด: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "ไม่สามารถลงทะเบียน %shortcut% ได้ในขณะนี้ อาจถูกใช้โดย macOS วิธีป้อนข้อมูล หรือแอปอื่น การค้นหาอย่างรวดเร็วแบบทั่วระบบไม่พร้อมใช้งานชั่วคราว ตรวจสอบแป้นพิมพ์ลัดหรือความขัดแย้งของปุ่มลัด แล้วเริ่ม TagLauncher ใหม่ รหัสข้อผิดพลาด: %status%.",
+ "quickSearch.loading": "กำลังเตรียมดัชนีค้นหา…",
+ "quickSearch.internalHotkey": "ค้นหาอย่างรวดเร็ว (ภายใน TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "ทำงานเฉพาะเมื่อรายการแอป TagLauncher เปิดอยู่",
+ "quickSearch.internalHotkeyStatus": "เฉพาะรายการแอป",
+ "quickSearch.globalHotkey": "ค้นหาอย่างรวดเร็ว (ทั่วระบบ)",
+ "quickSearch.globalHotkeyDesc": "เปิดการค้นหาอย่างรวดเร็วทั่วระบบเมื่อรายการแอป TagLauncher ไม่แสดงอยู่",
+ "quickSearch.spaceDisplay": "Space (แป้นเว้นวรรค)",
"trackpadGesture.title": "ท่าทางแทร็คแพด",
"trackpadGesture.description": "จับคู่ท่าทางแทร็คแพดในเครื่องมือภายนอกกับ URL นี้เพื่อแสดงรายการแอป",
"trackpadGesture.status": "เครื่องมือภายนอก",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "ดูตัวอย่าง",
"pro.card.restore": "กู้คืนการซื้อ",
- "pro.card.summary.free": "ปลดล็อกธีมพรีเมียม นำเข้าและส่งออกเลย์เอาต์ บันทึกย่อไม่จำกัด และการจัดเรียงแอปที่บันทึกไว้ด้วยตนเอง",
+ "pro.card.summary.free": "ปลดล็อกสีแท็กแบบกำหนดเอง ธีมพรีเมียม การนำเข้า/ส่งออกเลย์เอาต์ โน้ตแอปไม่จำกัด และปุ่มลัดแบบกำหนดเอง",
"pro.card.summary.legacy": "ขอขอบคุณที่สนับสนุน TagLauncher ก่อนกำหนด การเข้าถึง Pro ของคุณเปิดใช้งานแล้ว",
- "pro.card.summary.unlocked": "Pro ใช้งานอยู่ใน Mac นี้ ธีมพรีเมียมและเครื่องมือเค้าโครงขั้นสูงพร้อมแล้ว",
+ "pro.card.summary.unlocked": "Pro เปิดใช้งานบน Mac เครื่องนี้แล้ว สีแท็กแบบกำหนดเอง ธีมขั้นสูง โน้ตไม่จำกัด ปุ่มลัดแบบกำหนดเอง และเครื่องมือเลย์เอาต์พร้อมใช้",
"pro.card.title.free": "อัปเกรดเป็น Pro",
"pro.card.title.legacy": "Pro ปลดล็อคแล้ว",
"pro.card.title.unlocked": "Pro ปลดล็อคแล้ว",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "บันทึกแท็ก ลำดับ และเลย์เอาต์ปัจจุบันของคุณเป็นข้อมูลสำรองที่นำมาใช้ซ้ำได้",
"pro.feature.import": "นำเข้าเค้าโครง",
"pro.feature.import.benefit": "กู้คืนเค้าโครง TagLauncher ที่บันทึกไว้บน Mac นี้ในขั้นตอนเดียว",
- "pro.feature.notes": "บันทึกไม่จำกัด",
- "pro.feature.notes.benefit": "บันทึกโน้ตสำหรับทุกแอปโดยไม่มีขีดจำกัด 5 โน้ตฟรี",
+ "pro.feature.notes": "โน้ตแอปแบบกำหนดเอง",
+ "pro.feature.notes.benefit": "เวอร์ชันฟรีมีโน้ตแอป 3 รายการ Pro ปลดล็อกโน้ตไม่จำกัดสำหรับทุกแอป",
"pro.feature.sorting": "การจัดเรียงแอปที่บันทึกไว้",
"pro.feature.sorting.benefit": "เก็บลำดับแอปที่คุณกำหนดเองไว้หลังจากออกจากโหมดแก้ไข",
"pro.feature.themes": "ธีมพรีเมียม",
"pro.feature.themes.benefit": "ปลดล็อกธีม App Grid ขั้นสูงทุกอันและเก็บไว้อย่างถาวร",
- "pro.notes.limitReached": "เวอร์ชันฟรีสามารถบันทึกโน้ตได้สูงสุด 5 แอป ปลดล็อก Pro เพื่อบันทึกโน้ตได้ไม่จำกัด",
+ "pro.notes.limitReached": "เวอร์ชันฟรีบันทึกโน้ตแอปได้สูงสุด 3 รายการ ปลดล็อก Pro เพื่อบันทึกได้ไม่จำกัด",
"pro.notes.remaining": "เวอร์ชันฟรีมีบันทึกย่อของแอป %limit% รายการ เหลือ %remaining% รายการ",
"pro.operation.cancelled": "การซื้อถูกยกเลิก",
"pro.operation.loading": "กำลังตรวจสอบการเข้าถึง Pro...",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "กำลังกู้คืนการซื้อ...",
"pro.prompt.export": "การส่งออกเลย์เอาต์เป็นคุณสมบัติ Pro ปลดล็อก Pro เพื่อสำรองแท็ก ลำดับ และเลย์เอาต์ปัจจุบันของคุณ",
"pro.prompt.import": "การนำเข้าเค้าโครงเป็นคุณลักษณะ Pro ปลดล็อก Pro เพื่อคืนค่าเค้าโครงที่บันทึกไว้ใน Mac นี้",
- "pro.prompt.notes": "บันทึกแอปไม่จำกัดเป็นส่วนหนึ่งของ Pro ปลดล็อก Pro เพื่อบันทึกโน้ตสำหรับทุกแอป",
+ "pro.prompt.notes": "เวอร์ชันฟรีบันทึกโน้ตแอปได้สูงสุด 3 รายการ ปลดล็อก Pro เพื่อบันทึกโน้ตให้ทุกแอป",
"pro.prompt.sorting": "การเรียงลำดับแอปด้วยตนเองที่บันทึกไว้เป็นส่วนหนึ่งของ Pro ปลดล็อก Pro เพื่อรักษาคำสั่งซื้อที่คุณกำหนดเอง",
"pro.prompt.themes": "ธีมนี้เป็นส่วนหนึ่งของ Pro ปลดล็อก Pro เพื่อใช้ธีม App Grid ขั้นสูงต่อไป",
"pro.purchase.failed": "ไม่สามารถดำเนินการซื้อให้เสร็จสิ้นได้ในขณะนี้ โปรดลองอีกครั้ง",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "ปุ่มลัดกำหนดเอง",
"pro.feature.customHotkeys.benefit": "ตั้งปุ่มลัดส่วนกลางสำหรับรายการแอปและ Quick Search",
"pro.prompt.customHotkeys": "ปุ่มลัดกำหนดเองเป็นฟีเจอร์ Pro ปลดล็อก Pro เพื่อตั้งค่าได้",
- "hotkeys.customize": "กำหนดเอง",
+ "hotkeys.customize": "เปลี่ยนปุ่มลัด",
"hotkeys.restoreDefault": "คืนค่าเริ่มต้น",
"hotkeys.recording": "กดปุ่มลัดใหม่ตอนนี้ กด Esc เพื่อยกเลิก",
"hotkeys.recordingInline": "กำลังบันทึก",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "ไม่รองรับปุ่มนี้",
"hotkeys.error.reserved": "ปุ่มลัดนี้ถูกสงวนไว้โดย macOS หรือแอป",
"hotkeys.error.duplicate": "ปุ่มลัดนี้ถูกใช้กับการทำงานอื่นของ TagLauncher แล้ว",
- "hotkeys.error.registrationFailed": "ไม่สามารถลงทะเบียนปุ่มลัดได้ รหัสข้อผิดพลาด: %status%"
+ "hotkeys.error.registrationFailed": "ไม่สามารถลงทะเบียนปุ่มลัดได้ รหัสข้อผิดพลาด: %status%",
+ "pro.feature.customTagColors": "สีแท็กแบบกำหนดเอง",
+ "pro.feature.customTagColors.benefit": "ตั้งค่าสีใดก็ได้ให้ทุกแท็ก รวมถึงแท็กหมวดหมู่ระบบ SmartStart",
+ "pro.prompt.customTagColors": "สีแท็กแบบกำหนดเองเป็นฟีเจอร์ Pro ปลดล็อก Pro เพื่อให้ทุกแท็กใช้สีใดก็ได้และแยกหมวดหมู่ได้ง่ายขึ้น",
+ "settings.proStatus.freeUser": "ตอนนี้คุณเป็นผู้ใช้ฟรี",
+ "settings.proStatus.proUser": "ตอนนี้คุณเป็นผู้ใช้ 👑Pro ระดับพิเศษ",
+ "settings.proStatus.lockedListTitle": "ฟีเจอร์ Pro ที่รอปลดล็อก",
+ "settings.proStatus.unlockedListTitle": "ฟีเจอร์ที่ปลดล็อกแล้ว",
+ "settings.proStatus.lockedFeature": "✅ รองรับ",
+ "settings.proStatus.unlockedFeature": "✅ปลดล็อกแล้ว",
+ "settings.proStatus.freeNotes": "ฟรี 3 รายการ",
+ "settings.proStatus.unlimitedNotes": "✅ โน้ตไม่จำกัด",
+ "settings.proStatus.limitedFeature": "จำกัด",
+ "settings.proStatus.unsupportedFeature": "ไม่รองรับ",
+ "settings.proFeature.appNotes": "โน้ตแอปแบบกำหนดเอง",
+ "settings.proFeature.dataBackup": "นำเข้า/ส่งออกข้อมูลและสำรองเลย์เอาต์",
+ "tag.customColor": "สีแบบกำหนดเอง",
+ "settings.proBenefit.hotkeys": "ตั้งค่าปุ่มลัดของคุณเองสำหรับการทำงานของ TagLauncher",
+ "settings.proBenefit.tags": "ให้แต่ละแท็กมีสีแบบกำหนดเองเพื่อจดจำได้เร็วขึ้น",
+ "settings.proBenefit.data": "สำรอง ส่งออก นำเข้า และกู้คืนหมวดหมู่กับเลย์เอาต์",
+ "settings.proBenefit.about": "สิทธิประโยชน์ Pro ทั้งหมดปลดล็อกบน Mac เครื่องนี้แล้ว",
+ "settings.proBenefit.general": "คอนเทนเนอร์สีและตารางสี Pro พร้อมใช้งานบน Mac เครื่องนี้",
+ "settings.proGuide.hotkeys": "ใช้ปุ่มลัดเริ่มต้นได้ ผู้ใช้ Pro สามารถปรับแต่งปุ่มลัดได้",
+ "settings.proGuide.tags": "มีสีเริ่มต้น 7 สี ผู้ใช้ Pro สามารถปรับแต่งสีเพิ่มเติมได้",
+ "settings.proGuide.data": "ผู้ใช้ Pro สามารถนำเข้าและส่งออกข้อมูลหมวดหมู่กับเลย์เอาต์ได้",
+ "settings.proCompare.title": "ความแตกต่างระหว่างฟรีและ Pro",
+ "settings.proCompare.free": "ฟรี",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "ใช้งานไม่ได้",
+ "settings.proStatus.previewFiveMinutes": "ทดลองใช้ฟรีได้เพียง 5 นาที",
+ "settings.proGuide.general": "เฉพาะผู้ใช้ Pro เท่านั้นที่ใช้คอนเทนเนอร์ / กริดสีได้"
}
diff --git a/src/Apptag/Localization/tr.json b/src/Apptag/Localization/tr.json
index 69f60f0..a141bc5 100644
--- a/src/Apptag/Localization/tr.json
+++ b/src/Apptag/Localization/tr.json
@@ -8,8 +8,8 @@
"menu.language": "Dil",
"menu.help": "Yardım",
"menu.version": "Sürüm",
- "menu.proStatus.free": "Şu anda ücretsiz kullanıcısınız (Pro’ya yükseltin)",
- "menu.proStatus.unlocked": "Şu anda değerli bir Pro kullanıcısınız",
+ "menu.proStatus.free": "Şu anda ücretsiz kullanıcısınız (şimdi 👑Pro’ya yükseltin)",
+ "menu.proStatus.unlocked": "Şu anda değerli bir 👑Pro kullanıcısısınız",
"settings.language": "Dil",
"settings.languagePicker": "Uygulama dili:",
"settings.languageDesc": "Menülerde ve ayarlarda kullanılan dili seçin.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Uygulanacak akıllı sınıflandırma sonucu yok.",
"scheme.local": "Yerel şema",
"scheme.systemSmartStart": "Sistem akıllı başlangıç şeması",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Baloncuk ipuçları şunlar için gösterilsin:",
+ "settings.bubbleAllApps": "Tüm uygulamalar",
+ "settings.bubbleUncommonOnly": "Yalnızca az kullanılan uygulamalar",
+ "quickSearch.title": "Hızlı arama",
+ "quickSearch.placeholder": "Uygulama, etiket ve not ara",
+ "quickSearch.inputAccessibility": "Hızlı arama girişi",
+ "quickSearch.emptyPrompt": "Uygulamaları, etiketleri ve notları aramak için yazmaya başlayın.",
+ "quickSearch.noResults": "Uygulama bulunamadı.",
+ "quickSearch.launchFailed": "Bu uygulama açılamadı. Yeniden deneyin veya başka bir uygulama seçin.",
+ "quickSearch.tagPrefix": "Etiket",
+ "quickSearch.hotkeys": "Klavye kısayolları",
+ "quickSearch.mainHotkey": "Uygulama listesi",
+ "quickSearch.mainHotkeyDesc": "TagLauncher uygulama listesini açar.",
+ "quickSearch.status.Active": "Etkin",
+ "quickSearch.status.registrationFailed": "Kaydetme başarısız",
+ "quickSearch.status.unavailable": "Kısayol kullanılamıyor",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% şu anda kaydedilemiyor. macOS, bir giriş yöntemi veya başka bir uygulama tarafından kullanılıyor olabilir. Uygulama listesi kısayolu geçici olarak kullanılamıyor. Klavye kısayollarını veya kısayol çakışmalarını kontrol edip TagLauncher’ı yeniden başlatın. Hata kodu: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% şu anda kaydedilemiyor. macOS, bir giriş yöntemi veya başka bir uygulama tarafından kullanılıyor olabilir. Genel hızlı arama geçici olarak kullanılamıyor. Klavye kısayollarını veya kısayol çakışmalarını kontrol edip TagLauncher’ı yeniden başlatın. Hata kodu: %status%.",
+ "quickSearch.loading": "Arama dizini hazırlanıyor…",
+ "quickSearch.internalHotkey": "Hızlı arama (TagLauncher içinde)",
+ "quickSearch.internalHotkeyDesc": "Yalnızca TagLauncher uygulama listesi açıkken çalışır.",
+ "quickSearch.internalHotkeyStatus": "Yalnızca uygulama listesi",
+ "quickSearch.globalHotkey": "Hızlı arama (genel)",
+ "quickSearch.globalHotkeyDesc": "TagLauncher uygulama listesi görünür değilken genel hızlı aramayı açar.",
+ "quickSearch.spaceDisplay": "Space (boşluk tuşu)",
"trackpadGesture.title": "İzleme dörtgeni hareketi",
"trackpadGesture.description": "Uygulama listesini göstermek için üçüncü taraf bir araçta izleme dörtgeni hareketini bu URL’ye bağlayın.",
"trackpadGesture.status": "Harici araç",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Önizleme",
"pro.card.restore": "Satın Alımları Geri Yükle",
- "pro.card.summary.free": "Premium temaların, düzenin içe ve dışa aktarımının, sınırsız notların ve kaydedilmiş manuel uygulama sıralamasının kilidini açın.",
+ "pro.card.summary.free": "Özel etiket renklerini, premium temaları, düzen içe/dışa aktarmayı, sınırsız uygulama notlarını ve özel kısayolları açın.",
"pro.card.summary.legacy": "TagLauncher'ı erkenden desteklediğiniz için teşekkürler. Pro erişiminiz zaten etkin.",
- "pro.card.summary.unlocked": "Pro bu Mac üzerinde aktif. Premium temalar ve gelişmiş düzen araçları hazır.",
+ "pro.card.summary.unlocked": "Pro bu Mac’te etkin. Özel etiket renkleri, gelişmiş temalar, sınırsız notlar, özel kısayollar ve düzen araçları hazır.",
"pro.card.title.free": "Pro'ya yükseltin",
"pro.card.title.legacy": "Pro kilidi açıldı",
"pro.card.title.unlocked": "Pro kilidi açıldı",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Mevcut etiketlerinizi, sıranızı ve düzeninizi yeniden kullanılabilir bir yedek olarak kaydedin.",
"pro.feature.import": "Düzeni içe aktarma",
"pro.feature.import.benefit": "Bu Mac üzerinde kaydedilmiş bir TagLauncher düzenini tek adımda geri yükleyin.",
- "pro.feature.notes": "Sınırsız notlar",
- "pro.feature.notes.benefit": "Ücretsiz 5 nota sınırı olmadan her uygulama için not kaydedin.",
+ "pro.feature.notes": "Özel uygulama notları",
+ "pro.feature.notes.benefit": "Ücretsiz sürüm 3 uygulama notu içerir. Pro tüm uygulamalar için sınırsız not açar.",
"pro.feature.sorting": "Kayıtlı uygulama sıralaması",
"pro.feature.sorting.benefit": "Düzenleme modundan çıktıktan sonra manuel uygulama sıranızı koruyun.",
"pro.feature.themes": "Premium temalar",
"pro.feature.themes.benefit": "Tüm gelişmiş App Grid temalarının kilidini açın ve onu kalıcı olarak saklayın.",
- "pro.notes.limitReached": "Ücretsiz sürüm 5 uygulamaya kadar not kaydedebilir. Sınırsız not kaydetmek için Pro kilidini açın.",
+ "pro.notes.limitReached": "Ücretsiz sürüm en fazla 3 uygulama notu kaydedebilir. Sınırsız not için Pro’yu açın.",
"pro.notes.remaining": "Ücretsiz sürüm %limit% uygulama notu içerir. %remaining% kaldı.",
"pro.operation.cancelled": "Satın alma iptal edildi.",
"pro.operation.loading": "Pro erişimi kontrol ediliyor…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Satın alma işlemi geri yükleniyor…",
"pro.prompt.export": "Düzeni dışa aktarma bir Pro özelliğidir. Mevcut etiketlerinizi, siparişinizi ve düzeninizi yedeklemek için Pro kilidini açın.",
"pro.prompt.import": "Düzeni içe aktarma bir Pro özelliğidir. Bu Mac üzerinde kayıtlı bir düzeni geri yüklemek için Pro kilidini açın.",
- "pro.prompt.notes": "Sınırsız uygulama notları Pro'nun bir parçasıdır. Her uygulamaya ilişkin notları kaydetmek için Pro kilidini açın.",
+ "pro.prompt.notes": "Ücretsiz sürüm en fazla 3 uygulama notu kaydedebilir. Tüm uygulamalara not kaydetmek için Pro’yu açın.",
"pro.prompt.sorting": "Kaydedilen manuel uygulama sıralaması Pro'nun bir parçasıdır. Özel siparişinizi korumak için Pro kilidini açın.",
"pro.prompt.themes": "Bu tema Pro'nun bir parçasıdır. Gelişmiş App Grid temalarını kullanmaya devam etmek için Pro kilidini açın.",
"pro.purchase.failed": "Satın alma işlemi şu anda tamamlanamıyor. Lütfen tekrar deneyin.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Özel kısayollar",
"pro.feature.customHotkeys.benefit": "Uygulama listesi ve Quick Search için genel kısayollar ayarlayın.",
"pro.prompt.customHotkeys": "Özel kısayollar Pro özelliğidir. Genel kısayolları ayarlamak için Pro kilidini açın.",
- "hotkeys.customize": "Özelleştir",
+ "hotkeys.customize": "Kısayolu değiştir",
"hotkeys.restoreDefault": "Varsayılana dön",
"hotkeys.recording": "Yeni kısayola şimdi basın. İptal için Esc.",
"hotkeys.recordingInline": "Kaydediliyor",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Bu tuş desteklenmiyor.",
"hotkeys.error.reserved": "Bu kısayol macOS veya uygulama tarafından ayrılmıştır.",
"hotkeys.error.duplicate": "Bu kısayol başka bir TagLauncher eylemine atanmış.",
- "hotkeys.error.registrationFailed": "Kısayol kaydedilemedi. Hata kodu: %status%."
+ "hotkeys.error.registrationFailed": "Kısayol kaydedilemedi. Hata kodu: %status%.",
+ "pro.feature.customTagColors": "Özel etiket renkleri",
+ "pro.feature.customTagColors.benefit": "SmartStart sistem kategorileri dahil her etikete istediğiniz rengi verin.",
+ "pro.prompt.customTagColors": "Özel etiket renkleri bir Pro özelliğidir. Pro’yu açarak her etikete istediğiniz rengi verin ve kategorileri daha kolay tanıyın.",
+ "settings.proStatus.freeUser": "Şu anda ücretsiz kullanıcısısınız",
+ "settings.proStatus.proUser": "Şu anda değerli bir 👑Pro kullanıcısısınız",
+ "settings.proStatus.lockedListTitle": "Açılacak Pro özellikleri",
+ "settings.proStatus.unlockedListTitle": "Açılmış özellikler",
+ "settings.proStatus.lockedFeature": "✅ Desteklenir",
+ "settings.proStatus.unlockedFeature": "✅Açık",
+ "settings.proStatus.freeNotes": "3 ücretsiz",
+ "settings.proStatus.unlimitedNotes": "✅ Sınırsız not",
+ "settings.proStatus.limitedFeature": "Sınırlı",
+ "settings.proStatus.unsupportedFeature": "Desteklenmiyor",
+ "settings.proFeature.appNotes": "Özel uygulama notları",
+ "settings.proFeature.dataBackup": "Veri içe/dışa aktarma ve düzen yedekleri",
+ "tag.customColor": "Özel renk",
+ "settings.proBenefit.hotkeys": "TagLauncher eylemleri için kendi kısayollarınızı ayarlayın.",
+ "settings.proBenefit.tags": "Her etikete özel renk vererek daha hızlı tanıyın.",
+ "settings.proBenefit.data": "Kategorileri ve düzeni yedekleyin, dışa/içe aktarın ve geri yükleyin.",
+ "settings.proBenefit.about": "Tüm Pro avantajları bu Mac’te açık.",
+ "settings.proBenefit.general": "Pro renkli kapsayıcı ve renkli ızgara bu Mac’te kullanılabilir.",
+ "settings.proGuide.hotkeys": "Varsayılan kısayollar kullanılabilir. Pro kullanıcıları kısayolları özelleştirebilir.",
+ "settings.proGuide.tags": "7 varsayılan renk kullanılabilir. Pro kullanıcıları daha fazla rengi özelleştirebilir.",
+ "settings.proGuide.data": "Pro kullanıcıları kategori ve düzen verilerini içe ve dışa aktarabilir.",
+ "settings.proCompare.title": "Ücretsiz ve Pro farkları",
+ "settings.proCompare.free": "Ücretsiz",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Kullanılamaz",
+ "settings.proStatus.previewFiveMinutes": "Yalnızca 5 dakikalık önizleme",
+ "settings.proGuide.general": "Renkli kapsayıcılar / ızgaralar yalnızca Pro kullanıcıları içindir"
}
diff --git a/src/Apptag/Localization/uk.json b/src/Apptag/Localization/uk.json
index 0a4fafd..1f3807b 100644
--- a/src/Apptag/Localization/uk.json
+++ b/src/Apptag/Localization/uk.json
@@ -8,8 +8,8 @@
"menu.language": "Мова",
"menu.help": "Довідка",
"menu.version": "Версія",
- "menu.proStatus.free": "Зараз ви користувач безкоштовної версії (оновити до Pro)",
- "menu.proStatus.unlocked": "Зараз ви цінний користувач Pro",
+ "menu.proStatus.free": "Зараз ви користувач безкоштовної версії (перейдіть на 👑Pro зараз)",
+ "menu.proStatus.unlocked": "Зараз ви цінний користувач 👑Pro",
"settings.language": "Мова",
"settings.languagePicker": "Мова застосунку:",
"settings.languageDesc": "Оберіть мову меню та налаштувань.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Немає результатів розумної класифікації для застосування.",
"scheme.local": "Локальна схема",
"scheme.systemSmartStart": "Розумна початкова схема системи",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Показувати підказки-бульбашки для:",
+ "settings.bubbleAllApps": "Усі програми",
+ "settings.bubbleUncommonOnly": "Лише рідко використовувані програми",
+ "quickSearch.title": "Швидкий пошук",
+ "quickSearch.placeholder": "Пошук програм, тегів і нотаток",
+ "quickSearch.inputAccessibility": "Поле швидкого пошуку",
+ "quickSearch.emptyPrompt": "Почніть вводити, щоб шукати програми, теги й нотатки.",
+ "quickSearch.noResults": "Програми не знайдено.",
+ "quickSearch.launchFailed": "Не вдалося відкрити цю програму. Спробуйте ще раз або виберіть іншу програму.",
+ "quickSearch.tagPrefix": "Тег",
+ "quickSearch.hotkeys": "Комбінації клавіш",
+ "quickSearch.mainHotkey": "Список програм",
+ "quickSearch.mainHotkeyDesc": "Відкриває список програм TagLauncher.",
+ "quickSearch.status.Active": "Активно",
+ "quickSearch.status.registrationFailed": "Не вдалося зареєструвати",
+ "quickSearch.status.unavailable": "Комбінація недоступна",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% зараз не можна зареєструвати. Можливо, її використовує macOS, метод введення або інша програма. Комбінація для списку програм тимчасово недоступна. Перевірте комбінації клавіш або конфлікти й перезапустіть TagLauncher. Код помилки: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% зараз не можна зареєструвати. Можливо, її використовує macOS, метод введення або інша програма. Глобальний швидкий пошук тимчасово недоступний. Перевірте комбінації клавіш або конфлікти й перезапустіть TagLauncher. Код помилки: %status%.",
+ "quickSearch.loading": "Підготовка індексу пошуку…",
+ "quickSearch.internalHotkey": "Швидкий пошук (у TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Працює лише коли список програм TagLauncher відкритий.",
+ "quickSearch.internalHotkeyStatus": "Лише список програм",
+ "quickSearch.globalHotkey": "Швидкий пошук (глобально)",
+ "quickSearch.globalHotkeyDesc": "Відкриває глобальний швидкий пошук, коли список програм TagLauncher не видимий.",
+ "quickSearch.spaceDisplay": "Space (пробіл)",
"trackpadGesture.title": "Жест трекпада",
"trackpadGesture.description": "Призначте жест трекпада у сторонній утиліті на цю URL-адресу, щоб показати список програм.",
"trackpadGesture.status": "Зовнішній інструмент",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "попередній перегляд",
"pro.card.restore": "Відновити покупки",
- "pro.card.summary.free": "Розблокуйте преміум-теми, імпорт і експорт макетів, необмежену кількість нотаток і збережене ручне сортування програм.",
+ "pro.card.summary.free": "Відкрийте власні кольори тегів, преміум-теми, імпорт і експорт макетів, необмежені нотатки програм і власні скорочення.",
"pro.card.summary.legacy": "Дякуємо за першу підтримку TagLauncher. Ваш доступ до Pro вже активний.",
- "pro.card.summary.unlocked": "Pro активний на цьому Mac. Преміум-теми та розширені інструменти компонування готові.",
+ "pro.card.summary.unlocked": "Pro активний на цьому Mac. Власні кольори тегів, розширені теми, необмежені нотатки, власні скорочення та інструменти макета готові.",
"pro.card.title.free": "Оновити до Pro",
"pro.card.title.legacy": "Pro розблоковано",
"pro.card.title.unlocked": "Pro розблоковано",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "збережіть поточні теги, порядок і макет як багаторазову резервну копію.",
"pro.feature.import": "Імпорт макета",
"pro.feature.import.benefit": "відновіть збережений макет TagLauncher на цьому Mac одним кроком.",
- "pro.feature.notes": "Необмежена кількість нотаток",
- "pro.feature.notes.benefit": "Зберігайте нотатки для кожної програми без обмеження на 5 безкоштовних нотаток.",
+ "pro.feature.notes": "Власні нотатки програм",
+ "pro.feature.notes.benefit": "Безкоштовна версія містить 3 нотатки програм. Pro відкриває необмежені нотатки для всіх програм.",
"pro.feature.sorting": "сортування збережених програм",
"pro.feature.sorting.benefit": "зберігайте свій ручний порядок додатків після виходу з режиму редагування.",
"pro.feature.themes": "преміум-теми",
"pro.feature.themes.benefit": "розблокуйте кожну розширену тему App Grid та зберігайте її назавжди.",
- "pro.notes.limitReached": "безкоштовна версія може зберігати нотатки до 5 програм. Розблокуйте Pro, щоб зберігати необмежену кількість нотаток.",
+ "pro.notes.limitReached": "Безкоштовна версія може зберегти до 3 нотаток програм. Відкрийте Pro для необмежених нотаток.",
"pro.notes.remaining": "безкоштовна версія містить %limit% приміток до програми. Залишилося %remaining%.",
"pro.operation.cancelled": "покупку скасовано.",
"pro.operation.loading": "Перевірка доступу до Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Відновлення покупки…",
"pro.prompt.export": "експорт макета є функцією Pro. Розблокуйте Pro, щоб створити резервну копію поточних тегів, порядку та макета.",
"pro.prompt.import": "Імпорт макета є функцією Pro. Розблокуйте Pro, щоб відновити збережений макет на цьому Mac.",
- "pro.prompt.notes": "Необмежена кількість приміток до програми є частиною Pro. Розблокуйте Pro, щоб зберігати нотатки для кожної програми.",
+ "pro.prompt.notes": "Безкоштовна версія може зберегти до 3 нотаток програм. Відкрийте Pro, щоб зберігати нотатки для всіх програм.",
"pro.prompt.sorting": "Збережене ручне сортування програм є частиною Pro. Розблокуйте Pro, щоб зберегти свій власний порядок.",
"pro.prompt.themes": "Ця тема є частиною Pro. Розблокуйте Pro, щоб продовжувати використовувати розширені теми App Grid.",
"pro.purchase.failed": "зараз неможливо завершити покупку. Спробуйте ще раз.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Власні скорочення",
"pro.feature.customHotkeys.benefit": "Налаштуйте глобальні скорочення для списку програм і Quick Search.",
"pro.prompt.customHotkeys": "Власні скорочення входять до Pro. Розблокуйте Pro, щоб налаштувати їх.",
- "hotkeys.customize": "Налаштувати",
+ "hotkeys.customize": "Змінити скорочення",
"hotkeys.restoreDefault": "Відновити типове",
"hotkeys.recording": "Натисніть нове скорочення. Esc — скасувати.",
"hotkeys.recordingInline": "Запис",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Ця клавіша не підтримується.",
"hotkeys.error.reserved": "Це скорочення зарезервоване macOS або програмою.",
"hotkeys.error.duplicate": "Це скорочення вже використовується іншою дією TagLauncher.",
- "hotkeys.error.registrationFailed": "Не вдалося зареєструвати скорочення. Код помилки: %status%."
+ "hotkeys.error.registrationFailed": "Не вдалося зареєструвати скорочення. Код помилки: %status%.",
+ "pro.feature.customTagColors": "Власні кольори тегів",
+ "pro.feature.customTagColors.benefit": "Задавайте будь-який колір для кожного тега, включно із системними категоріями SmartStart.",
+ "pro.prompt.customTagColors": "Власні кольори тегів — функція Pro. Відкрийте Pro, щоб давати кожному тегу будь-який колір і легше розпізнавати категорії.",
+ "settings.proStatus.freeUser": "Зараз ви користувач безкоштовної версії",
+ "settings.proStatus.proUser": "Зараз ви цінний користувач 👑Pro",
+ "settings.proStatus.lockedListTitle": "Функції Pro для відкриття",
+ "settings.proStatus.unlockedListTitle": "Відкриті функції",
+ "settings.proStatus.lockedFeature": "✅ Підтримується",
+ "settings.proStatus.unlockedFeature": "✅Відкрито",
+ "settings.proStatus.freeNotes": "3 безкоштовно",
+ "settings.proStatus.unlimitedNotes": "✅ Нотатки без обмежень",
+ "settings.proStatus.limitedFeature": "Обмежено",
+ "settings.proStatus.unsupportedFeature": "Не підтримується",
+ "settings.proFeature.appNotes": "Власні нотатки програм",
+ "settings.proFeature.dataBackup": "Імпорт/експорт даних і резервні копії макета",
+ "tag.customColor": "Власний колір",
+ "settings.proBenefit.hotkeys": "Налаштовуйте власні скорочення для дій TagLauncher.",
+ "settings.proBenefit.tags": "Надавайте кожному тегу власний колір, щоб швидше його впізнавати.",
+ "settings.proBenefit.data": "Створюйте копії, експортуйте, імпортуйте й відновлюйте категорії та макет.",
+ "settings.proBenefit.about": "Усі переваги Pro відкриті на цьому Mac.",
+ "settings.proBenefit.general": "На цьому Mac доступні кольоровий контейнер і кольорова сітка Pro.",
+ "settings.proGuide.hotkeys": "Стандартні скорочення доступні. Користувачі Pro можуть налаштовувати власні скорочення.",
+ "settings.proGuide.tags": "Доступні 7 стандартних кольорів. Користувачі Pro можуть налаштовувати більше кольорів.",
+ "settings.proGuide.data": "Користувачі Pro можуть імпортувати й експортувати дані категорій і макета.",
+ "settings.proCompare.title": "Відмінності безкоштовної версії та Pro",
+ "settings.proCompare.free": "Безкоштовно",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Недоступно",
+ "settings.proStatus.previewFiveMinutes": "Лише 5 хвилин попереднього перегляду",
+ "settings.proGuide.general": "Кольорові контейнери / сітки доступні лише користувачам Pro"
}
diff --git a/src/Apptag/Localization/vi.json b/src/Apptag/Localization/vi.json
index 4dfb3bb..c770e4a 100644
--- a/src/Apptag/Localization/vi.json
+++ b/src/Apptag/Localization/vi.json
@@ -8,8 +8,8 @@
"menu.language": "Ngôn ngữ",
"menu.help": "Trợ giúp",
"menu.version": "Phiên bản",
- "menu.proStatus.free": "Bạn hiện là người dùng Miễn phí (nâng cấp lên Pro)",
- "menu.proStatus.unlocked": "Bạn hiện là người dùng Pro danh giá",
+ "menu.proStatus.free": "Bạn hiện là người dùng Miễn phí (nâng cấp ngay lên 👑Pro)",
+ "menu.proStatus.unlocked": "Bạn hiện là người dùng 👑Pro danh giá",
"settings.language": "Ngôn ngữ",
"settings.languagePicker": "Ngôn ngữ ứng dụng:",
"settings.languageDesc": "Chọn ngôn ngữ dùng cho menu và cài đặt.",
@@ -162,31 +162,31 @@
"settings.systemSchemeApplyFailed": "Không có kết quả phân loại thông minh để áp dụng.",
"scheme.local": "Sơ đồ cục bộ",
"scheme.systemSmartStart": "Sơ đồ khởi tạo thông minh của hệ thống",
- "settings.bubbleDisplayScope": "Bubble tips show for:",
- "settings.bubbleAllApps": "All apps",
- "settings.bubbleUncommonOnly": "Uncommon apps only",
- "quickSearch.title": "Quick Search",
- "quickSearch.placeholder": "Search apps, tags, and notes",
- "quickSearch.inputAccessibility": "Quick Search input",
- "quickSearch.emptyPrompt": "Start typing to search apps, tags, and notes.",
- "quickSearch.noResults": "No apps found.",
- "quickSearch.launchFailed": "Unable to open this app. Please try again or choose another app.",
- "quickSearch.tagPrefix": "Tag",
- "quickSearch.hotkeys": "Keyboard shortcuts",
- "quickSearch.mainHotkey": "App list",
- "quickSearch.mainHotkeyDesc": "Opens the TagLauncher app list.",
- "quickSearch.status.Active": "Active",
- "quickSearch.status.registrationFailed": "Registration failed",
- "quickSearch.status.unavailable": "Shortcut unavailable",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. The app-list shortcut is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% cannot be registered right now. It may be used by macOS, an input method, or another app. Global Quick Search is temporarily unavailable. Check keyboard shortcuts or shortcut conflicts, then restart TagLauncher. Error code: %status%.",
- "quickSearch.loading": "Preparing search index…",
- "quickSearch.internalHotkey": "Quick Search (inside TagLauncher)",
- "quickSearch.internalHotkeyDesc": "Works only while the TagLauncher app list is open.",
- "quickSearch.internalHotkeyStatus": "App list only",
- "quickSearch.globalHotkey": "Quick Search (global)",
- "quickSearch.globalHotkeyDesc": "Open Quick Search globally when the TagLauncher app list is not visible.",
- "quickSearch.spaceDisplay": "Space",
+ "settings.bubbleDisplayScope": "Hiển thị mẹo bong bóng cho:",
+ "settings.bubbleAllApps": "Tất cả ứng dụng",
+ "settings.bubbleUncommonOnly": "Chỉ ứng dụng ít dùng",
+ "quickSearch.title": "Tìm kiếm nhanh",
+ "quickSearch.placeholder": "Tìm ứng dụng, thẻ và ghi chú",
+ "quickSearch.inputAccessibility": "Ô nhập tìm kiếm nhanh",
+ "quickSearch.emptyPrompt": "Bắt đầu nhập để tìm ứng dụng, thẻ và ghi chú.",
+ "quickSearch.noResults": "Không tìm thấy ứng dụng.",
+ "quickSearch.launchFailed": "Không thể mở ứng dụng này. Hãy thử lại hoặc chọn ứng dụng khác.",
+ "quickSearch.tagPrefix": "Thẻ",
+ "quickSearch.hotkeys": "Phím tắt bàn phím",
+ "quickSearch.mainHotkey": "Danh sách ứng dụng",
+ "quickSearch.mainHotkeyDesc": "Mở danh sách ứng dụng TagLauncher.",
+ "quickSearch.status.Active": "Đang bật",
+ "quickSearch.status.registrationFailed": "Đăng ký thất bại",
+ "quickSearch.status.unavailable": "Phím tắt không khả dụng",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% hiện không thể đăng ký. Phím này có thể đang được macOS, bộ gõ hoặc ứng dụng khác dùng. Phím tắt danh sách ứng dụng tạm thời không khả dụng. Kiểm tra phím tắt bàn phím hoặc xung đột phím tắt, rồi khởi động lại TagLauncher. Mã lỗi: %status%.",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% hiện không thể đăng ký. Phím này có thể đang được macOS, bộ gõ hoặc ứng dụng khác dùng. Tìm kiếm nhanh toàn cục tạm thời không khả dụng. Kiểm tra phím tắt bàn phím hoặc xung đột phím tắt, rồi khởi động lại TagLauncher. Mã lỗi: %status%.",
+ "quickSearch.loading": "Đang chuẩn bị chỉ mục tìm kiếm…",
+ "quickSearch.internalHotkey": "Tìm kiếm nhanh (trong TagLauncher)",
+ "quickSearch.internalHotkeyDesc": "Chỉ hoạt động khi danh sách ứng dụng TagLauncher đang mở.",
+ "quickSearch.internalHotkeyStatus": "Chỉ danh sách ứng dụng",
+ "quickSearch.globalHotkey": "Tìm kiếm nhanh (toàn cục)",
+ "quickSearch.globalHotkeyDesc": "Mở tìm kiếm nhanh toàn cục khi danh sách ứng dụng TagLauncher không hiển thị.",
+ "quickSearch.spaceDisplay": "Space (phím cách)",
"trackpadGesture.title": "Cử chỉ bàn di chuột",
"trackpadGesture.description": "Gán một cử chỉ bàn di chuột trong công cụ bên thứ ba vào URL này để hiện danh sách ứng dụng.",
"trackpadGesture.status": "Công cụ bên ngoài",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "Xem trước",
"pro.card.restore": "Khôi phục mua hàng",
- "pro.card.summary.free": "Mở khóa các chủ đề cao cấp, nhập và xuất bố cục, ghi chú không giới hạn và phân loại ứng dụng thủ công được lưu.",
+ "pro.card.summary.free": "Mở khóa màu thẻ tùy chỉnh, chủ đề cao cấp, nhập và xuất bố cục, ghi chú ứng dụng không giới hạn và phím tắt tùy chỉnh.",
"pro.card.summary.legacy": "Cảm ơn đã ủng hộ TagLauncher sớm. Quyền truy cập Pro của bạn đã hoạt động.",
- "pro.card.summary.unlocked": "Pro đang hoạt động trên Mac này. Các chủ đề cao cấp và công cụ bố cục nâng cao đã sẵn sàng.",
+ "pro.card.summary.unlocked": "Pro đang hoạt động trên máy Mac này. Màu thẻ tùy chỉnh, chủ đề nâng cao, ghi chú không giới hạn, phím tắt tùy chỉnh và công cụ bố cục đã sẵn sàng.",
"pro.card.title.free": "Nâng cấp lên Pro",
"pro.card.title.legacy": "Pro đã mở khóa",
"pro.card.title.unlocked": "Pro đã mở khóa",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "Lưu các thẻ, thứ tự và bố cục hiện tại của bạn làm bản sao lưu có thể sử dụng lại.",
"pro.feature.import": "Nhập bố cục",
"pro.feature.import.benefit": "Khôi phục bố cục TagLauncher đã lưu trên Mac này trong một bước.",
- "pro.feature.notes": "Ghi chú không giới hạn",
- "pro.feature.notes.benefit": "Lưu ghi chú cho mọi ứng dụng mà không giới hạn 5 ghi chú miễn phí.",
+ "pro.feature.notes": "Ghi chú ứng dụng tùy chỉnh",
+ "pro.feature.notes.benefit": "Bản miễn phí gồm 3 ghi chú ứng dụng. Pro mở ghi chú không giới hạn cho mọi ứng dụng.",
"pro.feature.sorting": "Sắp xếp ứng dụng đã lưu",
"pro.feature.sorting.benefit": "Giữ nguyên thứ tự ứng dụng thủ công sau khi bạn thoát khỏi chế độ chỉnh sửa.",
"pro.feature.themes": "Chủ đề cao cấp",
"pro.feature.themes.benefit": "Mở khóa mọi chủ đề App Grid nâng cao và giữ nó vĩnh viễn.",
- "pro.notes.limitReached": "Phiên bản miễn phí có thể lưu ghi chú cho tối đa 5 ứng dụng. Mở khóa Pro để lưu ghi chú không giới hạn.",
+ "pro.notes.limitReached": "Bản miễn phí lưu tối đa 3 ghi chú ứng dụng. Mở khóa Pro để lưu ghi chú không giới hạn.",
"pro.notes.remaining": "Phiên bản miễn phí bao gồm %limit% ghi chú ứng dụng. Còn lại %remaining%.",
"pro.operation.cancelled": "Giao dịch mua bị hủy.",
"pro.operation.loading": "Đang kiểm tra quyền truy cập Pro…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "Khôi phục giao dịch mua…",
"pro.prompt.export": "Xuất bố cục là một tính năng Pro. Mở khóa Pro để sao lưu thẻ, thứ tự và bố cục hiện tại của bạn.",
"pro.prompt.import": "Nhập bố cục là một tính năng Pro. Mở khóa Pro để khôi phục bố cục đã lưu trên Mac này.",
- "pro.prompt.notes": "Ghi chú ứng dụng không giới hạn là một phần của Pro. Mở khóa Pro để lưu ghi chú cho mọi ứng dụng.",
+ "pro.prompt.notes": "Bản miễn phí lưu tối đa 3 ghi chú ứng dụng. Mở khóa Pro để lưu ghi chú cho mọi ứng dụng.",
"pro.prompt.sorting": "Việc sắp xếp ứng dụng thủ công đã lưu là một phần của Pro. Mở khóa Pro để giữ thứ tự tùy chỉnh của bạn.",
"pro.prompt.themes": "Chủ đề này là một phần của Pro. Mở khóa Pro để tiếp tục sử dụng các chủ đề App Grid nâng cao.",
"pro.purchase.failed": "Không thể hoàn tất việc mua hàng ngay bây giờ. Vui lòng thử lại.",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "Phím tắt tuỳ chỉnh",
"pro.feature.customHotkeys.benefit": "Đặt phím tắt toàn cục cho danh sách ứng dụng và Quick Search.",
"pro.prompt.customHotkeys": "Phím tắt tuỳ chỉnh là tính năng Pro. Mở khoá Pro để đặt phím tắt toàn cục.",
- "hotkeys.customize": "Tuỳ chỉnh",
+ "hotkeys.customize": "Đổi phím tắt",
"hotkeys.restoreDefault": "Khôi phục mặc định",
"hotkeys.recording": "Nhấn phím tắt mới ngay bây giờ. Nhấn Esc để huỷ.",
"hotkeys.recordingInline": "Đang ghi",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "Phím này không được hỗ trợ.",
"hotkeys.error.reserved": "Phím tắt này được macOS hoặc ứng dụng giữ lại.",
"hotkeys.error.duplicate": "Phím tắt này đã thuộc về một thao tác TagLauncher khác.",
- "hotkeys.error.registrationFailed": "Không thể đăng ký phím tắt. Mã lỗi: %status%."
+ "hotkeys.error.registrationFailed": "Không thể đăng ký phím tắt. Mã lỗi: %status%.",
+ "pro.feature.customTagColors": "Màu thẻ tùy chỉnh",
+ "pro.feature.customTagColors.benefit": "Đặt bất kỳ màu nào cho mỗi thẻ, kể cả thẻ danh mục hệ thống SmartStart.",
+ "pro.prompt.customTagColors": "Màu thẻ tùy chỉnh là tính năng Pro. Mở khóa Pro để đặt màu bất kỳ cho từng thẻ và nhận diện danh mục dễ hơn.",
+ "settings.proStatus.freeUser": "Bạn hiện là người dùng Miễn phí",
+ "settings.proStatus.proUser": "Bạn hiện là người dùng 👑Pro danh giá",
+ "settings.proStatus.lockedListTitle": "Tính năng Pro chờ mở khóa",
+ "settings.proStatus.unlockedListTitle": "Tính năng đã mở khóa",
+ "settings.proStatus.lockedFeature": "✅ Hỗ trợ",
+ "settings.proStatus.unlockedFeature": "✅Đã mở khóa",
+ "settings.proStatus.freeNotes": "3 miễn phí",
+ "settings.proStatus.unlimitedNotes": "✅ Ghi chú không giới hạn",
+ "settings.proStatus.limitedFeature": "Bị giới hạn",
+ "settings.proStatus.unsupportedFeature": "Không hỗ trợ",
+ "settings.proFeature.appNotes": "Ghi chú ứng dụng tùy chỉnh",
+ "settings.proFeature.dataBackup": "Nhập/xuất dữ liệu và sao lưu bố cục",
+ "tag.customColor": "Màu tùy chỉnh",
+ "settings.proBenefit.hotkeys": "Đặt phím tắt riêng cho các thao tác TagLauncher.",
+ "settings.proBenefit.tags": "Gán màu tùy chỉnh cho từng thẻ để nhận diện nhanh hơn.",
+ "settings.proBenefit.data": "Sao lưu, xuất, nhập và khôi phục danh mục cùng bố cục.",
+ "settings.proBenefit.about": "Tất cả lợi ích Pro đã mở khóa trên máy Mac này.",
+ "settings.proBenefit.general": "Bộ chứa màu và lưới màu Pro có sẵn trên máy Mac này.",
+ "settings.proGuide.hotkeys": "Có thể dùng phím tắt mặc định. Người dùng Pro có thể tùy chỉnh phím tắt.",
+ "settings.proGuide.tags": "Có sẵn 7 màu mặc định. Người dùng Pro có thể tùy chỉnh thêm màu.",
+ "settings.proGuide.data": "Người dùng Pro có thể nhập và xuất dữ liệu danh mục và bố cục.",
+ "settings.proCompare.title": "Khác biệt giữa Miễn phí và Pro",
+ "settings.proCompare.free": "Miễn phí",
+ "settings.proCompare.pro": "Pro",
+ "settings.proStatus.unavailableFeature": "Không khả dụng",
+ "settings.proStatus.previewFiveMinutes": "Chỉ xem trước 5 phút",
+ "settings.proGuide.general": "Chỉ người dùng Pro mới dùng được vùng chứa / lưới màu"
}
diff --git a/src/Apptag/Localization/zh-Hans.json b/src/Apptag/Localization/zh-Hans.json
index 3d623de..c601c12 100644
--- a/src/Apptag/Localization/zh-Hans.json
+++ b/src/Apptag/Localization/zh-Hans.json
@@ -8,8 +8,8 @@
"menu.language": "语言",
"menu.help": "帮助",
"menu.version": "版本",
- "menu.proStatus.free": "当前您是:免费版(升级到 Pro)用户",
- "menu.proStatus.unlocked": "当前您是:尊贵的 Pro 版用户",
+ "menu.proStatus.free": "当前您是: 免费版用户(立刻升级到 👑Pro)",
+ "menu.proStatus.unlocked": "当前您是:尊贵的 👑Pro版用户",
"settings.language": "语言",
"settings.languagePicker": "应用语言:",
"settings.languageDesc": "选择菜单和设置面板使用的语言。",
@@ -162,15 +162,15 @@
"settings.systemSchemeApplyFailed": "没有找到可应用的智能分类结果。",
"scheme.local": "本地分类方案",
"scheme.systemSmartStart": "系统智能化初始分类",
- "settings.bubbleDisplayScope": "气泡提示框显示位置:",
+ "settings.bubbleDisplayScope": "气泡提示显示范围:",
"settings.bubbleAllApps": "全部应用",
"settings.bubbleUncommonOnly": "仅不常用应用",
"quickSearch.title": "快捷搜索",
"quickSearch.placeholder": "搜索 App、标签和备注",
"quickSearch.inputAccessibility": "快捷搜索输入框",
"quickSearch.emptyPrompt": "开始输入以搜索 App、标签和备注。",
- "quickSearch.noResults": "未找到 App。",
- "quickSearch.launchFailed": "无法打开这个 App。请重试或选择其他 App。",
+ "quickSearch.noResults": "未找到应用。",
+ "quickSearch.launchFailed": "无法打开这个应用。请重试或选择其他应用。",
"quickSearch.tagPrefix": "标签",
"quickSearch.hotkeys": "快捷键",
"quickSearch.mainHotkey": "主界面",
@@ -178,15 +178,15 @@
"quickSearch.status.Active": "已启用",
"quickSearch.status.registrationFailed": "注册失败",
"quickSearch.status.unavailable": "快捷键不可用",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% 当前无法注册,可能被系统、输入法或其他软件占用。主界面快捷键暂不可用。请检查 macOS 键盘快捷键、输入法快捷键或其他常驻软件的快捷键占用,然后重启 TagLauncher。错误码:%status%。",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% 当前无法注册,可能被系统、输入法或其他软件占用。快捷搜索全局唤起暂不可用。请检查 macOS 键盘快捷键、输入法快捷键或其他常驻软件的快捷键占用,然后重启 TagLauncher。错误码:%status%。",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% 现在无法注册,可能已被 macOS、输入法或其他应用占用。应用列表快捷键暂时不可用。请检查键盘快捷键或快捷键冲突,然后重启 TagLauncher。错误代码:%status%。",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% 现在无法注册,可能已被 macOS、输入法或其他应用占用。全局快捷搜索暂时不可用。请检查键盘快捷键或快捷键冲突,然后重启 TagLauncher。错误代码:%status%。",
"quickSearch.loading": "正在准备搜索索引…",
"quickSearch.internalHotkey": "快捷搜索(TagLauncher 内部)",
- "quickSearch.internalHotkeyDesc": "仅在 TagLauncher 主界面有效。",
+ "quickSearch.internalHotkeyDesc": "仅在 TagLauncher 主界面打开时有效。",
"quickSearch.internalHotkeyStatus": "仅主界面有效",
"quickSearch.globalHotkey": "快捷搜索(全局)",
- "quickSearch.globalHotkeyDesc": "不在 TagLauncher 主界面时,直接打开快捷搜索。全局有效。",
- "quickSearch.spaceDisplay": "Space(空格键)",
+ "quickSearch.globalHotkeyDesc": "不在 TagLauncher 主界面时,直接打开快捷搜索。",
+ "quickSearch.spaceDisplay": "Space(空格键)",
"trackpadGesture.title": "触控板手势",
"trackpadGesture.description": "在第三方手势工具中把触控板手势映射到这个 URL,即可显示应用列表。",
"trackpadGesture.status": "外部工具",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "预览",
"pro.card.restore": "恢复购买",
- "pro.card.summary.free": "解锁高级主题、布局导入导出、无限备注,以及手动应用排序保存。",
+ "pro.card.summary.free": "解锁自定义标签颜色、高级主题、布局导入导出、无限应用备注和自定义快捷键。",
"pro.card.summary.legacy": "感谢你早期支持 TagLauncher。你的 Pro 权益已自动生效。",
- "pro.card.summary.unlocked": "这台 Mac 上的 Pro 已生效。高级主题和布局工具已可使用。",
+ "pro.card.summary.unlocked": "这台 Mac 上的 Pro 已生效。自定义标签颜色、高级主题、无限备注、自定义快捷键和布局工具已可使用。",
"pro.card.title.free": "升级到 Pro",
"pro.card.title.legacy": "Pro 已解锁",
"pro.card.title.unlocked": "Pro 已解锁",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "把当前标签、顺序和布局保存成可复用的备份。",
"pro.feature.import": "导入布局",
"pro.feature.import.benefit": "一步恢复这台 Mac 上已保存的 TagLauncher 布局。",
- "pro.feature.notes": "无限备注",
- "pro.feature.notes.benefit": "不再受免费版 5 条备注上限限制,可为每个应用保存备注。",
+ "pro.feature.notes": "自定义应用备注",
+ "pro.feature.notes.benefit": "免费版包含 3 个应用备注。Pro 可为所有应用保存无限备注。",
"pro.feature.sorting": "排序持久化",
"pro.feature.sorting.benefit": "离开编辑模式后仍保留你手动调整的应用顺序。",
"pro.feature.themes": "高级主题",
"pro.feature.themes.benefit": "解锁所有高级应用网格主题,并可永久使用。",
- "pro.notes.limitReached": "免费版最多只能为 5 个应用保存备注。解锁 Pro 后可保存无限备注。",
+ "pro.notes.limitReached": "免费版最多可保存 3 个应用备注。解锁 Pro 后,可保存无限备注。",
"pro.notes.remaining": "免费版最多支持 %limit% 个应用备注。当前剩余 %remaining% 个。",
"pro.operation.cancelled": "购买已取消。",
"pro.operation.loading": "正在检查 Pro 权益…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "正在恢复购买…",
"pro.prompt.export": "导出布局属于 Pro 功能。解锁 Pro 后可备份当前标签、顺序和布局。",
"pro.prompt.import": "导入布局属于 Pro 功能。解锁 Pro 后可在这台 Mac 上恢复已保存的布局。",
- "pro.prompt.notes": "无限应用备注属于 Pro 功能。解锁 Pro 后可为每个应用保存备注。",
+ "pro.prompt.notes": "免费版最多可保存 3 个应用备注。解锁 Pro 后,可为所有应用保存备注。",
"pro.prompt.sorting": "手动应用排序保存属于 Pro 功能。解锁 Pro 后可保留你的自定义顺序。",
"pro.prompt.themes": "这个主题属于 Pro。解锁 Pro 后可持续使用高级应用网格主题。",
"pro.purchase.failed": "暂时无法完成购买,请稍后再试。",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "自定义快捷键",
"pro.feature.customHotkeys.benefit": "为主界面和快捷搜索设置自己的全局快捷键。",
"pro.prompt.customHotkeys": "自定义快捷键属于 Pro 功能。解锁 Pro 后即可设置自己的全局快捷键。",
- "hotkeys.customize": "自定义",
+ "hotkeys.customize": "修改快捷键",
"hotkeys.restoreDefault": "恢复默认",
"hotkeys.recording": "请按下新的快捷键。按 Esc 取消。",
"hotkeys.recordingInline": "录制中",
@@ -309,9 +309,39 @@
"hotkeys.saved": "快捷键已保存。",
"hotkeys.restored": "已恢复默认快捷键。",
"hotkeys.proRequired": "解锁 Pro 后可自定义快捷键。",
- "hotkeys.error.modifierRequired": "请至少使用 Command、Control,或两个组合键。",
+ "hotkeys.error.modifierRequired": "请至少使用 Command、Control、Option,或两个组合键。",
"hotkeys.error.unsupportedKey": "不支持这个按键。",
"hotkeys.error.reserved": "这个快捷键已被 macOS 或应用保留。",
"hotkeys.error.duplicate": "这个快捷键已用于 TagLauncher 的另一个操作。",
- "hotkeys.error.registrationFailed": "快捷键注册失败。错误码:%status%。"
+ "hotkeys.error.registrationFailed": "快捷键注册失败。错误码:%status%。",
+ "pro.feature.customTagColors": "自定义标签颜色",
+ "pro.feature.customTagColors.benefit": "为每个标签设置任意颜色,包括 SmartStart 系统分类标签。",
+ "pro.prompt.customTagColors": "自定义标签颜色属于 Pro 功能。解锁 Pro 后,可为每个标签设置任意颜色,让分类更容易识别。",
+ "settings.proStatus.freeUser": "您当前是免费版用户",
+ "settings.proStatus.proUser": "您当前是尊贵的 👑Pro版用户",
+ "settings.proStatus.lockedListTitle": "待解锁的 Pro 功能",
+ "settings.proStatus.unlockedListTitle": "已解锁的功能",
+ "settings.proStatus.lockedFeature": "✅支持",
+ "settings.proStatus.unlockedFeature": "✅已解锁",
+ "settings.proStatus.freeNotes": "免费 3 个",
+ "settings.proStatus.unlimitedNotes": "✅无限备注",
+ "settings.proStatus.limitedFeature": "受限",
+ "settings.proStatus.unsupportedFeature": "不支持",
+ "settings.proFeature.appNotes": "自定义应用备注",
+ "settings.proFeature.dataBackup": "数据导入导出 / 分类与布局备份恢复",
+ "tag.customColor": "自定义颜色",
+ "settings.proBenefit.hotkeys": "您当前是尊贵的 Pro 用户,可以自定义快捷键。",
+ "settings.proBenefit.tags": "您当前是尊贵的 Pro 用户,可以自定义标签颜色。",
+ "settings.proBenefit.data": "您当前是尊贵的 Pro 用户,可以备份、导出、导入和恢复分类与布局。",
+ "settings.proBenefit.about": "这台 Mac 上的 Pro 权益已全部解锁。",
+ "settings.proBenefit.general": "这台 Mac 上可使用 Pro 专用彩色容器/网格",
+ "settings.proGuide.hotkeys": "默认快捷键可用,Pro 用户可以自定义快捷键。",
+ "settings.proGuide.tags": "默认 7 种配色可用,Pro 用户可以自定义更多颜色。",
+ "settings.proGuide.data": "Pro 用户可以导入导出分类与布局数据。",
+ "settings.proCompare.title": "免费版与 Pro 版差异",
+ "settings.proCompare.free": "免费版",
+ "settings.proCompare.pro": "Pro 版",
+ "settings.proStatus.unavailableFeature": "不可用",
+ "settings.proStatus.previewFiveMinutes": "只可预览 5 分钟",
+ "settings.proGuide.general": "仅Pro用户可以使用彩色容器/彩色网格"
}
diff --git a/src/Apptag/Localization/zh-Hant.json b/src/Apptag/Localization/zh-Hant.json
index 07623ef..3cb5c8e 100644
--- a/src/Apptag/Localization/zh-Hant.json
+++ b/src/Apptag/Localization/zh-Hant.json
@@ -8,8 +8,8 @@
"menu.language": "語言",
"menu.help": "說明",
"menu.version": "版本",
- "menu.proStatus.free": "目前您是:免費版(升級到 Pro)使用者",
- "menu.proStatus.unlocked": "目前您是:尊貴的 Pro 版使用者",
+ "menu.proStatus.free": "目前您是: 免費版使用者(立即升級到 👑Pro)",
+ "menu.proStatus.unlocked": "目前您是:尊貴的 👑Pro版使用者",
"settings.language": "語言",
"settings.languagePicker": "應用程式語言:",
"settings.languageDesc": "選擇選單和設定面板使用的語言。",
@@ -162,30 +162,30 @@
"settings.systemSchemeApplyFailed": "沒有找到可套用的智慧分類結果。",
"scheme.local": "本機分類方案",
"scheme.systemSmartStart": "系統智慧化初始分類",
- "settings.bubbleDisplayScope": "氣泡提示框顯示位置:",
+ "settings.bubbleDisplayScope": "氣泡提示顯示範圍:",
"settings.bubbleAllApps": "全部 App",
"settings.bubbleUncommonOnly": "僅不常用 App",
- "quickSearch.title": "快捷搜尋",
+ "quickSearch.title": "快速搜尋",
"quickSearch.placeholder": "搜尋 App、標籤和備註",
- "quickSearch.inputAccessibility": "快捷搜尋輸入框",
+ "quickSearch.inputAccessibility": "快速搜尋輸入框",
"quickSearch.emptyPrompt": "開始輸入以搜尋 App、標籤和備註。",
"quickSearch.noResults": "找不到 App。",
- "quickSearch.launchFailed": "無法打開這個 App。請重試或選擇其他 App。",
+ "quickSearch.launchFailed": "無法開啟這個 App。請重試或選擇其他 App。",
"quickSearch.tagPrefix": "標籤",
- "quickSearch.hotkeys": "快捷鍵",
- "quickSearch.mainHotkey": "主介面",
- "quickSearch.mainHotkeyDesc": "打開 TagLauncher 應用列表。",
+ "quickSearch.hotkeys": "快速鍵",
+ "quickSearch.mainHotkey": "主畫面",
+ "quickSearch.mainHotkeyDesc": "開啟 TagLauncher App 列表。",
"quickSearch.status.Active": "已啟用",
"quickSearch.status.registrationFailed": "註冊失敗",
- "quickSearch.status.unavailable": "快捷鍵不可用",
- "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% 目前無法註冊,可能被系統、輸入法或其他軟體佔用。主介面快捷鍵暫時不可用。請檢查 macOS 鍵盤快捷鍵、輸入法快捷鍵或其他常駐軟體的快捷鍵佔用,然後重新啟動 TagLauncher。錯誤碼:%status%。",
- "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% 目前無法註冊,可能被系統、輸入法或其他軟體佔用。快捷搜尋全域喚起暫時不可用。請檢查 macOS 鍵盤快捷鍵、輸入法快捷鍵或其他常駐軟體的快捷鍵佔用,然後重新啟動 TagLauncher。錯誤碼:%status%。",
+ "quickSearch.status.unavailable": "快速鍵不可用",
+ "quickSearch.mainHotkeyUnavailableMessage": "%shortcut% 目前無法註冊,可能已被 macOS、輸入法或其他 App 使用。App 列表快速鍵暫時不可用。請檢查鍵盤快速鍵或快速鍵衝突,然後重新啟動 TagLauncher。錯誤碼:%status%。",
+ "quickSearch.globalHotkeyUnavailableMessage": "%shortcut% 目前無法註冊,可能已被 macOS、輸入法或其他 App 使用。全域快速搜尋暫時不可用。請檢查鍵盤快速鍵或快速鍵衝突,然後重新啟動 TagLauncher。錯誤碼:%status%。",
"quickSearch.loading": "正在準備搜尋索引…",
- "quickSearch.internalHotkey": "快捷搜尋(TagLauncher 內部)",
- "quickSearch.internalHotkeyDesc": "僅在 TagLauncher 主介面有效。",
- "quickSearch.internalHotkeyStatus": "僅主介面有效",
- "quickSearch.globalHotkey": "快捷搜尋(全域)",
- "quickSearch.globalHotkeyDesc": "不在 TagLauncher 主介面時,直接打開快捷搜尋。全域有效。",
+ "quickSearch.internalHotkey": "快速搜尋(TagLauncher 內部)",
+ "quickSearch.internalHotkeyDesc": "僅在 TagLauncher 主畫面開啟時有效。",
+ "quickSearch.internalHotkeyStatus": "僅主畫面有效",
+ "quickSearch.globalHotkey": "快速搜尋(全域)",
+ "quickSearch.globalHotkeyDesc": "當 TagLauncher 主畫面未顯示時,直接開啟快速搜尋。",
"quickSearch.spaceDisplay": "Space(空格鍵)",
"trackpadGesture.title": "觸控板手勢",
"trackpadGesture.description": "在第三方手勢工具中把觸控板手勢映射到這個 URL,即可顯示應用列表。",
@@ -252,9 +252,9 @@
"pro.card.badge": "Pro",
"pro.card.previewBadge": "預覽",
"pro.card.restore": "恢復購買",
- "pro.card.summary.free": "解鎖進階主題、版面匯入匯出、無限備註,以及手動應用排序保存。",
+ "pro.card.summary.free": "解鎖自訂標籤顏色、高級主題、版面匯入匯出、無限應用備註和自訂快捷鍵。",
"pro.card.summary.legacy": "感謝你早期支持 TagLauncher。你的 Pro 權益已自動生效。",
- "pro.card.summary.unlocked": "這台 Mac 上的 Pro 已啟用。進階主題與版面工具已可使用。",
+ "pro.card.summary.unlocked": "這台 Mac 上的 Pro 已生效。自訂標籤顏色、高級主題、無限備註、自訂快捷鍵和版面工具已可使用。",
"pro.card.title.free": "升級到 Pro",
"pro.card.title.legacy": "Pro 已解鎖",
"pro.card.title.unlocked": "Pro 已解鎖",
@@ -263,13 +263,13 @@
"pro.feature.export.benefit": "把目前標籤、順序與版面儲存成可重複使用的備份。",
"pro.feature.import": "匯入版面",
"pro.feature.import.benefit": "一步恢復這台 Mac 上已儲存的 TagLauncher 版面。",
- "pro.feature.notes": "無限備註",
- "pro.feature.notes.benefit": "不再受免費版 5 筆備註上限限制,可為每個應用儲存備註。",
+ "pro.feature.notes": "自訂應用備註",
+ "pro.feature.notes.benefit": "免費版包含 3 個應用備註。Pro 可為所有應用儲存無限備註。",
"pro.feature.sorting": "排序持久化",
"pro.feature.sorting.benefit": "離開編輯模式後仍保留你手動調整的應用順序。",
"pro.feature.themes": "進階主題",
"pro.feature.themes.benefit": "解鎖所有進階應用網格主題,並可永久使用。",
- "pro.notes.limitReached": "免費版最多只能為 5 個應用儲存備註。解鎖 Pro 後可儲存無限備註。",
+ "pro.notes.limitReached": "免費版最多可儲存 3 個應用備註。解鎖 Pro 後可儲存無限備註。",
"pro.notes.remaining": "免費版最多支援 %limit% 個應用備註。當前剩餘 %remaining% 個。",
"pro.operation.cancelled": "購買已取消。",
"pro.operation.loading": "正在檢查 Pro 權益…",
@@ -279,7 +279,7 @@
"pro.operation.restoring": "正在恢復購買…",
"pro.prompt.export": "匯出版面屬於 Pro 功能。解鎖 Pro 後可備份目前標籤、順序與版面。",
"pro.prompt.import": "匯入版面屬於 Pro 功能。解鎖 Pro 後可在這台 Mac 上恢復已儲存的版面。",
- "pro.prompt.notes": "無限應用備註屬於 Pro 功能。解鎖 Pro 後可為每個應用儲存備註。",
+ "pro.prompt.notes": "免費版最多可儲存 3 個應用備註。解鎖 Pro 後可為所有應用儲存備註。",
"pro.prompt.sorting": "手動應用排序保存屬於 Pro 功能。解鎖 Pro 後可保留你的自訂順序。",
"pro.prompt.themes": "這個主題屬於 Pro。解鎖 Pro 後可持續使用進階應用網格主題。",
"pro.purchase.failed": "暫時無法完成購買,請稍後再試。",
@@ -301,7 +301,7 @@
"pro.feature.customHotkeys": "自訂快速鍵",
"pro.feature.customHotkeys.benefit": "為主介面與快速搜尋設定自己的全域快速鍵。",
"pro.prompt.customHotkeys": "自訂快速鍵屬於 Pro 功能。解鎖 Pro 後即可設定自己的全域快速鍵。",
- "hotkeys.customize": "自訂",
+ "hotkeys.customize": "修改快速鍵",
"hotkeys.restoreDefault": "恢復預設",
"hotkeys.recording": "請按下新的快速鍵。按 Esc 取消。",
"hotkeys.recordingInline": "錄製中",
@@ -313,5 +313,35 @@
"hotkeys.error.unsupportedKey": "不支援這個按鍵。",
"hotkeys.error.reserved": "這個快速鍵已被 macOS 或應用程式保留。",
"hotkeys.error.duplicate": "這個快速鍵已用於 TagLauncher 的另一個操作。",
- "hotkeys.error.registrationFailed": "快速鍵註冊失敗。錯誤碼:%status%。"
+ "hotkeys.error.registrationFailed": "快速鍵註冊失敗。錯誤碼:%status%。",
+ "pro.feature.customTagColors": "自訂標籤顏色",
+ "pro.feature.customTagColors.benefit": "為每個標籤設定任意顏色,包括 SmartStart 系統分類標籤。",
+ "pro.prompt.customTagColors": "自訂標籤顏色屬於 Pro 功能。解鎖 Pro 後可為每個標籤設定任意顏色,讓分類更容易辨識。",
+ "settings.proStatus.freeUser": "您目前是免費版使用者",
+ "settings.proStatus.proUser": "您目前是尊貴的 👑Pro版使用者",
+ "settings.proStatus.lockedListTitle": "待解鎖的 Pro 功能",
+ "settings.proStatus.unlockedListTitle": "已解鎖的功能",
+ "settings.proStatus.lockedFeature": "✅支援",
+ "settings.proStatus.unlockedFeature": "✅已解鎖",
+ "settings.proStatus.freeNotes": "免費 3 個",
+ "settings.proStatus.unlimitedNotes": "✅無限備註",
+ "settings.proStatus.limitedFeature": "受限",
+ "settings.proStatus.unsupportedFeature": "不支援",
+ "settings.proFeature.appNotes": "自訂應用備註",
+ "settings.proFeature.dataBackup": "資料匯入匯出 / 分類與版面備份還原",
+ "tag.customColor": "自訂顏色",
+ "settings.proBenefit.hotkeys": "您目前是尊貴的 Pro 使用者,可以自訂快捷鍵。",
+ "settings.proBenefit.tags": "您目前是尊貴的 Pro 使用者,可以自訂標籤顏色。",
+ "settings.proBenefit.data": "您目前是尊貴的 Pro 使用者,可以備份、匯出、匯入和還原分類與版面。",
+ "settings.proBenefit.about": "這台 Mac 上的 Pro 權益已全部解鎖。",
+ "settings.proBenefit.general": "這台 Mac 上可使用 Pro 專用彩色容器/網格",
+ "settings.proGuide.hotkeys": "預設快捷鍵可用,Pro 使用者可以自訂快捷鍵。",
+ "settings.proGuide.tags": "預設 7 種配色可用,Pro 使用者可以自訂更多顏色。",
+ "settings.proGuide.data": "Pro 使用者可以匯入匯出分類與版面資料。",
+ "settings.proCompare.title": "免費版與 Pro 版差異",
+ "settings.proCompare.free": "免費版",
+ "settings.proCompare.pro": "Pro 版",
+ "settings.proStatus.unavailableFeature": "不可用",
+ "settings.proStatus.previewFiveMinutes": "只可預覽 5 分鐘",
+ "settings.proGuide.general": "僅 Pro 使用者可以使用彩色容器/彩色網格"
}
diff --git a/src/Apptag/PreferencesView.swift b/src/Apptag/PreferencesView.swift
index 8838d3d..0e6c0e5 100644
--- a/src/Apptag/PreferencesView.swift
+++ b/src/Apptag/PreferencesView.swift
@@ -13,6 +13,7 @@
case hotkeys
case tags
case data
+ case pro
case about
var id: String { rawValue }
@@ -25,6 +26,7 @@
case .hotkeys: return "quickSearch.hotkeys"
case .tags: return "settings.tags"
case .data: return "settings.data"
+ case .pro: return "pro.card.badge"
case .about: return "settings.about"
}
}
@@ -33,10 +35,11 @@
switch self {
case .language: return "globe"
case .general: return "gearshape"
- case .theme: return "paintpalette.fill"
+ case .theme: return "paintpalette"
case .hotkeys: return "keyboard"
- case .tags: return "tag.fill"
- case .data: return "externaldrive.fill"
+ case .tags: return "tag"
+ case .data: return "externaldrive"
+ case .pro: return "crown"
case .about: return "info.circle"
}
}
@@ -79,6 +82,7 @@
@State private var isRefreshingLanguage = false
@State private var allApps: [AppInfo] = []
@State private var tagColors: [String: Int] = [:]
+ @State private var tagCustomColors: [String: TagCustomColor] = [:]
@State private var categoryScheme = TagDatabase.CategorySchemeState()
@State private var isApplyingSystemScheme = false
@State private var isResettingToUncategorized = false
@@ -111,9 +115,11 @@
let store = TagDatabase.loadWithEnsuredCategoryScheme()
apps = TagEditor.annotate(apps: apps)
let colors = store.tags.mapValues { $0.color }
+ let customColors = store.tags.compactMapValues { $0.customColor }
DispatchQueue.main.async {
allApps = apps
tagColors = colors
+ tagCustomColors = customColors
categoryScheme = store.categoryScheme
}
}
@@ -318,7 +324,12 @@
presentSettingsProPrompt(for: .customHotkeys)
return
}
+ guard let appDelegate = AppDelegate.shared else {
+ handleHotkeyCustomizationResult(.registrationFailed(-1))
+ return
+ }
stopHotkeyRecording(showCancelledToast: false)
+ appDelegate.suspendConfiguredHotkeysForRecording()
recordingHotkeyKind = kind
showHotkeyStatusToast(tr("hotkeys.recording"))
hotkeyRecorderMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
@@ -336,7 +347,7 @@
return
}
let candidate = LauncherHotkeySettings.candidate(from: event)
- let result = (NSApp.delegate as? AppDelegate)?
+ let result = AppDelegate.shared?
.applyCustomHotkey(candidate, for: kind)
?? .registrationFailed(-1)
stopHotkeyRecording(showCancelledToast: false)
@@ -348,18 +359,22 @@
presentSettingsProPrompt(for: .customHotkeys)
return
}
- let result = (NSApp.delegate as? AppDelegate)?
+ let result = AppDelegate.shared?
.restoreDefaultHotkey(for: kind)
?? .registrationFailed(-1)
handleHotkeyCustomizationResult(result)
}
private func stopHotkeyRecording(showCancelledToast: Bool = false) {
+ let wasRecording = recordingHotkeyKind != nil || hotkeyRecorderMonitor != nil
if let hotkeyRecorderMonitor {
NSEvent.removeMonitor(hotkeyRecorderMonitor)
}
hotkeyRecorderMonitor = nil
recordingHotkeyKind = nil
+ if wasRecording {
+ AppDelegate.shared?.resumeConfiguredHotkeysAfterRecording()
+ }
if showCancelledToast {
showHotkeyStatusToast(tr("hotkeys.recordingCancelled"))
}
@@ -651,8 +666,12 @@
ProEntitlementPolicy.effectiveTheme(for: selectedAppGridTheme)
}
+ private var effectiveDisplayMode: String {
+ ProEntitlementPolicy.effectiveDisplayMode(for: displayMode)
+ }
+
private var proStatusPillStyle: ProStatusPillStyle {
- if proEntitlement.isPreviewingTheme {
+ if proEntitlement.isPreviewingProAppearance {
return .preview
}
switch proEntitlement.accessState {
@@ -665,30 +684,338 @@
}
}
- private var proCardTitle: String {
- switch proEntitlement.accessState {
- case .free:
- return tr("pro.card.title.free")
- case .purchased:
- return tr("pro.card.title.unlocked")
- case .legacy:
- return tr("pro.card.title.legacy")
+ private var proAccentColor: Color {
+ Color(red: 0.56, green: 0.35, blue: 0.03)
+ }
+
+ private func centeredSettingsScrollContent<Content: View>(
+ width: CGFloat,
+ @ViewBuilder content: @escaping () -> Content
+ ) -> some View {
+ GeometryReader { proxy in
+ ScrollView(.vertical, showsIndicators: true) {
+ VStack(alignment: .center, spacing: 18) {
+ content()
+ }
+ .frame(width: width, alignment: .center)
+ .frame(maxWidth: .infinity, alignment: .center)
+ .frame(minHeight: proxy.size.height, alignment: .center)
+ }
}
}
- private var proCardSummary: String {
- switch proEntitlement.accessState {
- case .free:
- return tr("pro.card.summary.free")
- case .purchased:
- return tr("pro.card.summary.unlocked")
- case .legacy:
- return tr("pro.card.summary.legacy")
+ @ViewBuilder
+ private func proUnlockedBenefitLine(_ textKey: String, bottomPadding: CGFloat = 14) -> some View {
+ if proEntitlement.isUnlocked {
+ HStack(spacing: 12) {
+ ProStatusPill(
+ text: tr(proEntitlement.compactStatusTextKey),
+ style: proStatusPillStyle
+ )
+
+ Text(tr(textKey))
+ .font(.system(size: 13, weight: .medium))
+ .foregroundStyle(.secondary)
+ .lineLimit(2)
+ .fixedSize(horizontal: false, vertical: true)
+
+ Spacer(minLength: 0)
+ }
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .padding(.bottom, bottomPadding)
}
+ }
+
+ private func proPurchaseGuidanceLine(
+ _ textKey: String,
+ feature: ProFeature,
+ bottomPadding: CGFloat = 14,
+ compact: Bool = false
+ ) -> some View {
+ HStack(spacing: compact ? 8 : 12) {
+ ProStatusPill(
+ text: tr(proEntitlement.compactStatusTextKey),
+ style: proStatusPillStyle
+ )
+ .layoutPriority(1)
+
+ Text(tr(textKey))
+ .font(.system(size: 13, weight: .medium))
+ .foregroundStyle(.secondary)
+ .lineLimit(2)
+ .fixedSize(horizontal: false, vertical: true)
+ .layoutPriority(2)
+
+ Spacer(minLength: 8)
+
+ if !proEntitlement.isUnlocked {
+ Button(unlockButtonTitle()) {
+ presentSettingsProPrompt(for: feature)
+ }
+ .buttonStyle(.borderedProminent)
+ .controlSize(compact ? .small : .regular)
+ .layoutPriority(3)
+
+ Button(tr("pro.card.restore")) {
+ proEntitlement.restorePurchases()
+ }
+ .buttonStyle(.bordered)
+ .controlSize(compact ? .small : .regular)
+ .layoutPriority(3)
+ }
+ }
+ .padding(.horizontal, compact ? 10 : 16)
+ .padding(.vertical, compact ? 8 : 14)
+ .background(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .fill(Color(nsColor: .controlBackgroundColor))
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .stroke(Color.secondary.opacity(0.16), lineWidth: 1)
+ )
+ .padding(.bottom, bottomPadding)
+ }
+
+ @ViewBuilder
+ private func proAccessGuidanceLine(
+ freeTextKey: String,
+ unlockedTextKey: String,
+ feature: ProFeature,
+ bottomPadding: CGFloat = 14,
+ compact: Bool = false
+ ) -> some View {
+ if proEntitlement.isUnlocked {
+ proUnlockedBenefitLine(unlockedTextKey, bottomPadding: bottomPadding)
+ } else {
+ proPurchaseGuidanceLine(freeTextKey, feature: feature, bottomPadding: bottomPadding, compact: compact)
+ }
+ }
+
+ private var settingsProHeaderFeature: ProFeature {
+ switch selectedTab {
+ case .hotkeys:
+ return .customHotkeys
+ case .tags:
+ return .customTagColors
+ case .data:
+ return .layoutExport
+ case .theme, .general, .language, .pro, .about:
+ return .premiumThemes
+ }
+ }
+
+ private var settingsProHeaderText: String {
+ if selectedTab == .pro {
+ return tr(proEntitlement.isUnlocked ? "settings.proStatus.proUser" : "settings.proStatus.freeUser")
+ }
+
+ switch selectedTab {
+ case .general, .language, .about:
+ return tr(proEntitlement.isUnlocked ? "settings.proBenefit.general" : "settings.proGuide.general")
+ case .theme:
+ return themeStatusSummary
+ case .hotkeys:
+ return tr(proEntitlement.isUnlocked ? "settings.proBenefit.hotkeys" : "settings.proGuide.hotkeys")
+ case .tags:
+ return tr(proEntitlement.isUnlocked ? "settings.proBenefit.tags" : "settings.proGuide.tags")
+ case .data:
+ return tr(proEntitlement.isUnlocked ? "settings.proBenefit.data" : "settings.proGuide.data")
+ case .pro:
+ return tr(proEntitlement.isUnlocked ? "settings.proStatus.proUser" : "settings.proStatus.freeUser")
+ }
+ }
+
+ private var shouldShowSettingsFixedProHeader: Bool {
+ selectedTab != .language && selectedTab != .about
+ }
+
+ private var settingsFixedProHeader: some View {
+ HStack {
+ HStack(spacing: 12) {
+ if selectedTab != .pro {
+ ProStatusPill(
+ text: tr(proEntitlement.compactStatusTextKey),
+ style: proStatusPillStyle
+ )
+ .layoutPriority(1)
+ }
+
+ Text(settingsProHeaderText)
+ .font(.system(size: 13, weight: .medium))
+ .foregroundStyle(.secondary)
+ .lineLimit(2)
+ .fixedSize(horizontal: false, vertical: true)
+ .layoutPriority(2)
+
+ Spacer(minLength: 8)
+
+ if !proEntitlement.isUnlocked {
+ Button(unlockButtonTitle()) {
+ presentSettingsProPrompt(for: settingsProHeaderFeature)
+ }
+ .buttonStyle(.borderedProminent)
+ .controlSize(.small)
+ .layoutPriority(3)
+
+ Button(tr("pro.card.restore")) {
+ proEntitlement.restorePurchases()
+ }
+ .buttonStyle(.bordered)
+ .controlSize(.small)
+ .layoutPriority(3)
+ }
+ }
+ .padding(.horizontal, 16)
+ .padding(.vertical, 10)
+ .frame(width: dataPanelWidth, alignment: .leading)
+ .frame(minHeight: 44)
+ .background(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .fill(Color(nsColor: .controlBackgroundColor))
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .stroke(Color.secondary.opacity(0.16), lineWidth: 1)
+ )
+ }
+ .frame(maxWidth: .infinity, alignment: .center)
+ .padding(.top, 12)
+ .padding(.bottom, 10)
+ .background(Color(nsColor: .windowBackgroundColor))
+ }
+
+ private var proTabComparisonFeatures: [ProTabComparisonFeature] {
+ [
+ ProTabComparisonFeature(
+ title: tr("pro.feature.customTagColors"),
+ freeStatusKey: "settings.proStatus.unavailableFeature",
+ proLockedStatusKey: "settings.proStatus.lockedFeature",
+ proUnlockedStatusKey: "settings.proStatus.unlockedFeature",
+ freeStyle: .neutral,
+ proLockedStyle: .neutral,
+ proUnlockedStyle: .neutral
+ ),
+ ProTabComparisonFeature(
+ title: "\(tr("settings.coloredContainer")) / \(tr("settings.coloredGridContainer"))",
+ freeStatusKey: "settings.proStatus.previewFiveMinutes",
+ proLockedStatusKey: "settings.proStatus.lockedFeature",
+ proUnlockedStatusKey: "settings.proStatus.unlockedFeature",
+ freeStyle: .neutral,
+ proLockedStyle: .neutral,
+ proUnlockedStyle: .neutral
+ ),
+ ProTabComparisonFeature(
+ title: tr("pro.feature.themes"),
+ freeStatusKey: "settings.proStatus.previewFiveMinutes",
+ proLockedStatusKey: "settings.proStatus.lockedFeature",
+ proUnlockedStatusKey: "settings.proStatus.unlockedFeature",
+ freeStyle: .neutral,
+ proLockedStyle: .neutral,
+ proUnlockedStyle: .neutral
+ ),
+ ProTabComparisonFeature(
+ title: tr("pro.feature.customHotkeys"),
+ freeStatusKey: "settings.proStatus.unavailableFeature",
+ proLockedStatusKey: "settings.proStatus.lockedFeature",
+ proUnlockedStatusKey: "settings.proStatus.unlockedFeature",
+ freeStyle: .neutral,
+ proLockedStyle: .neutral,
+ proUnlockedStyle: .neutral
+ ),
+ ProTabComparisonFeature(
+ title: tr("settings.proFeature.appNotes"),
+ freeStatusKey: "settings.proStatus.freeNotes",
+ proLockedStatusKey: "settings.proStatus.unlimitedNotes",
+ proUnlockedStatusKey: "settings.proStatus.unlimitedNotes",
+ freeStyle: .neutral,
+ proLockedStyle: .neutral,
+ proUnlockedStyle: .neutral
+ ),
+ ProTabComparisonFeature(
+ title: tr("settings.proFeature.dataBackup"),
+ freeStatusKey: "settings.proStatus.unavailableFeature",
+ proLockedStatusKey: "settings.proStatus.lockedFeature",
+ proUnlockedStatusKey: "settings.proStatus.unlockedFeature",
+ freeStyle: .neutral,
+ proLockedStyle: .neutral,
+ proUnlockedStyle: .neutral
+ )
+ ]
+ }
+
+ private func proTabComparisonTable(width: CGFloat) -> some View {
+ VStack(alignment: .leading, spacing: 8) {
+ VStack(spacing: 8) {
+ HStack(spacing: 10) {
+ Text("")
+ .frame(maxWidth: .infinity, alignment: .leading)
+ Text(tr("settings.proCompare.free"))
+ .font(.system(size: 12, weight: .semibold))
+ .foregroundStyle(.secondary)
+ .frame(width: 118, alignment: .center)
+ HStack(spacing: 4) {
+ Image(systemName: "crown")
+ .font(.system(size: 12, weight: .semibold))
+ Text(tr("settings.proCompare.pro"))
+ .font(.system(size: 12, weight: .semibold))
+ }
+ .foregroundStyle(proAccentColor)
+ .lineLimit(1)
+ .minimumScaleFactor(0.82)
+ .frame(width: 118, alignment: .center)
+ }
+
+ ForEach(proTabComparisonFeatures) { feature in
+ let proStatusKey = proEntitlement.isUnlocked ? feature.proUnlockedStatusKey : feature.proLockedStatusKey
+ let proStyle = proEntitlement.isUnlocked ? feature.proUnlockedStyle : feature.proLockedStyle
+
+ HStack(alignment: .top, spacing: 10) {
+ Text(feature.title)
+ .font(.system(size: 12, weight: .medium))
+ .foregroundStyle(proAccentColor)
+ .lineLimit(2)
+ .fixedSize(horizontal: false, vertical: true)
+ .frame(maxWidth: .infinity, alignment: .leading)
+
+ ProStatusPill(
+ text: tr(feature.freeStatusKey),
+ style: feature.freeStyle,
+ compact: true
+ )
+ .frame(width: 118, alignment: .center)
+
+ ProStatusPill(
+ text: tr(proStatusKey),
+ style: proStyle,
+ compact: true
+ )
+ .frame(width: 118, alignment: .center)
+ }
+ .padding(.horizontal, 10)
+ .padding(.vertical, 8)
+ .background(
+ RoundedRectangle(cornerRadius: 8, style: .continuous)
+ .fill(Color(nsColor: .windowBackgroundColor).opacity(0.72))
+ )
+ }
+ }
+ }
+ .padding(.horizontal, 16)
+ .padding(.vertical, 14)
+ .frame(width: width, alignment: .leading)
+ .background(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .fill(Color(nsColor: .controlBackgroundColor))
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .stroke(Color.secondary.opacity(0.16), lineWidth: 1)
+ )
}
private var themeStatusSummary: String {
- if proEntitlement.isPreviewingTheme {
+ if proEntitlement.isPreviewingProAppearance {
if let countdown = themePreviewCountdownText {
return tr("pro.theme.status.previewCountdown")
.replacingOccurrences(of: "%time%", with: countdown)
@@ -714,6 +1041,15 @@
return
}
proEntitlement.startThemePreview(for: theme, tuning: currentThemeTuning(for: theme))
+ }
+
+ private func handleDisplayModeSelection(_ mode: String) {
+ if ProEntitlementPolicy.canUseDisplayMode(mode) {
+ proEntitlement.stopDisplayModePreview()
+ displayMode = mode
+ return
+ }
+ proEntitlement.startDisplayModePreview(for: mode)
}
private var activeColorTuningTheme: AppGridTheme? {
@@ -772,10 +1108,20 @@
if let preview = proEntitlement.themePreviewState?.theme, preview == theme {
return .countdown(text: themePreviewCountdownText ?? "00:00")
}
- if !proEntitlement.isUnlocked && theme.requiresPro {
+ if theme.requiresPro {
return .pill(text: tr("pro.card.badge"), style: .locked)
}
return effectiveAppGridTheme == theme ? .checkmark : .circle
+ }
+
+ private func displayModeOptionAccessory(for mode: String) -> ThemeOptionAccessory {
+ if proEntitlement.displayModePreviewState?.displayMode == mode {
+ return .countdown(text: themePreviewCountdownText ?? "00:00")
+ }
+ if ProEntitlementPolicy.isPremiumDisplayMode(mode) {
+ return .pill(text: tr("pro.card.badge"), style: .locked)
+ }
+ return effectiveDisplayMode == mode ? .checkmark : .circle
}
private func presentSettingsProPrompt(for feature: ProFeature) {
@@ -786,8 +1132,13 @@
}
private var themePreviewCountdownText: String? {
- guard let preview = proEntitlement.themePreviewState else { return nil }
- return Self.formatThemePreviewCountdown(seconds: preview.remainingSeconds(at: themePreviewNow))
+ if let preview = proEntitlement.themePreviewState {
+ return Self.formatThemePreviewCountdown(seconds: preview.remainingSeconds(at: themePreviewNow))
+ }
+ if let preview = proEntitlement.displayModePreviewState {
+ return Self.formatThemePreviewCountdown(seconds: preview.remainingSeconds(at: themePreviewNow))
+ }
+ return nil
}
private static func formatThemePreviewCountdown(seconds: Int) -> String {
@@ -797,9 +1148,13 @@
private func refreshThemePreviewCountdown(now: Date = Date()) {
themePreviewNow = now
- guard let preview = proEntitlement.themePreviewState else { return }
- if preview.remainingSeconds(at: now) <= 0 {
+ if let preview = proEntitlement.themePreviewState,
+ preview.remainingSeconds(at: now) <= 0 {
proEntitlement.stopThemePreview()
+ }
+ if let preview = proEntitlement.displayModePreviewState,
+ preview.remainingSeconds(at: now) <= 0 {
+ proEntitlement.stopDisplayModePreview()
}
}
@@ -811,11 +1166,18 @@
}
private func handleProAccessStateChange(_ newState: ProAccessState) {
- guard newState.isUnlocked else { return }
+ guard newState.isUnlocked else {
+ stopHotkeyRecording(showCancelledToast: false)
+ return
+ }
if let preview = proEntitlement.themePreviewState {
appGridThemeID = preview.theme.rawValue
persistThemeTuning(preview.themeTuning, for: preview.theme)
proEntitlement.stopThemePreview()
+ }
+ if let preview = proEntitlement.displayModePreviewState {
+ displayMode = preview.displayMode
+ proEntitlement.stopDisplayModePreview()
}
if settingsProPromptFeature != nil {
dismissSettingsProPrompt()
@@ -941,7 +1303,8 @@
displayText: LauncherHotkeySettings.effectiveHotkey(for: .main).displayString,
statusText: hotkeyStatusText(for: .main),
statusTone: hotkeyStatusTone(for: .main),
- customizeTitle: proEntitlement.isUnlocked ? tr("hotkeys.customize") : tr("pro.card.badge"),
+ customizeTitle: tr("hotkeys.customize"),
+ proBadgeTitle: tr("pro.card.badge"),
restoreTitle: tr("hotkeys.restoreDefault"),
isRecording: recordingHotkeyKind == .main,
isProLocked: !proEntitlement.isUnlocked,
@@ -964,7 +1327,8 @@
displayText: LauncherHotkeySettings.effectiveHotkey(for: .quickSearch).displayString,
statusText: hotkeyStatusText(for: .quickSearch),
statusTone: hotkeyStatusTone(for: .quickSearch),
- customizeTitle: proEntitlement.isUnlocked ? tr("hotkeys.customize") : tr("pro.card.badge"),
+ customizeTitle: tr("hotkeys.customize"),
+ proBadgeTitle: tr("pro.card.badge"),
restoreTitle: tr("hotkeys.restoreDefault"),
isRecording: recordingHotkeyKind == .quickSearch,
isProLocked: !proEntitlement.isUnlocked,
@@ -984,21 +1348,24 @@
.id(hotkeySettingsRefreshToken)
}
+ @ViewBuilder
private var themeProStatusRow: some View {
- HStack(spacing: 12) {
- ProStatusPill(
- text: tr(proEntitlement.compactStatusTextKey),
- style: proStatusPillStyle
- )
+ if proEntitlement.isUnlocked {
+ proUnlockedBenefitLine("pro.theme.status.unlocked", bottomPadding: 0)
+ } else {
+ HStack(spacing: 12) {
+ ProStatusPill(
+ text: tr(proEntitlement.compactStatusTextKey),
+ style: proStatusPillStyle
+ )
- Text(themeStatusSummary)
- .font(.system(size: 13, weight: .medium))
- .foregroundStyle(.secondary)
- .fixedSize(horizontal: false, vertical: true)
+ Text(themeStatusSummary)
+ .font(.system(size: 13, weight: .medium))
+ .foregroundStyle(.secondary)
+ .fixedSize(horizontal: false, vertical: true)
- Spacer(minLength: 0)
+ Spacer(minLength: 0)
- if !proEntitlement.isUnlocked {
Button(unlockButtonTitle()) {
presentSettingsProPrompt(for: .premiumThemes)
}
@@ -1009,77 +1376,21 @@
}
.buttonStyle(.bordered)
}
+ .padding(.horizontal, 16)
+ .padding(.vertical, 14)
+ .background(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .fill(Color(nsColor: .controlBackgroundColor))
+ )
+ .overlay(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .stroke(Color.secondary.opacity(0.16), lineWidth: 1)
+ )
}
- .padding(.horizontal, 16)
- .padding(.vertical, 14)
- .background(
- RoundedRectangle(cornerRadius: 10, style: .continuous)
- .fill(Color(nsColor: .controlBackgroundColor))
- )
- .overlay(
- RoundedRectangle(cornerRadius: 10, style: .continuous)
- .stroke(Color.secondary.opacity(0.16), lineWidth: 1)
- )
- }
-
- private var proStatusCard: some View {
- HStack(alignment: .top, spacing: 18) {
- VStack(alignment: .leading, spacing: 10) {
- HStack(spacing: 10) {
- Text(proCardTitle)
- .font(.system(size: 20, weight: .bold))
- ProStatusPill(
- text: tr(proEntitlement.compactStatusTextKey),
- style: proStatusPillStyle
- )
- }
-
- Text(proCardSummary)
- .font(.system(size: 13, weight: .medium))
- .foregroundStyle(.secondary)
- .lineSpacing(2)
- .fixedSize(horizontal: false, vertical: true)
-
- }
-
- Spacer(minLength: 16)
-
- VStack(alignment: .trailing, spacing: 10) {
- if !proEntitlement.isUnlocked {
- Button(unlockButtonTitle()) {
- proEntitlement.purchasePro()
- }
- .buttonStyle(.borderedProminent)
- }
-
- Button(tr("pro.card.restore")) {
- proEntitlement.restorePurchases()
- }
- .buttonStyle(.bordered)
-
- if let statusKey = proEntitlement.operationState.statusMessageKey {
- Text(tr(statusKey))
- .font(.caption)
- .foregroundStyle(.secondary)
- .multilineTextAlignment(.trailing)
- }
- }
- }
- .padding(.horizontal, 20)
- .padding(.vertical, 18)
- .frame(width: dataPanelWidth, alignment: .leading)
- .background(
- RoundedRectangle(cornerRadius: 12, style: .continuous)
- .fill(Color(nsColor: .controlBackgroundColor))
- )
- .overlay(
- RoundedRectangle(cornerRadius: 12, style: .continuous)
- .stroke(Color.secondary.opacity(0.18), lineWidth: 1)
- )
}
private var settingsTabBar: some View {
- HStack(spacing: 8) {
+ HStack(spacing: 6) {
ForEach(SettingsTab.allCases) { tab in
settingsTabButton(tab)
}
@@ -1096,17 +1407,17 @@
} label: {
VStack(spacing: 5) {
Image(systemName: tab.systemImage)
- .font(.system(size: 25, weight: .regular))
+ .font(.system(size: 24, weight: .regular))
.symbolRenderingMode(.hierarchical)
- .frame(width: 32, height: 32)
+ .frame(width: 30, height: 30)
Text(tr(tab.titleKey))
- .font(.system(size: 13, weight: .semibold))
+ .font(.system(size: 12, weight: .semibold))
.lineLimit(2)
.multilineTextAlignment(.center)
.minimumScaleFactor(0.8)
}
.foregroundStyle(isSelected ? Color.accentColor : Color.secondary)
- .frame(width: 108, height: 74)
+ .frame(width: 94, height: 72)
.background(
RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(isSelected ? Color.accentColor.opacity(0.10) : Color.clear)
@@ -1127,18 +1438,14 @@
VStack(spacing: 0) {
settingsTabBar
Divider()
+ if shouldShowSettingsFixedProHeader {
+ settingsFixedProHeader
+ }
Group {
switch selectedTab {
case .language:
// Tab 1: Language
- VStack(alignment: .leading, spacing: 10) {
- Text(tr("settings.language"))
- .font(.headline)
- Text(tr("settings.languageDesc"))
- .font(.caption)
- .foregroundStyle(.secondary)
-
- ScrollView {
+ centeredSettingsScrollContent(width: settingsContentWidth) {
LazyVGrid(columns: languageColumns, alignment: .leading, spacing: 6) {
Button {
selectedLanguage = L10n.automaticCode
@@ -1188,11 +1495,7 @@
}
}
.padding(.vertical, 4)
- }
- .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
}
- .frame(maxWidth: settingsContentWidth, alignment: .leading)
- .padding()
case .general:
// Tab 2: General
@@ -1231,9 +1534,10 @@
DisplayModeOptionButton(
mode: "flat",
title: tr("settings.flat"),
- isSelected: displayMode == "flat"
+ isSelected: effectiveDisplayMode == "flat",
+ accessory: displayModeOptionAccessory(for: "flat")
) {
- displayMode = "flat"
+ handleDisplayModeSelection("flat")
}
LazyVGrid(columns: displayModeColumns, alignment: .leading, spacing: 8) {
@@ -1241,9 +1545,10 @@
DisplayModeOptionButton(
mode: option.id,
title: option.title,
- isSelected: displayMode == option.id
+ isSelected: effectiveDisplayMode == option.id,
+ accessory: displayModeOptionAccessory(for: option.id)
) {
- displayMode = option.id
+ handleDisplayModeSelection(option.id)
}
}
}
@@ -1291,8 +1596,6 @@
case .theme:
ScrollView(.vertical, showsIndicators: true) {
VStack(alignment: .leading, spacing: 18) {
- themeProStatusRow
-
LazyVGrid(columns: themeColumns, alignment: .leading, spacing: 12) {
ForEach(AppGridTheme.settingsDisplayOrder) { theme in
ThemeOptionButton(
@@ -1331,7 +1634,10 @@
VStack(spacing: 0) {
TagEditorView(
tagColors: $tagColors,
+ tagCustomColors: $tagCustomColors,
excludedTagNames: ["Mac自带", defaultGroupName],
+ isCustomColorUnlocked: proEntitlement.isUnlocked,
+ onLockedCustomColor: { presentSettingsProPrompt(for: .customTagColors) },
onRefresh: { scanApps() }
)
}
@@ -1339,226 +1645,214 @@
case .data:
// Tab 5: Data
- VStack(spacing: 0) {
- Spacer(minLength: 36)
+ ScrollView(.vertical, showsIndicators: true) {
+ VStack(spacing: 18) {
+ VStack(alignment: .center, spacing: 24) {
+ dataSection(minHeight: 124) {
+ HStack(alignment: .center, spacing: 12) {
+ dataSectionTitle(tr("settings.initialLayout"))
- VStack(alignment: .center, spacing: 24) {
- dataSection(minHeight: 124) {
- HStack(alignment: .center, spacing: 12) {
- dataSectionTitle(tr("settings.initialLayout"))
+ HStack(spacing: 22) {
+ initialLayoutOption(
+ tr("settings.initialLayoutUncategorized"),
+ mode: .uncategorized
+ )
+ initialLayoutOption(
+ tr("settings.initialLayoutSmart"),
+ mode: .smart
+ )
+ }
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .layoutPriority(1)
- HStack(spacing: 22) {
- initialLayoutOption(
- tr("settings.initialLayoutUncategorized"),
- mode: .uncategorized
+ dataActionButton(
+ tr("settings.applyScheme"),
+ prominent: true,
+ enabled: !isApplyingSystemScheme && !isResettingToUncategorized,
+ action: applySelectedInitialLayout
)
- initialLayoutOption(
- tr("settings.initialLayoutSmart"),
- mode: .smart
- )
+ .frame(width: dataActionWidth, alignment: .trailing)
+ .layoutPriority(2)
}
+ }
+
+ dataSection(minHeight: 190) {
+ HStack(alignment: .top, spacing: 12) {
+ dataSectionTitle(tr("settings.customLayout"))
+ .padding(.top, 4)
+
+ VStack(alignment: .leading, spacing: 10) {
+ HStack(alignment: .firstTextBaseline, spacing: 8) {
+ Text(tr("settings.previousScheme"))
+ .font(.system(size: 13, weight: .semibold))
+ .foregroundStyle(.secondary)
+ .lineLimit(1)
+ .minimumScaleFactor(0.82)
+ Text(previousCategorySchemeName)
+ .font(.system(size: 13, weight: .medium))
+ .foregroundStyle(canRestorePreviousScheme ? .primary : .tertiary)
+ .lineLimit(1)
+ .truncationMode(.middle)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ }
+
+ HStack(alignment: .firstTextBaseline, spacing: 8) {
+ Text(tr("settings.currentScheme"))
+ .font(.system(size: 13, weight: .semibold))
+ .foregroundStyle(.secondary)
+ .lineLimit(1)
+ .minimumScaleFactor(0.82)
+ Text(currentCategorySchemeName)
+ .font(.system(size: 13, weight: .medium))
+ .foregroundStyle(.primary)
+ .lineLimit(1)
+ .truncationMode(.middle)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ }
+
+ Divider().opacity(0.35)
+ .padding(.top, 2)
+
+ VStack(alignment: .center, spacing: 8) {
+ HStack(spacing: 12) {
+ Button {
+ exportTags()
+ } label: {
+ HStack(spacing: 8) {
+ Text(tr("settings.export"))
+ ProStatusPill(text: tr("pro.card.badge"), style: .locked, compact: true)
+ }
+ }
+ .buttonStyle(.bordered)
+ .disabled(isDataFilePanelPresented)
+ Button {
+ importTags()
+ } label: {
+ HStack(spacing: 8) {
+ Text(tr("settings.import"))
+ ProStatusPill(text: tr("pro.card.badge"), style: .locked, compact: true)
+ }
+ }
+ .buttonStyle(.bordered)
+ .disabled(isDataFilePanelPresented)
+ }
+ Text(tr("settings.backupDesc"))
+ .font(.caption)
+ .foregroundStyle(.secondary)
+ .multilineTextAlignment(.center)
+ .fixedSize(horizontal: false, vertical: true)
+ .frame(maxWidth: dataPanelWidth - dataLabelWidth - dataActionWidth - 92, alignment: .center)
+ }
+ .frame(maxWidth: .infinity, alignment: .center)
+ }
.frame(maxWidth: .infinity, alignment: .leading)
.layoutPriority(1)
- dataActionButton(
- tr("settings.applyScheme"),
- prominent: true,
- enabled: !isApplyingSystemScheme && !isResettingToUncategorized,
- action: applySelectedInitialLayout
- )
- .frame(width: dataActionWidth, alignment: .trailing)
- .layoutPriority(2)
- }
- }
-
- dataSection(minHeight: 190) {
- HStack(alignment: .top, spacing: 12) {
- dataSectionTitle(tr("settings.customLayout"))
- .padding(.top, 4)
-
- VStack(alignment: .leading, spacing: 10) {
- HStack(alignment: .firstTextBaseline, spacing: 8) {
- Text(tr("settings.previousScheme"))
- .font(.system(size: 13, weight: .semibold))
- .foregroundStyle(.secondary)
- .lineLimit(1)
- .minimumScaleFactor(0.82)
- Text(previousCategorySchemeName)
- .font(.system(size: 13, weight: .medium))
- .foregroundStyle(canRestorePreviousScheme ? .primary : .tertiary)
- .lineLimit(1)
- .truncationMode(.middle)
- .frame(maxWidth: .infinity, alignment: .leading)
- }
-
- HStack(alignment: .firstTextBaseline, spacing: 8) {
- Text(tr("settings.currentScheme"))
- .font(.system(size: 13, weight: .semibold))
- .foregroundStyle(.secondary)
- .lineLimit(1)
- .minimumScaleFactor(0.82)
- Text(currentCategorySchemeName)
- .font(.system(size: 13, weight: .medium))
- .foregroundStyle(.primary)
- .lineLimit(1)
- .truncationMode(.middle)
- .frame(maxWidth: .infinity, alignment: .leading)
- }
-
- Divider().opacity(0.35)
- .padding(.top, 2)
-
- VStack(alignment: .center, spacing: 8) {
- HStack(spacing: 12) {
- Button {
- exportTags()
- } label: {
- HStack(spacing: 8) {
- Text(tr("settings.export"))
- if !proEntitlement.isUnlocked {
- ProStatusPill(text: tr("pro.card.badge"), style: .locked, compact: true)
- }
- }
- }
- .buttonStyle(.bordered)
- .disabled(isDataFilePanelPresented)
- Button {
- importTags()
- } label: {
- HStack(spacing: 8) {
- Text(tr("settings.import"))
- if !proEntitlement.isUnlocked {
- ProStatusPill(text: tr("pro.card.badge"), style: .locked, compact: true)
- }
- }
- }
- .buttonStyle(.bordered)
- .disabled(isDataFilePanelPresented)
- }
- Text(tr("settings.backupDesc"))
- .font(.caption)
- .foregroundStyle(.secondary)
- .multilineTextAlignment(.center)
- .fixedSize(horizontal: false, vertical: true)
- .frame(maxWidth: dataPanelWidth - dataLabelWidth - dataActionWidth - 92, alignment: .center)
- }
- .frame(maxWidth: .infinity, alignment: .center)
+ dataActionButton(
+ tr("settings.restorePreviousScheme"),
+ prominent: false,
+ enabled: canRestorePreviousScheme,
+ action: restorePreviousCategoryScheme
+ )
+ .frame(width: dataActionWidth, alignment: .trailing)
+ .layoutPriority(2)
}
- .frame(maxWidth: .infinity, alignment: .leading)
- .layoutPriority(1)
-
- dataActionButton(
- tr("settings.restorePreviousScheme"),
- prominent: false,
- enabled: canRestorePreviousScheme,
- action: restorePreviousCategoryScheme
- )
- .frame(width: dataActionWidth, alignment: .trailing)
- .layoutPriority(2)
}
}
- }
- .frame(width: dataPanelWidth, alignment: .center)
+ .frame(width: dataPanelWidth, alignment: .center)
- Spacer(minLength: 30)
+ HStack(alignment: .center, spacing: 14) {
+ Text(tr("settings.bubbleDisplayScope"))
+ .font(.system(size: 13, weight: .medium))
+ .frame(width: 190, alignment: .trailing)
- HStack(alignment: .center, spacing: 14) {
- Text(tr("settings.bubbleDisplayScope"))
- .font(.system(size: 13, weight: .medium))
- .frame(width: 190, alignment: .trailing)
-
- HStack(spacing: 20) {
- bubbleScopeOption(
- tr("settings.bubbleAllApps"),
- isSelected: !showUncommonAppBubbles
- ) {
- showUncommonAppBubbles = false
+ HStack(spacing: 20) {
+ bubbleScopeOption(
+ tr("settings.bubbleAllApps"),
+ isSelected: !showUncommonAppBubbles
+ ) {
+ showUncommonAppBubbles = false
+ }
+ bubbleScopeOption(
+ tr("settings.bubbleUncommonOnly"),
+ isSelected: showUncommonAppBubbles
+ ) {
+ showUncommonAppBubbles = true
+ }
}
- bubbleScopeOption(
- tr("settings.bubbleUncommonOnly"),
- isSelected: showUncommonAppBubbles
- ) {
- showUncommonAppBubbles = true
- }
+ .frame(width: 300, alignment: .leading)
}
- .frame(width: 300, alignment: .leading)
+ .frame(width: 520, alignment: .center)
}
- .frame(width: 520, alignment: .center)
-
- Spacer(minLength: 18)
+ .frame(maxWidth: dataPanelWidth, alignment: .center)
+ .padding()
}
- .padding()
.onAppear { refreshDataState() }
- case .about:
- // Tab 6: About
- VStack(spacing: 0) {
- Spacer(minLength: 44)
-
- VStack(alignment: .center, spacing: 24) {
- proStatusCard
-
- HStack(alignment: .center, spacing: 24) {
- if let icon = NSImage(named: NSImage.applicationIconName) {
- Image(nsImage: icon)
- .resizable()
- .frame(width: 112, height: 112)
- }
- VStack(alignment: .leading, spacing: 4) {
- Text("TagLauncher")
- .font(.title2)
- .fontWeight(.semibold)
- Text(tr("app.description"))
- .font(.body)
- .foregroundStyle(.secondary)
- Text("\(tr("app.version")) \(appVersion) (\(tr("app.build")) \(buildVersion))")
- .font(.callout)
- .foregroundStyle(.tertiary)
-
- Divider()
- .padding(.vertical, 4)
-
- HStack(spacing: 8) {
- Button {
- NSWorkspace.shared.open(helpPDFURL)
- } label: {
- Label(tr("help.openPDF"), systemImage: "questionmark.circle")
- }
- .buttonStyle(.borderedProminent)
- .controlSize(.regular)
-
- Button {
- NSPasteboard.general.clearContents()
- NSPasteboard.general.setString(helpPDFURL.absoluteString, forType: .string)
- } label: {
- Image(systemName: "link")
- }
- .buttonStyle(.bordered)
- .controlSize(.regular)
- .help(tr("help.copyLink"))
- }
-
- Text(tr("help.currentLanguage"))
- .font(.caption)
- .foregroundStyle(.secondary)
- .padding(.bottom, 2)
-
- Text("万物之中,希望最美")
- .font(.caption)
- .foregroundStyle(.secondary)
- Text("永桔@shanghai3168@gmail.com")
- .font(.caption)
- .foregroundStyle(.secondary)
- }
- }
- .frame(width: dataPanelWidth, alignment: .leading)
- }
- .frame(width: dataPanelWidth, alignment: .center)
-
- Spacer(minLength: 30)
- Spacer(minLength: 18)
+ case .pro:
+ // Tab 6: Pro
+ centeredSettingsScrollContent(width: dataPanelWidth) {
+ proTabComparisonTable(width: dataPanelWidth)
}
- .padding()
+
+ case .about:
+ // Tab 7: About
+ centeredSettingsScrollContent(width: dataPanelWidth) {
+ HStack(alignment: .center, spacing: 24) {
+ if let icon = NSImage(named: NSImage.applicationIconName) {
+ Image(nsImage: icon)
+ .resizable()
+ .frame(width: 112, height: 112)
+ }
+ VStack(alignment: .leading, spacing: 4) {
+ Text("TagLauncher")
+ .font(.title2)
+ .fontWeight(.semibold)
+ Text(tr("app.description"))
+ .font(.body)
+ .foregroundStyle(.secondary)
+ Text("\(tr("app.version")) \(appVersion) (\(tr("app.build")) \(buildVersion))")
+ .font(.callout)
+ .foregroundStyle(.tertiary)
+
+ Divider()
+ .padding(.vertical, 4)
+
+ HStack(spacing: 8) {
+ Button {
+ NSWorkspace.shared.open(helpPDFURL)
+ } label: {
+ Label(tr("help.openPDF"), systemImage: "questionmark.circle")
+ }
+ .buttonStyle(.borderedProminent)
+ .controlSize(.regular)
+
+ Button {
+ NSPasteboard.general.clearContents()
+ NSPasteboard.general.setString(helpPDFURL.absoluteString, forType: .string)
+ } label: {
+ Image(systemName: "link")
+ }
+ .buttonStyle(.bordered)
+ .controlSize(.regular)
+ .help(tr("help.copyLink"))
+ }
+
+ Text(tr("help.currentLanguage"))
+ .font(.caption)
+ .foregroundStyle(.secondary)
+ .padding(.bottom, 2)
+
+ Text("万物之中,希望最美")
+ .font(.caption)
+ .foregroundStyle(.secondary)
+ Text("永桔@shanghai3168@gmail.com")
+ .font(.caption)
+ .foregroundStyle(.secondary)
+ }
+ .frame(maxWidth: 520, alignment: .leading)
+ }
+ }
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
@@ -1581,6 +1875,11 @@
}
.onChange(of: proEntitlement.accessState) { _, newState in
handleProAccessStateChange(newState)
+ }
+ .onChange(of: selectedTab) { _, newTab in
+ if newTab != .hotkeys {
+ stopHotkeyRecording(showCancelledToast: false)
+ }
}
if isRefreshingLanguage {
@@ -1704,6 +2003,17 @@
}
}
+private struct ProTabComparisonFeature: Identifiable {
+ var id: String { title }
+ let title: String
+ let freeStatusKey: String
+ let proLockedStatusKey: String
+ let proUnlockedStatusKey: String
+ let freeStyle: ProStatusPillStyle
+ let proLockedStyle: ProStatusPillStyle
+ let proUnlockedStyle: ProStatusPillStyle
+}
+
private enum HotkeyStatusTone {
case active
case warning
@@ -1771,6 +2081,7 @@
let statusText: String
let statusTone: HotkeyStatusTone
let customizeTitle: String
+ let proBadgeTitle: String
let restoreTitle: String
let isRecording: Bool
let isProLocked: Bool
@@ -1805,12 +2116,17 @@
.font(.system(size: 11, weight: .semibold))
.foregroundStyle(.blue)
}
+
+ if !isProLocked {
+ ProStatusPill(text: proBadgeTitle, style: .locked, compact: true)
+ }
}
}
.frame(width: 156, alignment: .leading)
HotkeyPrimaryActionButton(
title: customizeTitle,
+ proBadgeTitle: proBadgeTitle,
isProLocked: isProLocked,
action: onCustomize
)
@@ -1853,14 +2169,25 @@
private struct HotkeyPrimaryActionButton: View {
let title: String
+ let proBadgeTitle: String
let isProLocked: Bool
let action: () -> Void
var body: some View {
- Button(action: action) {
- if isProLocked {
- ProStatusPill(text: title, style: .locked, compact: true)
- } else {
+ if isProLocked {
+ Button(action: action) {
+ HStack(spacing: 8) {
+ Text(title)
+ .lineLimit(1)
+ .minimumScaleFactor(0.82)
+
+ ProStatusPill(text: proBadgeTitle, style: .locked, compact: true)
+ }
+ }
+ .buttonStyle(.bordered)
+ .contentShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
+ } else {
+ Button(action: action) {
Text(title)
.font(.system(size: 11, weight: .semibold))
.foregroundStyle(Color.white)
@@ -1872,9 +2199,9 @@
.fill(Color.accentColor)
)
}
+ .buttonStyle(.plain)
+ .contentShape(Capsule(style: .continuous))
}
- .buttonStyle(.plain)
- .contentShape(Capsule(style: .continuous))
}
}
@@ -2110,22 +2437,27 @@
let mode: String
let title: String
let isSelected: Bool
+ let accessory: ThemeOptionAccessory
let action: () -> Void
var body: some View {
Button(action: action) {
- HStack(spacing: 7) {
+ HStack(spacing: 8) {
DisplayModeGlyph(mode: mode, isSelected: isSelected)
.frame(width: 24, height: 18)
Text(title)
.font(.system(size: 13, weight: .semibold))
- .multilineTextAlignment(.center)
+ .multilineTextAlignment(.leading)
.lineLimit(2)
.minimumScaleFactor(0.82)
.foregroundStyle(isSelected ? Color.white : Color.primary)
- .frame(maxWidth: .infinity)
+ .frame(maxWidth: .infinity, alignment: .leading)
+ .layoutPriority(1)
+
+ accessoryView
+ .frame(width: 64, alignment: .trailing)
}
- .frame(maxWidth: .infinity, minHeight: 34)
+ .frame(maxWidth: .infinity, minHeight: 38)
.padding(.horizontal, 9)
.padding(.vertical, 2)
.background(
@@ -2141,6 +2473,39 @@
.buttonStyle(.plain)
.accessibilityLabel(title)
}
+
+ @ViewBuilder
+ private var accessoryView: some View {
+ switch accessory {
+ case .checkmark:
+ Image(systemName: "checkmark.circle.fill")
+ .font(.system(size: 16, weight: .semibold))
+ .foregroundStyle(isSelected ? Color.white : Color.accentColor)
+ case .circle:
+ Image(systemName: "circle")
+ .font(.system(size: 16, weight: .semibold))
+ .foregroundStyle(isSelected ? Color.white.opacity(0.74) : Color.secondary.opacity(0.42))
+ .opacity(0.001)
+ case .countdown(let text):
+ Text(text)
+ .font(.system(size: 10, weight: .semibold, design: .monospaced))
+ .foregroundStyle(Color(red: 0.30, green: 0.22, blue: 0.08))
+ .lineLimit(1)
+ .frame(minWidth: 42)
+ .padding(.horizontal, 8)
+ .padding(.vertical, 4)
+ .background(
+ Capsule(style: .continuous)
+ .fill(Color.orange.opacity(0.14))
+ )
+ .overlay(
+ Capsule(style: .continuous)
+ .stroke(Color.orange.opacity(0.28), lineWidth: 1)
+ )
+ case .pill(let text, let style):
+ ProStatusPill(text: text, style: style, compact: true)
+ }
+ }
}
private struct DisplayModeGlyph: View {
diff --git a/src/Apptag/ProAccessViews.swift b/src/Apptag/ProAccessViews.swift
index dda089c..49b65d1 100644
--- a/src/Apptag/ProAccessViews.swift
+++ b/src/Apptag/ProAccessViews.swift
@@ -79,7 +79,7 @@
private var showsCrown: Bool {
switch style {
case .locked, .unlocked, .legacy:
- return text.localizedCaseInsensitiveContains("Pro")
+ return true
case .preview, .neutral:
return false
}
@@ -95,6 +95,8 @@
return "pro.prompt.import"
case .layoutExport:
return "pro.prompt.export"
+ case .customTagColors:
+ return "pro.prompt.customTagColors"
case .unlimitedNotes:
return "pro.prompt.notes"
case .persistentAppSorting:
diff --git a/src/Apptag/ProEntitlement.swift b/src/Apptag/ProEntitlement.swift
index 3267c3e..1674af4 100644
--- a/src/Apptag/ProEntitlement.swift
+++ b/src/Apptag/ProEntitlement.swift
@@ -6,6 +6,7 @@
case premiumThemes
case layoutImport
case layoutExport
+ case customTagColors
case unlimitedNotes
case persistentAppSorting
case customHotkeys
@@ -18,6 +19,8 @@
return "pro.feature.import"
case .layoutExport:
return "pro.feature.export"
+ case .customTagColors:
+ return "pro.feature.customTagColors"
case .unlimitedNotes:
return "pro.feature.notes"
case .persistentAppSorting:
@@ -35,6 +38,8 @@
return "pro.feature.import.benefit"
case .layoutExport:
return "pro.feature.export.benefit"
+ case .customTagColors:
+ return "pro.feature.customTagColors.benefit"
case .unlimitedNotes:
return "pro.feature.notes.benefit"
case .persistentAppSorting:
@@ -109,6 +114,16 @@
}
}
+struct ProDisplayModePreviewState: Equatable {
+ let displayMode: String
+ let startedAt: Date
+ let endsAt: Date
+
+ func remainingSeconds(at date: Date = Date()) -> Int {
+ max(0, Int(ceil(endsAt.timeIntervalSince(date))))
+ }
+}
+
struct ProNoteQuotaStatus: Equatable {
let isUnlimited: Bool
let used: Int
@@ -131,7 +146,7 @@
static let legacyFallbackOriginalPurchaseDateISO8601: String? = nil
static let freeThemes: Set<AppGridTheme> = [.defaultLight, .black]
- static let freeNoteLimit = 5
+ static let freeNoteLimit = 3
static let defaultThemePreviewDuration: TimeInterval = 5 * 60
static let qaStateEnvKey = "TAGLAUNCHER_QA_PRO_STATE"
@@ -170,6 +185,7 @@
var accessState: ProAccessState = .free
var previewThemeID: String? = nil
var previewThemeTuning: Double? = nil
+ var previewDisplayMode: String? = nil
}
private enum ProEntitlementSnapshotStore {
@@ -191,6 +207,8 @@
}
enum ProEntitlementPolicy {
+ static let premiumDisplayModes: Set<String> = ["coloredContainer", "coloredGridContainer"]
+
static func accessState() -> ProAccessState {
ProEntitlementSnapshotStore.read().accessState
}
@@ -207,13 +225,44 @@
static func isUnlocked(_ feature: ProFeature) -> Bool {
switch feature {
- case .premiumThemes, .layoutImport, .layoutExport, .unlimitedNotes, .persistentAppSorting, .customHotkeys:
+ case .premiumThemes, .layoutImport, .layoutExport, .customTagColors, .unlimitedNotes, .persistentAppSorting, .customHotkeys:
return accessState().isUnlocked
}
}
static func canUseTheme(_ theme: AppGridTheme) -> Bool {
ProEntitlementConfig.freeThemes.contains(theme) || isUnlocked(.premiumThemes)
+ }
+
+ static func isPremiumDisplayMode(_ displayMode: String) -> Bool {
+ premiumDisplayModes.contains(displayMode)
+ }
+
+ static func canUseDisplayMode(_ displayMode: String) -> Bool {
+ !isPremiumDisplayMode(displayMode) || isUnlocked(.premiumThemes)
+ }
+
+ static func fallbackDisplayMode(for displayMode: String) -> String {
+ switch displayMode {
+ case "coloredContainer":
+ return "container"
+ case "coloredGridContainer":
+ return "gridContainer"
+ default:
+ return displayMode
+ }
+ }
+
+ static func effectiveDisplayMode(for storedDisplayMode: String) -> String {
+ let snapshot = ProEntitlementSnapshotStore.read()
+ if let previewDisplayMode = snapshot.previewDisplayMode,
+ isPremiumDisplayMode(previewDisplayMode) {
+ return previewDisplayMode
+ }
+ guard canUseDisplayMode(storedDisplayMode) else {
+ return fallbackDisplayMode(for: storedDisplayMode)
+ }
+ return storedDisplayMode
}
static func effectiveTheme(for storedTheme: AppGridTheme) -> AppGridTheme {
@@ -305,17 +354,20 @@
@Published private(set) var operationState: ProOperationState = .idle
@Published private(set) var priceDisplayText: String? = nil
@Published private(set) var themePreviewState: ProThemePreviewState? = nil
+ @Published private(set) var displayModePreviewState: ProDisplayModePreviewState? = nil
private var hasStarted = false
private var cachedProduct: Product?
private var updateTask: Task<Void, Never>?
private var themePreviewTask: Task<Void, Never>?
+ private var displayModePreviewTask: Task<Void, Never>?
private init() {}
deinit {
updateTask?.cancel()
themePreviewTask?.cancel()
+ displayModePreviewTask?.cancel()
}
var isUnlocked: Bool {
@@ -326,8 +378,12 @@
themePreviewState != nil
}
+ var isPreviewingProAppearance: Bool {
+ themePreviewState != nil || displayModePreviewState != nil
+ }
+
var compactStatusTextKey: String {
- if themePreviewState != nil {
+ if isPreviewingProAppearance {
return "pro.theme.preview.status"
}
switch accessState {
@@ -425,6 +481,7 @@
guard !ProEntitlementConfig.freeThemes.contains(theme) else { return }
guard !accessState.isUnlocked else { return }
+ stopDisplayModePreview()
themePreviewTask?.cancel()
let preview = ProThemePreviewState(
@@ -462,6 +519,35 @@
themePreviewTask?.cancel()
themePreviewTask = nil
applyThemePreview(nil)
+ }
+
+ func startDisplayModePreview(for displayMode: String) {
+ guard ProEntitlementPolicy.isPremiumDisplayMode(displayMode) else { return }
+ guard !accessState.isUnlocked else { return }
+
+ stopThemePreview()
+ displayModePreviewTask?.cancel()
+
+ let now = Date()
+ let preview = ProDisplayModePreviewState(
+ displayMode: displayMode,
+ startedAt: now,
+ endsAt: now.addingTimeInterval(ProEntitlementConfig.themePreviewDuration)
+ )
+ applyDisplayModePreview(preview)
+
+ displayModePreviewTask = Task { [weak self] in
+ let duration = max(1, ProEntitlementConfig.themePreviewDuration)
+ try? await Task.sleep(nanoseconds: UInt64(duration * 1_000_000_000))
+ guard !Task.isCancelled else { return }
+ self?.stopDisplayModePreview()
+ }
+ }
+
+ func stopDisplayModePreview() {
+ displayModePreviewTask?.cancel()
+ displayModePreviewTask = nil
+ applyDisplayModePreview(nil)
}
private func startTransactionUpdates() {
@@ -604,6 +690,13 @@
}
}
+ private func applyDisplayModePreview(_ preview: ProDisplayModePreviewState?) {
+ displayModePreviewState = preview
+ ProEntitlementSnapshotStore.update { snapshot in
+ snapshot.previewDisplayMode = preview?.displayMode
+ }
+ }
+
private var cacheURL: URL {
AppIdentity.applicationSupportDirectory
.appendingPathComponent("pro-entitlement-cache.json")
diff --git a/src/Apptag/QuickSearch.swift b/src/Apptag/QuickSearch.swift
index 5678234..c7b25eb 100644
--- a/src/Apptag/QuickSearch.swift
+++ b/src/Apptag/QuickSearch.swift
@@ -852,6 +852,7 @@
if panel.frame != frame {
panel.setFrame(frame, display: true)
}
+ NSApp.activate(ignoringOtherApps: true)
panel.makeKeyAndOrderFront(nil)
panel.orderFrontRegardless()
}
@@ -876,7 +877,7 @@
let panel = QuickSearchPanel(
contentRect: .zero,
- styleMask: [.borderless, .fullSizeContentView, .nonactivatingPanel],
+ styleMask: [.borderless, .fullSizeContentView],
backing: .buffered,
defer: false
)
@@ -947,8 +948,52 @@
override var canBecomeKey: Bool { true }
override var canBecomeMain: Bool { false }
+ override func sendEvent(_ event: NSEvent) {
+ if event.type == .leftMouseDown,
+ let row = quickSearchResultRow(at: event.locationInWindow) {
+ row.launchFromMouseClick()
+ return
+ }
+ super.sendEvent(event)
+ }
+
override func constrainFrameRect(_ frameRect: NSRect, to screen: NSScreen?) -> NSRect {
frameRect
+ }
+
+ private func quickSearchResultRow(at windowPoint: NSPoint) -> QuickSearchResultRowView? {
+ guard let contentView else { return nil }
+ if let row = contentView.quickSearchResultRowFromHitTest(atWindowPoint: windowPoint) {
+ return row
+ }
+ return contentView.quickSearchResultRowDescendant(containingWindowPoint: windowPoint)
+ }
+}
+
+private extension NSView {
+ func quickSearchResultRowFromHitTest(atWindowPoint windowPoint: NSPoint) -> QuickSearchResultRowView? {
+ let localPoint = convert(windowPoint, from: nil)
+ var hitView = hitTest(localPoint)
+ while let candidate = hitView {
+ if let row = candidate as? QuickSearchResultRowView {
+ return row
+ }
+ hitView = candidate.superview
+ }
+ return nil
+ }
+
+ func quickSearchResultRowDescendant(containingWindowPoint windowPoint: NSPoint) -> QuickSearchResultRowView? {
+ for subview in subviews.reversed() {
+ if let row = subview as? QuickSearchResultRowView,
+ row.containsWindowPointForLaunch(windowPoint) {
+ return row
+ }
+ if let row = subview.quickSearchResultRowDescendant(containingWindowPoint: windowPoint) {
+ return row
+ }
+ }
+ return nil
}
}
@@ -1454,13 +1499,31 @@
}
override func mouseDown(with event: NSEvent) {
- if let result {
- DispatchQueue.main.async { [onLaunch] in
- onLaunch(result)
- }
- } else {
+ if !launchFromMouseClick() {
super.mouseDown(with: event)
}
+ }
+
+ @discardableResult
+ func launchFromMouseClick() -> Bool {
+ guard let result else { return false }
+ DispatchQueue.main.async { [onLaunch, result] in
+ onLaunch(result)
+ }
+ return true
+ }
+
+ func containsWindowPointForLaunch(_ windowPoint: NSPoint) -> Bool {
+ guard window != nil else { return false }
+ var view: NSView? = self
+ while let candidate = view {
+ if candidate.isHidden || candidate.alphaValue <= 0 {
+ return false
+ }
+ view = candidate.superview
+ }
+ let localPoint = convert(windowPoint, from: nil)
+ return bounds.contains(localPoint) && visibleRect.contains(localPoint)
}
private func setup() {
@@ -1578,6 +1641,8 @@
field.placeholderString = placeholder
field.delegate = context.coordinator
field.onCommand = onCommand
+ field.target = context.coordinator
+ field.action = #selector(Coordinator.submitAction(_:))
context.coordinator.onCommand = onCommand
field.setAccessibilityLabel(tr("quickSearch.inputAccessibility"))
context.coordinator.field = field
@@ -1591,6 +1656,8 @@
}
field.placeholderString = placeholder
field.onCommand = onCommand
+ field.target = context.coordinator
+ field.action = #selector(Coordinator.submitAction(_:))
context.coordinator.onCommand = onCommand
if context.coordinator.lastFocusToken != focusToken {
context.coordinator.lastFocusToken = focusToken
@@ -1632,6 +1699,10 @@
text.wrappedValue = field.stringValue
}
+ @objc func submitAction(_ sender: Any?) {
+ onCommand?(.submit)
+ }
+
func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
switch commandSelector {
case #selector(NSResponder.moveUp(_:)):
diff --git a/src/Apptag/TagEditorView.swift b/src/Apptag/TagEditorView.swift
index 775170a..1d2963b 100644
--- a/src/Apptag/TagEditorView.swift
+++ b/src/Apptag/TagEditorView.swift
@@ -1,3 +1,4 @@
+import AppKit
import SwiftUI
// MARK: - Reusable Tag Editor (overlay edit mode + Preferences)
@@ -6,7 +7,11 @@
/// All changes (rename, delete, setColor) are saved to the local tag database.
struct TagEditorView: View {
@Binding var tagColors: [String: Int]
+ @Binding var tagCustomColors: [String: TagCustomColor]
let excludedTagNames: Set<String>
+ let isCustomColorUnlocked: Bool
+ let onLockedCustomColor: () -> Void
+ var topLeadingAccessory: AnyView? = nil
var onRefresh: (() -> Void)?
@State private var editingTagName: String? = nil
@@ -30,7 +35,13 @@
VStack(spacing: 0) {
// "New Tag" button at top
HStack {
- Spacer()
+ if let topLeadingAccessory {
+ topLeadingAccessory
+ .frame(maxWidth: .infinity, alignment: .leading)
+ } else {
+ Spacer()
+ }
+
Button {
addingNewTag = true
newTagNameText = ""
@@ -85,16 +96,20 @@
private func tagEditRow(_ tagName: String) -> some View {
let colorIndex = tagColors[tagName] ?? 0
+ let hasCustomColor = tagCustomColors[tagName] != nil
return HStack(spacing: 10) {
HStack(spacing: 4) {
ForEach(TagColor.allIndices, id: \.self) { idx in
- ColorSwatch(index: idx, isSelected: idx == colorIndex) {
+ ColorSwatch(index: idx, isSelected: !hasCustomColor && idx == colorIndex) {
TagEditor.setColor(idx, for: tagName)
tagColors[tagName] = idx
+ tagCustomColors.removeValue(forKey: tagName)
onRefresh?()
}
}
}
+
+ customColorControl(tagName: tagName, colorIndex: colorIndex)
if editingTagName == tagName {
MacTextField(
@@ -167,6 +182,8 @@
TagEditor.renameTag(from: oldName, to: newName)
tagColors[newName] = tagColors[oldName]
tagColors.removeValue(forKey: oldName)
+ tagCustomColors[newName] = tagCustomColors[oldName]
+ tagCustomColors.removeValue(forKey: oldName)
editingTagName = nil
onRefresh?()
}
@@ -184,6 +201,82 @@
private func deleteTag(_ name: String) {
TagEditor.deleteTagCompletely(name)
tagColors.removeValue(forKey: name)
+ tagCustomColors.removeValue(forKey: name)
onRefresh?()
}
+
+ @ViewBuilder
+ private func customColorControl(tagName: String, colorIndex: Int) -> some View {
+ let isSelected = tagCustomColors[tagName] != nil
+ if isCustomColorUnlocked {
+ ColorPicker(
+ "",
+ selection: customColorBinding(tagName: tagName, colorIndex: colorIndex),
+ supportsOpacity: false
+ )
+ .labelsHidden()
+ .opacity(0.02)
+ .frame(width: 64, height: 24)
+ .overlay(
+ customColorSwatch(tagName: tagName, colorIndex: colorIndex, isSelected: isSelected)
+ .allowsHitTesting(false)
+ )
+ .frame(width: 72, alignment: .leading)
+ .help(tr("tag.customColor"))
+ } else {
+ Button(action: onLockedCustomColor) {
+ customColorSwatch(tagName: tagName, colorIndex: colorIndex, isSelected: isSelected)
+ }
+ .buttonStyle(.plain)
+ .frame(width: 72, alignment: .leading)
+ .help(tr("pro.prompt.customTagColors"))
+ }
+ }
+
+ private func customColorSwatch(tagName: String, colorIndex: Int, isSelected: Bool) -> some View {
+ let fill = Color(nsColor: TagColor.nsColor(for: colorIndex, customColor: tagCustomColors[tagName]))
+ return ZStack {
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .fill(fill)
+ .frame(width: 58, height: 18)
+ .overlay(
+ RoundedRectangle(cornerRadius: 10, style: .continuous)
+ .stroke(Color.secondary.opacity(0.18), lineWidth: 1)
+ )
+ .padding(3)
+ .overlay(
+ RoundedRectangle(cornerRadius: 13, style: .continuous)
+ .stroke(isSelected ? Color.white : Color.clear, lineWidth: 2)
+ )
+ .shadow(color: .black.opacity(0.15), radius: 2, y: 1)
+
+ Image(systemName: "crown")
+ .font(.system(size: 10, weight: .semibold))
+ .symbolRenderingMode(.monochrome)
+ .foregroundStyle(Color.white)
+ .shadow(color: .black.opacity(0.28), radius: 1, y: 0.5)
+ }
+ }
+
+ private func customColorBinding(tagName: String, colorIndex: Int) -> Binding<Color> {
+ Binding(
+ get: {
+ Color(nsColor: TagColor.nsColor(for: colorIndex, customColor: tagCustomColors[tagName]))
+ },
+ set: { color in
+ guard isCustomColorUnlocked else {
+ onLockedCustomColor()
+ return
+ }
+ let nsColor = NSColor(color)
+ let customColor = TagCustomColor(nsColor: nsColor)
+ guard TagEditor.setCustomColor(customColor, for: tagName) else {
+ onLockedCustomColor()
+ return
+ }
+ tagCustomColors[tagName] = customColor
+ onRefresh?()
+ }
+ )
+ }
}
diff --git a/src/Apptag/TagNavigationView.swift b/src/Apptag/TagNavigationView.swift
index 9086a96..ce079c7 100644
--- a/src/Apptag/TagNavigationView.swift
+++ b/src/Apptag/TagNavigationView.swift
@@ -5,6 +5,7 @@
var id: String { name }
let name: String
let colorIndex: Int
+ let customColor: TagCustomColor?
}
struct TagNavigationView: NSViewRepresentable {
@@ -402,7 +403,7 @@
}
required init?(coder: NSCoder) {
- self.item = TagNavigationItem(name: "", colorIndex: 0)
+ self.item = TagNavigationItem(name: "", colorIndex: 0, customColor: nil)
self.orientation = .horizontal
super.init(coder: coder)
}
@@ -543,7 +544,7 @@
}
private func updateAppearance() {
- let background = TagColor.nsColor(for: item.colorIndex)
+ let background = TagColor.nsColor(for: item.colorIndex, customColor: item.customColor)
let dragScale: CGFloat = isDragging ? 1.04 : 1.0
layer?.backgroundColor = background.cgColor
layer?.cornerRadius = orientation == .horizontal ? 7 : 6
@@ -555,7 +556,7 @@
layer?.setAffineTransform(CGAffineTransform(scaleX: dragScale, y: dragScale))
alphaValue = dragModeActive ? (isDragging ? 1.0 : 0.62) : 1.0
- let textColor: NSColor = (item.colorIndex == 0 || item.colorIndex == 5) ? .labelColor : .white
+ let textColor: NSColor = TagColor.prefersDarkText(for: background) ? .labelColor : .white
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = alignment
if orientation == .vertical {
diff --git a/src/CHANGELOG.md b/src/CHANGELOG.md
index 9aee5ca..d08d753 100644
--- a/src/CHANGELOG.md
+++ b/src/CHANGELOG.md
@@ -2,6 +2,55 @@
## [Unreleased]
+## [8.2.8] — 2026-06-30
+
+- 修复 Quick Search 候选列表触摸板 / 鼠标点击仍无法启动应用的问题:结果面板保留原 `hitTest` 路径,并增加按窗口坐标递归命中结果行的几何兜底,复用回车同一启动路径
+- 扩展 Quick Search 启动回归门禁,要求 panel 级点击兜底不能只依赖 SwiftUI / NSScrollView 中间层的 `hitTest`
+- 版本号更新为 `8.2.8`,Build 更新为 `20260630.0128`
+
+## [8.2.7] — 2026-06-30
+
+- Pro 已解锁后,设置页固定 Pro 状态行不再显示“恢复购买”按钮
+- Pro 页对比表已解锁状态统一加上 `✅` 前缀,和 `✅支持` / `✅无限备注` 保持一致
+- 补齐 29 个语种的已解锁状态、Quick Search 快捷键页和气泡提示设置文案,并扩展 Pro / 本地化 QA 门禁覆盖本轮返工点
+- 版本号更新为 `8.2.7`,Build 更新为 `20260630.0049`
+
+## [8.2.6] — 2026-06-29
+
+- 按最新标注移除语言页和关于页顶部固定 Pro 引导行,保留其它设置页的固定购买引导
+- 调整 Pro 页对比表文案:Pro 列未购买功能显示 `✅支持`,备注行显示 `✅无限备注`
+- 补齐 29 个语种的新增 Pro 对比文案,并扩展 Pro / 本地化 QA 门禁覆盖本轮返工点
+- 版本号更新为 `8.2.6`,Build 更新为 `20260629.2315`
+
+## [8.2.5] — 2026-06-29
+
+- 修复 Quick Search 候选列表中鼠标点击应用不启动的问题:结果面板现在会在 AppKit 窗口事件层兜底解析被点击的结果行,并复用原有启动路径打开应用
+- 扩展 Quick Search 启动回归门禁,覆盖结果面板对鼠标点击事件的处理,避免只检查回车路径
+- 调整 Pro 页免费 / Pro 状态文案和对比表状态:免费态显示“不可用 / 只可预览 5 分钟 / 待解锁”,Pro 列标题补充皇冠标识
+- 调整菜单栏免费态 Pro 状态文案,强化“立刻升级到 👑Pro”的购买引导;点击该状态项会直接打开 Pro 设置页
+- 设置页增加固定位置的 Pro 引导行,各页签切换时保持同一位置;Pro 对比表状态胶囊统一为中性样式,不再显示皇冠图标
+- 版本号更新为 `8.2.5`,Build 更新为 `20260629.2210`
+
+## [8.2.4] — 2026-06-29
+
+- 设置页 Pro、语言、关于三个少内容页面改为按主内容区域全局上下左右居中,避免内容只在局部区域居中
+- Pro 胶囊的皇冠图标不再依赖文案中是否包含 `Pro`,长语种和 RTL 语言下也保留皇冠视觉引导
+- 快捷键、标签、数据页补充与主题页一致的购买引导文案;标签页引导与 `+ 新建标签` 保持同一行对齐
+- 标签自定义颜色入口继续保留横向色条与皇冠引导,不回退已验收的彩色容器 / 彩色网格 5 分钟试用逻辑
+- 补齐 29 个语种的新增购买引导文案,并扩展 Pro / 本地化 QA 门禁覆盖本轮返工点
+- 版本号更新为 `8.2.4`,Build 更新为 `20260629.1813`
+
+## [8.2.3] — 2026-06-29
+
+- 设置页新增独立 `Pro` 页签,并将顶部页签压缩为 8 个线型图标入口;`Pro` 位于“数据”和“关于”之间,`关于`页不再重复承载 Pro 对比说明
+- Pro 已解锁用户在“通用 / 主题 / 快捷键 / 标签 / 数据”页顶部显示轻量的 `Pro 已解锁` 权益行,不再使用多页重复的大型 Pro 状态卡片
+- Pro 专属的高级主题、彩色容器 / 彩色网格、自定义快捷键、自定义标签颜色和数据导入导出入口在已解锁后仍保留皇冠 Pro 标识
+- Pro 对比页将免费版的数据导入导出能力状态从“受限”改为“不支持”,付费解锁前后状态统一为“待解锁 / 已解锁”
+- 设置页语言列表去掉重复标题说明,并在主内容区域内上下左右居中;关于页应用信息块也改为主内容区域居中显示
+- 标签页自定义颜色入口改为横向色条加白色线型皇冠图标,不再显示“自定义颜色”文字;免费态点击仍触发 Pro 提示,Pro 态继续使用 macOS 原生颜色选择器
+- 补齐 29 个语种的通用页 Pro 权益说明和“不支持”状态文案,并扩展 Pro / 标签颜色 / 本地化 QA 门禁
+- 版本号更新为 `8.2.3`,Build 更新为 `20260629.1703`
+
## [8.2.1] — 2026-06-28
- 修复“设置 > 快捷键”页的自定义快捷键行排版:快捷键值、状态和操作入口改为同一行稳定布局,避免右侧控件纵向堆叠导致页面失衡
diff --git a/src/Release/Freeze-8.2.8-20260630.0128/FREEZE_MANIFEST.md b/src/Release/Freeze-8.2.8-20260630.0128/FREEZE_MANIFEST.md
new file mode 100644
index 0000000..276ac07
--- /dev/null
+++ b/src/Release/Freeze-8.2.8-20260630.0128/FREEZE_MANIFEST.md
@@ -0,0 +1,150 @@
+# TagLauncher 8.2.8 Build 20260630.0128 Code Freeze
+
+## Freeze Scope
+
+- Version: `8.2.8`
+- Build: `20260630.0128`
+- Branch: `codex/pro-custom-hotkeys-8.2.0`
+- Freeze tag: `v8.2.8-build20260630.0128`
+- Freeze commit: the commit pointed to by the freeze tag.
+- Freeze time: `2026-06-30 03:37:56 +0800`
+- Operator: Codex
+
+This freeze captures the current TagLauncher Pro feature enhancement batch and the blocking Quick Search click-launch fix for App Store handoff. It intentionally excludes unrelated dirty workspace changes under legacy `docs/`, old `src/Release/AppStore-7.8.15...` screenshot deletions, local planning/canvas documents, and `.codex-sessionhistory/` evidence files.
+
+## Included Product Changes
+
+- Pro custom hotkeys:
+ - Free users see Pro-gated custom hotkey controls.
+ - Pro users can customize the main AppGrid and global Quick Search shortcuts.
+ - Shortcut recording suspends active global shortcuts during capture and restores them after success, failure, cancel, tab switch, window close, or entitlement change.
+ - Validation allows `Option+Space`, rejects unsafe/invalid shortcuts, and keeps default fallback behavior for free users or invalid saved values.
+- Pro tag custom colors:
+ - `TagDef.customColor` / `TagCustomColor` support optional sRGB custom colors while preserving old tag data.
+ - Custom colors propagate to AppGrid group titles, tag navigation, and tag editing.
+ - Free users can keep existing custom colors and switch back to base colors, but cannot set new custom colors.
+- Pro notes quota:
+ - Free users can save 3 custom app notes.
+ - Pro users can save unlimited app notes.
+ - Editing existing notes remains allowed, and deleting notes releases quota.
+- Pro display modes and theme preview:
+ - Colorful container and colorful grid display modes are Pro-gated.
+ - Free users can preview these display modes for 5 minutes using the same preview model as Pro themes.
+- Settings / Pro UI:
+ - Adds a dedicated `Pro` settings tab between Data and About.
+ - Keeps settings tab icons line-style and compressed for 8 tabs.
+ - Moves the Pro comparison table into the Pro tab.
+ - Removes repeated large Pro cards from About / Data / Tags / Hotkeys pages.
+ - Removes the restore purchase button from Pro-unlocked states.
+ - About now only keeps app information, help, and contact content.
+- Localization:
+ - Updates 29 language packs for Pro feature copy, Quick Search hotkey settings, bubble tip settings, and Pro comparison states.
+ - Removes old `5 notes` quota wording from the Pro notes feature copy.
+- Quick Search blocking fix:
+ - Quick Search panel is an activating key panel and activates TagLauncher before ordering front.
+ - Return / Enter keeps both command delegate and target/action submit fallback.
+ - Mouse / trackpad clicking result rows is handled through `QuickSearchResultRowView.mouseDown` and a panel-level `sendEvent` fallback.
+ - The panel fallback first tries `hitTest`, then recursively scans visible result row geometry by window point, avoiding SwiftUI / `NSHostingView` / `NSScrollView` hit-test gaps.
+
+## Included Project Governance Changes
+
+- `AGENTS.md` and `CODE_GOVERNANCE.md` now include a UI Preview Gate for non-trivial TagLauncher UI changes.
+- The gate requires UI contracts, high-fidelity preview or equivalent marked screenshots, user confirmation before production UI edits, and real rendered / interaction evidence before visual PASS.
+- These governance changes do not affect the binary build, but are included in the freeze commit as part of this round's delivery guardrails.
+
+## QA Evidence
+
+Passed before freeze:
+
+- `bash Scripts/quick_search_launch_contract_qa.sh`
+- `bash Scripts/pro_custom_hotkeys_qa.sh`
+- `bash Scripts/pro_feature_gate_qa.sh`
+- `git diff --check -- CODEGRAPH.md src/CHANGELOG.md src/Apptag/Info.plist src/Apptag/QuickSearch.swift src/Scripts/quick_search_launch_contract_qa.sh`
+- `APP_BUILD=20260630.0128 bash build.sh`
+- `bash make_dmg.sh`
+- `codesign --verify --deep --strict --verbose=2 build/TagLauncher.app`
+- `hdiutil verify build/TagLauncher.dmg`
+
+Additional freeze-time artifact verification:
+
+- Mounted `/Users/ar/Projects/Taglauncher/src/build/TagLauncher.dmg` read-only.
+- DMG contents include:
+ - `TagLauncher.app`
+ - `Applications` symlink.
+- Mounted app metadata:
+ - `CFBundleShortVersionString = 8.2.8`
+ - `CFBundleVersion = 20260630.0128`
+- Mounted app signature verification:
+ - `codesign --verify --deep --strict --verbose=2 /tmp/TagLauncherFreezeMount/TagLauncher.app`
+ - Result: valid on disk and satisfies designated requirement.
+- DMG verification:
+ - `hdiutil verify /Users/ar/Projects/Taglauncher/src/build/TagLauncher.dmg`
+ - Result: checksum is valid.
+- Quick Search real GUI click verification:
+ - Opened the built TagLauncher app.
+ - Pressed `Space` through GUI automation to open Quick Search.
+ - Typed `Calculator`.
+ - Confirmed `Calculator` was not running before click.
+ - Clicked the `Calculator` candidate row using a real left-click automation event, not Return.
+ - Confirmed `Calculator` launched and became the frontmost app.
+ - Cleaned up by quitting Calculator.
+ - Screenshot evidence: `/Users/ar/Projects/Taglauncher/.codex-sessionhistory/assets/2026-06-30-quicksearch-calculator-click-pass.png`
+ - Screenshot SHA256: `f50d2cc5908b43309ba58ec6be0001d350391899c17a323d796e7b66cde8d7d7`
+
+## Build Artifacts
+
+- DMG: `/Users/ar/Projects/Taglauncher/src/build/TagLauncher.dmg`
+- DMG SHA256: `47b7d7127781a7c5dbf709b6a9f65be1baa9f1f0f5fd1e93b531fcc61eaaf61a`
+- Mounted executable SHA256: `27d39957070512e8849b876edaa736ebd89a05e46b04e3312a4ffa4995885b32`
+
+Note: after DMG creation, `build/TagLauncher.app` was no longer present in the build directory root. Freeze-time app metadata and signature checks were therefore performed against the app inside the mounted DMG.
+
+## CODEGRAPH Check
+
+- Checked: `/Users/ar/Projects/Taglauncher/CODEGRAPH.md`
+- Change type:
+ - Pro entitlement policy and preview model changes.
+ - Settings / Pro tab UI ownership and protected behavior.
+ - Tag custom color data model and display propagation.
+ - Custom hotkey storage / validation / registration behavior.
+ - Quick Search key panel, Return fallback, and mouse-click launch fallback.
+ - New QA script entries.
+- Conclusion: updated in this freeze.
+
+## Excluded Dirty Workspace Changes
+
+The following dirty areas are intentionally not included in this freeze tag because they are unrelated to the 8.2.8 App build or their ownership is not established in this release handoff:
+
+- Legacy `docs/` deletions and website assets.
+- Old `src/Release/AppStore-7.8.15-20260605.2337/...` screenshot deletions.
+- Existing edits in old release metadata under `src/Release/AppStore-7.9.1...` and `src/Release/AppStore-7.9.4...`.
+- Untracked planning / knowledge documents under `Docs/`, `canvas/`, and root-level local notes.
+- `.codex-sessionhistory/` records and screenshots, which remain local evidence rather than release source.
+
+## Rollback
+
+To inspect the frozen source without changing the current branch:
+
+```bash
+git switch --detach v8.2.8-build20260630.0128
+```
+
+To revert this freeze from a descendant branch:
+
+```bash
+git revert v8.2.8-build20260630.0128
+```
+
+## App Store Handoff
+
+This code freeze must be completed before any App Store submission work proceeds. App Store upload / submission is outside this freeze step and should start only after the freeze commit and tag exist.
+
+## Remote Push Status
+
+- Local freeze commit and local annotated tag were created successfully.
+- Remote push attempted:
+ - `git push origin codex/pro-custom-hotkeys-8.2.0`
+ - `git push origin v8.2.8-build20260630.0128`
+- Remote push result: not pushed.
+- Reason: GitHub HTTPS authentication is not available in this environment: `fatal: could not read Username for 'https://github.com': Device not configured`.
+- Impact: the local repository has a fixed commit and tag for freeze / rollback. Remote backup is still pending until GitHub credentials are available.
diff --git a/src/Release/Freeze-8.2.8-20260630.0128/SHA256SUMS.txt b/src/Release/Freeze-8.2.8-20260630.0128/SHA256SUMS.txt
new file mode 100644
index 0000000..a3aa98e
--- /dev/null
+++ b/src/Release/Freeze-8.2.8-20260630.0128/SHA256SUMS.txt
@@ -0,0 +1,3 @@
+47b7d7127781a7c5dbf709b6a9f65be1baa9f1f0f5fd1e93b531fcc61eaaf61a src/build/TagLauncher.dmg
+27d39957070512e8849b876edaa736ebd89a05e46b04e3312a4ffa4995885b32 TagLauncher.app/Contents/MacOS/TagLauncher (inside src/build/TagLauncher.dmg)
+f50d2cc5908b43309ba58ec6be0001d350391899c17a323d796e7b66cde8d7d7 .codex-sessionhistory/assets/2026-06-30-quicksearch-calculator-click-pass.png
diff --git a/src/Scripts/pro_custom_hotkeys_qa.sh b/src/Scripts/pro_custom_hotkeys_qa.sh
index bb797a4..a70de65 100755
--- a/src/Scripts/pro_custom_hotkeys_qa.sh
+++ b/src/Scripts/pro_custom_hotkeys_qa.sh
@@ -98,6 +98,13 @@
require(settings, "modifiers == UInt32(kEventKeyModifierFnMask)", "Fn-only must be restricted explicitly")
require(settings, "hotkey.keyCode == UInt32(kVK_Space)", "Fn-only must only be valid for Space")
require(settings, "isReservedBySystem", "system-reserved shortcuts must be rejected")
+require(settings, "modifiers == UInt32(shiftKey)", "Shift-only must remain rejected")
+if "modifiers == UInt32(shiftKey) || modifiers == UInt32(optionKey)" in settings:
+ fail("Option-only shortcuts such as Option+Space must be allowed")
+require(settings, "private static let functionKeyCodes: Set<Int>", "function keys must use an explicit Carbon key-code set")
+require(settings, "functionKeyCodes.contains(key)", "supported-key validation must check the explicit function key set")
+if "kVK_F1...kVK_F12" in settings:
+ fail("Carbon function key codes are not contiguous; kVK_F1...kVK_F12 crashes at runtime")
effective_body = function_body(settings, "static func effectiveHotkey(for kind: LauncherHotkeyKind) -> LauncherHotkey")
if "validationError(for:" in effective_body:
@@ -131,11 +138,30 @@
require(activate_body, "return .registrationFailed(status)", "registration failure must not save the candidate")
require(app, "observeProEntitlementChanges()", "AppDelegate must observe Pro entitlement changes")
+require(app, "static private(set) weak var shared: AppDelegate?", "Preferences must have a stable AppDelegate bridge for custom hotkey writes")
+require(app, "Self.shared = self", "AppDelegate must publish its stable shared bridge during initialization")
+require(app, "private var configuredHotkeysSuspendedForRecording = false", "AppDelegate must track hotkey recording suspension")
require(app, "registerConfiguredHotkeys()", "Pro entitlement changes must re-register effective hotkeys")
require(app, "LauncherHotkeySettings.effectiveHotkey(for: .main).displayString", "menu title must display the effective App Grid shortcut")
require(app, "LauncherHotkeySettings.effectiveHotkey(for: kind)", "hotkey registration must read effective shortcuts")
require(app, "RegisterEventHotKey", "Carbon RegisterEventHotKey must remain the global hotkey backend")
require(app, "UnregisterEventHotKey(oldRef)", "old hotkey ref must be released after successful replacement")
+
+register_configured_body = function_body(app, "private func registerConfiguredHotkeys()")
+require(register_configured_body, "guard !configuredHotkeysSuspendedForRecording else { return }", "configured hotkeys must stay unregistered while recording")
+
+suspend_body = function_body(app, "func suspendConfiguredHotkeysForRecording()")
+require(suspend_body, "guard !configuredHotkeysSuspendedForRecording else { return }", "recording suspension must be idempotent")
+require(suspend_body, "configuredHotkeysSuspendedForRecording = true", "recording suspension must set the guard flag")
+require(suspend_body, "unregisterHotkey(for: .main)", "recording must suspend the App Grid global hotkey")
+require(suspend_body, "unregisterHotkey(for: .quickSearch)", "recording must suspend the Quick Search global hotkey")
+if "LauncherHotkeySettings.save" in suspend_body or "clearCustomHotkey" in suspend_body:
+ fail("recording suspension must not write custom hotkey storage")
+
+resume_body = function_body(app, "func resumeConfiguredHotkeysAfterRecording()")
+require(resume_body, "guard configuredHotkeysSuspendedForRecording else { return }", "recording resume must be idempotent")
+require(resume_body, "configuredHotkeysSuspendedForRecording = false", "recording resume must clear the guard flag")
+require(resume_body, "registerConfiguredHotkeys()", "recording resume must restore effective hotkeys")
for forbidden in ["CGEventTapCreate", "AXIsProcessTrusted", "IOHIDManagerCreate", "addGlobalMonitorForEvents(matching: .keyDown"]:
if forbidden in app + preferences + settings + quick_search:
@@ -145,14 +171,40 @@
require(preferences, "NSEvent.addLocalMonitorForEvents(matching: .keyDown)", "recording must use local key-down capture in Settings")
require(preferences, "Int(event.keyCode) == kVK_Escape", "Esc must cancel recording")
require(preferences, "LauncherHotkeySettings.candidate(from: event)", "recording must normalize NSEvent into LauncherHotkey")
+require(preferences, "AppDelegate.shared?", "recording must use the stable AppDelegate bridge instead of NSApp.delegate casting")
+require(preferences, "appDelegate.suspendConfiguredHotkeysForRecording()", "recording must suspend existing global hotkeys before capture")
+require(preferences, "AppDelegate.shared?.resumeConfiguredHotkeysAfterRecording()", "recording cleanup must restore effective global hotkeys")
require(preferences, ".applyCustomHotkey(candidate, for: kind)", "recording must call the AppDelegate transactional save path")
require(preferences, "CustomizableHotkeyInfoRow", "Settings hotkey rows must expose custom controls")
require(preferences, "StaticHotkeyInfoRow(", "internal App Grid Space shortcut must remain static")
require(preferences, "LauncherHotkeySettings.effectiveHotkey(for: .main).displayString", "Settings must display effective App Grid shortcut")
require(preferences, "LauncherHotkeySettings.effectiveHotkey(for: .quickSearch).displayString", "Settings must display effective Quick Search shortcut")
require(preferences, "HotkeyPrimaryActionButton", "custom hotkey rows must use the shared action button")
-require(preferences, "ProStatusPill(text: title, style: .locked, compact: true)", "locked custom hotkey action must use the global Pro pill")
+require(preferences, 'customizeTitle: tr("hotkeys.customize")', "locked custom hotkey actions must still show the action label")
+require(preferences, 'proBadgeTitle: tr("pro.card.badge")', "locked custom hotkey actions must compose the global Pro badge beside the action label")
+require(preferences, "ProStatusPill(text: proBadgeTitle, style: .locked, compact: true)", "locked custom hotkey action must use the global Pro pill")
require(preferences, "if canRestore {", "restore-default action must only appear when a custom shortcut exists")
+
+start_recording_body = function_body(preferences, "private func startHotkeyRecording(for kind: LauncherHotkeyKind)")
+suspend_index = start_recording_body.find("appDelegate.suspendConfiguredHotkeysForRecording()")
+monitor_index = start_recording_body.find("NSEvent.addLocalMonitorForEvents(matching: .keyDown)")
+if suspend_index == -1 or monitor_index == -1 or not suspend_index < monitor_index:
+ fail("recording must suspend global hotkeys before installing the local monitor")
+
+stop_recording_body = function_body(preferences, "private func stopHotkeyRecording(showCancelledToast: Bool = false)")
+require(stop_recording_body, "let wasRecording", "recording cleanup must only resume when a recording was active")
+require(stop_recording_body, "NSEvent.removeMonitor(hotkeyRecorderMonitor)", "recording cleanup must remove the local monitor")
+require(stop_recording_body, "recordingHotkeyKind = nil", "recording cleanup must clear recording state")
+require(stop_recording_body, "AppDelegate.shared?.resumeConfiguredHotkeysAfterRecording()", "recording cleanup must restore global hotkeys")
+
+capture_recording_body = function_body(preferences, "private func captureHotkeyEvent(_ event: NSEvent)")
+stop_index = capture_recording_body.find("stopHotkeyRecording(showCancelledToast: false)")
+handle_index = capture_recording_body.find("handleHotkeyCustomizationResult(result)")
+if stop_index == -1 or handle_index == -1 or not stop_index < handle_index:
+ fail("recording capture must restore global hotkeys before showing save/failure feedback")
+
+require(preferences, "if newTab != .hotkeys", "leaving the Hotkeys tab must end recording")
+require(preferences, "stopHotkeyRecording(showCancelledToast: false)", "recording must clean up on tab change, Pro changes, and view disappearance")
custom_row_start = preferences.find("private struct CustomizableHotkeyInfoRow")
custom_row_end = preferences.find("private struct HotkeyStatusPill")
@@ -162,8 +214,15 @@
if ".buttonStyle(.borderedProminent)" in custom_row:
fail("custom hotkey rows must not use the default blue borderedProminent Pro button")
+hotkey_button_start = preferences.find("private struct HotkeyPrimaryActionButton")
+hotkey_button_end = preferences.find("private struct HotkeySecondaryActionButton")
+if hotkey_button_start == -1 or hotkey_button_end == -1 or hotkey_button_end <= hotkey_button_start:
+ fail("could not inspect HotkeyPrimaryActionButton layout")
+hotkey_button = preferences[hotkey_button_start:hotkey_button_end]
+require(hotkey_button, ".buttonStyle(.bordered)", "locked custom hotkey action must visually match Data tab Pro-gated buttons")
+
require(pro, "case customHotkeys", "ProFeature.customHotkeys is missing")
-require(pro, "case .premiumThemes, .layoutImport, .layoutExport, .unlimitedNotes, .persistentAppSorting, .customHotkeys:", "customHotkeys must be unlocked only by the Pro access state")
+require(pro, "case .premiumThemes, .layoutImport, .layoutExport, .customTagColors, .unlimitedNotes, .persistentAppSorting, .customHotkeys:", "customHotkeys must be unlocked only by the Pro access state")
require(pro, "NotificationCenter.default.post(name: .tagLauncherProEntitlementChanged", "entitlement changes must notify hotkey registration")
require(access_views, "case .customHotkeys:", "Pro prompt routing must include custom hotkeys")
@@ -186,5 +245,90 @@
if "%status%" not in data["hotkeys.error.registrationFailed"]:
fail(f"{path.name} hotkeys.error.registrationFailed must keep %status% placeholder")
-print("PASS Pro custom hotkeys QA: Pro gating, transactional Carbon registration, duplicate-safe effective shortcuts, local recording, Pro-consistent row UI, and 29-language copy are wired")
+print("PASS Pro custom hotkeys static QA: Pro gating, recording suspension, transactional save path, duplicate-safe effective shortcuts, local recording, Pro-consistent row UI, and 29-language copy are wired")
PY
+
+swift - <<'SWIFT'
+import Carbon
+import Darwin
+
+func fail(_ message: String) -> Never {
+ fputs("FAIL: \(message)\n", stderr)
+ exit(1)
+}
+
+@discardableResult
+func register(
+ label: String,
+ keyCode: Int,
+ modifiers: UInt32,
+ id: UInt32,
+ expectSuccess: Bool
+) -> EventHotKeyRef? {
+ let hotkeyID = EventHotKeyID(signature: OSType(0x54474C51), id: id) // 'TGLQ'
+ var ref: EventHotKeyRef?
+ let status = RegisterEventHotKey(
+ UInt32(keyCode),
+ modifiers,
+ hotkeyID,
+ GetApplicationEventTarget(),
+ 0,
+ &ref
+ )
+ if expectSuccess {
+ guard status == noErr, let ref else {
+ fail("\(label) should register successfully, got status \(status)")
+ }
+ return ref
+ }
+ if status == noErr {
+ if let ref { UnregisterEventHotKey(ref) }
+ fail("\(label) should not register successfully")
+ }
+ return nil
+}
+
+let modifiers = UInt32(controlKey | optionKey | shiftKey)
+let mainRef = register(
+ label: "main representative shortcut",
+ keyCode: kVK_ANSI_9,
+ modifiers: modifiers,
+ id: 1,
+ expectSuccess: true
+)
+let quickSearchRef = register(
+ label: "quick search representative shortcut",
+ keyCode: kVK_ANSI_8,
+ modifiers: modifiers,
+ id: 2,
+ expectSuccess: true
+)
+let replacementRef = register(
+ label: "same-id replacement shortcut",
+ keyCode: kVK_ANSI_7,
+ modifiers: modifiers,
+ id: 1,
+ expectSuccess: true
+)
+let optionSpaceRef = register(
+ label: "Option-Space shortcut",
+ keyCode: kVK_Space,
+ modifiers: UInt32(optionKey),
+ id: 4,
+ expectSuccess: true
+)
+_ = register(
+ label: "duplicate shortcut conflict",
+ keyCode: kVK_ANSI_7,
+ modifiers: modifiers,
+ id: 3,
+ expectSuccess: false
+)
+
+if let optionSpaceRef { UnregisterEventHotKey(optionSpaceRef) }
+if let replacementRef { UnregisterEventHotKey(replacementRef) }
+if let quickSearchRef { UnregisterEventHotKey(quickSearchRef) }
+if let mainRef { UnregisterEventHotKey(mainRef) }
+
+print("PASS Pro custom hotkeys runtime QA: Carbon accepts representative custom registrations, Option-Space, same-id replacement, and rejects duplicate active shortcuts")
+SWIFT
diff --git a/src/Scripts/pro_display_mode_preview_qa.sh b/src/Scripts/pro_display_mode_preview_qa.sh
new file mode 100755
index 0000000..292d40e
--- /dev/null
+++ b/src/Scripts/pro_display_mode_preview_qa.sh
@@ -0,0 +1,139 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+python3 - "$ROOT_DIR" <<'PY'
+import re
+import sys
+from pathlib import Path
+
+root = Path(sys.argv[1])
+app = root / "Apptag"
+
+
+def fail(message: str) -> None:
+ raise SystemExit(f"FAIL: {message}")
+
+
+def read(name: str) -> str:
+ path = app / name
+ try:
+ return path.read_text(encoding="utf-8")
+ except Exception as error:
+ fail(f"could not read {path}: {error}")
+
+
+def require(source: str, needle: str, message: str) -> None:
+ if needle not in source:
+ fail(message)
+
+
+def function_body(source: str, signature: str) -> str:
+ start = source.find(signature)
+ if start == -1:
+ fail(f"missing function signature: {signature}")
+ brace = source.find("{", start)
+ if brace == -1:
+ fail(f"missing function body for: {signature}")
+ depth = 0
+ for index in range(brace, len(source)):
+ char = source[index]
+ if char == "{":
+ depth += 1
+ elif char == "}":
+ depth -= 1
+ if depth == 0:
+ return source[brace + 1:index]
+ fail(f"unterminated function body for: {signature}")
+
+
+pro = read("ProEntitlement.swift")
+preferences = read("PreferencesView.swift")
+content = read("ContentView.swift")
+defaults = read("AppDefaults.swift")
+
+require(defaults, 'static let displayMode = "gridContainer"', "new installs must default to a free display mode")
+
+for needle in [
+ "struct ProDisplayModePreviewState: Equatable",
+ "var previewDisplayMode: String? = nil",
+ 'static let premiumDisplayModes: Set<String> = ["coloredContainer", "coloredGridContainer"]',
+ "static func isPremiumDisplayMode(_ displayMode: String) -> Bool",
+ "static func canUseDisplayMode(_ displayMode: String) -> Bool",
+ "static func fallbackDisplayMode(for displayMode: String) -> String",
+ "static func effectiveDisplayMode(for storedDisplayMode: String) -> String",
+ "func startDisplayModePreview(for displayMode: String)",
+ "func stopDisplayModePreview()",
+ "ProEntitlementConfig.themePreviewDuration",
+ "var isPreviewingProAppearance: Bool",
+]:
+ require(pro, needle, f"Pro display-mode preview contract is missing: {needle}")
+
+fallback_body = function_body(pro, "static func fallbackDisplayMode(for displayMode: String) -> String")
+require(fallback_body, 'case "coloredContainer":', "coloredContainer must have a free fallback")
+require(fallback_body, 'return "container"', "coloredContainer must fall back to container")
+require(fallback_body, 'case "coloredGridContainer":', "coloredGridContainer must have a free fallback")
+require(fallback_body, 'return "gridContainer"', "coloredGridContainer must fall back to gridContainer")
+
+effective_body = function_body(pro, "static func effectiveDisplayMode(for storedDisplayMode: String) -> String")
+require(effective_body, "snapshot.previewDisplayMode", "effective display mode must prefer active preview")
+require(effective_body, "canUseDisplayMode(storedDisplayMode)", "effective display mode must enforce Pro access")
+require(effective_body, "fallbackDisplayMode(for: storedDisplayMode)", "locked stored display modes must fall back")
+
+start_body = function_body(pro, "func startDisplayModePreview(for displayMode: String)")
+require(start_body, "ProEntitlementPolicy.isPremiumDisplayMode(displayMode)", "only premium display modes should start preview")
+require(start_body, "guard !accessState.isUnlocked else { return }", "Pro users should not start a trial preview")
+require(start_body, "stopThemePreview()", "display-mode preview must share one active Pro appearance trial with themes")
+require(start_body, "endsAt: now.addingTimeInterval(ProEntitlementConfig.themePreviewDuration)", "display-mode preview must reuse Pro theme 5-minute duration")
+require(start_body, "applyDisplayModePreview(preview)", "display-mode preview must publish snapshot state")
+
+require(preferences, "private var effectiveDisplayMode: String", "Preferences must expose effective display mode")
+require(preferences, "private func handleDisplayModeSelection(_ mode: String)", "Preferences display mode handler is missing")
+require(preferences, "private func displayModeOptionAccessory(for mode: String) -> ThemeOptionAccessory", "display mode accessory policy is missing")
+require(preferences, "isSelected: effectiveDisplayMode ==", "display buttons must select by effective display mode")
+require(preferences, "accessory: displayModeOptionAccessory", "display buttons must render Pro badge/countdown accessory")
+require(preferences, "proEntitlement.startDisplayModePreview(for: mode)", "locked display-mode selection must start preview")
+require(preferences, ".frame(width: 64, alignment: .trailing)", "display mode buttons must reserve a fixed accessory slot")
+require(preferences, "ProStatusPill(text: text, style: style, compact: true)", "display mode Pro badge must use the shared Pro pill")
+require(preferences, ".font(.system(size: 10, weight: .semibold, design: .monospaced))", "display mode countdown must use the shared MM:SS visual")
+
+handler_body = function_body(preferences, "private func handleDisplayModeSelection(_ mode: String)")
+require(handler_body, "ProEntitlementPolicy.canUseDisplayMode(mode)", "display mode handler must branch on Pro access")
+require(handler_body, "displayMode = mode", "unlocked/free display modes must persist")
+require(handler_body, "proEntitlement.startDisplayModePreview(for: mode)", "locked premium display modes must not persist immediately")
+if handler_body.find("displayMode = mode") > handler_body.find("proEntitlement.startDisplayModePreview(for: mode)"):
+ fail("locked display mode preview must not write displayMode before starting preview")
+
+accessory_body = function_body(preferences, "private func displayModeOptionAccessory(for mode: String) -> ThemeOptionAccessory")
+require(accessory_body, "displayModePreviewState?.displayMode == mode", "active display mode preview must show countdown on that option")
+require(accessory_body, ".countdown(text: themePreviewCountdownText ?? \"00:00\")", "active display mode preview must show MM:SS")
+require(accessory_body, "ProEntitlementPolicy.isPremiumDisplayMode(mode)", "only premium display modes should show locked Pro badge")
+require(accessory_body, "return effectiveDisplayMode == mode ? .checkmark : .circle", "ordinary selected state must use effective display mode")
+
+countdown_body = function_body(preferences, "private var themePreviewCountdownText: String?")
+require(countdown_body, "proEntitlement.displayModePreviewState", "shared countdown text must support display-mode previews")
+
+refresh_body = function_body(preferences, "private func refreshThemePreviewCountdown(now: Date = Date())")
+require(refresh_body, "displayModePreviewState", "timer refresh must expire display-mode previews")
+require(refresh_body, "proEntitlement.stopDisplayModePreview()", "expired display-mode preview must stop")
+
+access_body = function_body(preferences, "private func handleProAccessStateChange(_ newState: ProAccessState)")
+require(access_body, "if let preview = proEntitlement.displayModePreviewState", "unlock flow must accept display-mode preview")
+require(access_body, "displayMode = preview.displayMode", "unlock flow must persist accepted display-mode preview")
+require(access_body, "proEntitlement.stopDisplayModePreview()", "unlock flow must clear display-mode preview after persisting")
+
+require(content, "private var renderedDisplayMode: String", "ContentView must expose entitlement-aware display mode")
+require(content, "ProEntitlementPolicy.effectiveDisplayMode(for: displayMode)", "ContentView must calculate effective display mode")
+require(content, "displayMode: renderedDisplayMode", "AppGrid must render with effective display mode")
+require(content, "renderedDisplayMode == \"container\" || renderedDisplayMode == \"gridContainer\"", "colorless-container behavior must use effective display mode")
+require(content, "if let preview = proEntitlement.displayModePreviewState", "ContentView unlock flow must accept display-mode preview")
+require(content, "displayMode = preview.displayMode", "ContentView must persist accepted display-mode preview")
+
+if re.search(r'isSelected:\s*displayMode\s*==', preferences):
+ fail("display mode buttons still select by raw stored displayMode")
+if re.search(r'displayMode:\s*displayMode\s*,', content):
+ fail("AppGridCollectionView still receives raw stored displayMode")
+
+print("PASS Pro display-mode preview QA: colored container/grid are Pro-only, free users get a 5-minute non-persistent preview, UI badges/countdown are aligned, and AppGrid renders the effective display mode")
+PY
diff --git a/src/Scripts/pro_feature_gate_qa.sh b/src/Scripts/pro_feature_gate_qa.sh
index 9ed2c60..db76239 100755
--- a/src/Scripts/pro_feature_gate_qa.sh
+++ b/src/Scripts/pro_feature_gate_qa.sh
@@ -60,6 +60,7 @@
"premiumThemes",
"layoutImport",
"layoutExport",
+ "customTagColors",
"unlimitedNotes",
"persistentAppSorting",
"customHotkeys",
@@ -69,8 +70,11 @@
require(pro, 'static let lifetimeProductID = "com.taglauncher.pro.lifetime"', "StoreKit lifetime product id changed or missing")
require(pro, 'static let firstFreeProVersion = "8.1.0"', "legacy unlock cutoff must be 8.1.0")
require(pro, 'static let qaStateEnvKey = "TAGLAUNCHER_QA_PRO_STATE"', "QA Pro-state override is missing")
-require(pro, "static let freeNoteLimit = 5", "free note limit must remain explicit")
+require(pro, "static let freeNoteLimit = 3", "free note limit must be 3")
require(pro, "static let freeThemes: Set<AppGridTheme> = [.defaultLight, .black]", "free theme set must be default/black")
+require(pro, 'static let premiumDisplayModes: Set<String> = ["coloredContainer", "coloredGridContainer"]', "colored container/grid display modes must be Pro-only")
+require(pro, "static func effectiveDisplayMode(for storedDisplayMode: String) -> String", "effective display mode gate is missing")
+require(pro, "func startDisplayModePreview(for displayMode: String)", "Pro display-mode trial preview is missing")
require(pro, "Product.products(for: [ProEntitlementConfig.lifetimeProductID])", "StoreKit product lookup is missing")
require(pro, "Transaction.currentEntitlements", "current entitlement restore/read path is missing")
require(pro, "Transaction.updates", "transaction update listener is missing")
@@ -81,12 +85,17 @@
require(pro, "ProEntitlementSnapshotStore", "sync entitlement snapshot for data-layer policy is missing")
require(pro, "manualNonEmptyNoteCount", "note quota must count existing manual notes")
require(pro, "manualNonEmptyNotePaths", "note quota must avoid double-counting existing notes")
-require(pro, "case .premiumThemes, .layoutImport, .layoutExport, .unlimitedNotes, .persistentAppSorting, .customHotkeys:", "custom hotkeys must be unlocked only by the Pro access state")
+require(pro, "case .premiumThemes, .layoutImport, .layoutExport, .customTagColors, .unlimitedNotes, .persistentAppSorting, .customHotkeys:", "custom tag colors and custom hotkeys must be unlocked only by the Pro access state")
require(pro, "NotificationCenter.default.post(name: .tagLauncherProEntitlementChanged", "Pro entitlement changes must notify hotkey registration")
effective_theme = function_body(pro, "static func effectiveTheme(for storedTheme: AppGridTheme) -> AppGridTheme")
require(effective_theme, "return .defaultLight", "locked premium theme must fall back to defaultLight")
require(effective_theme, "canUseTheme(storedTheme)", "effectiveTheme must check Pro theme entitlement")
+
+effective_display_mode = function_body(pro, "static func effectiveDisplayMode(for storedDisplayMode: String) -> String")
+require(effective_display_mode, "snapshot.previewDisplayMode", "effective display mode must prefer active preview")
+require(effective_display_mode, "canUseDisplayMode(storedDisplayMode)", "effective display mode must check Pro entitlement")
+require(effective_display_mode, "fallbackDisplayMode(for: storedDisplayMode)", "locked colored display mode must fall back to its free variant")
require(app, "ProEntitlementCenter.shared.start()", "App startup does not start Pro entitlement center")
require(app, "observeProEntitlementChanges()", "App startup must observe Pro entitlement changes for custom hotkeys")
@@ -119,6 +128,16 @@
if note_body.find("guard case .allow = decision else") > note_body.find("let previousStore = store"):
fail("note quota decision must happen before store mutation snapshot")
+require(data_layer, "var customColor: TagCustomColor? = nil", "tag definitions must store an optional custom color")
+require(data_layer, "struct TagCustomColor: Codable, Equatable", "custom tag color must be Codable and comparable")
+require(data_layer, "static func nsColor(for index: Int, customColor: TagCustomColor?) -> NSColor", "tag rendering must prefer custom colors with base-color fallback")
+set_color_body = function_body(data_layer, "static func setColor(_ color: Int, for tag: String)")
+require(set_color_body, "tagDef.customColor = nil", "selecting a base tag color must clear the custom color")
+set_custom_color_body = function_body(data_layer, "static func setCustomColor(_ customColor: TagCustomColor, for tag: String) -> Bool")
+require(set_custom_color_body, "guard ProEntitlementPolicy.isUnlocked(.customTagColors) else", "custom tag color writes must be hard-gated by Pro")
+if set_custom_color_body.find("guard ProEntitlementPolicy.isUnlocked(.customTagColors) else") > set_custom_color_body.find("var store = TagDatabase.load()"):
+ fail("custom tag color lock must run before loading/writing store")
+
export_ui = function_body(preferences, "private func exportTags()")
require(export_ui, "guard proEntitlement.isUnlocked else", "export UI must prompt Pro before file panel")
require(export_ui, "presentSettingsProPrompt(for: .layoutExport)", "export UI prompt feature is missing")
@@ -134,9 +153,89 @@
require(preferences, "ProStatusPill(text: tr(\"pro.card.badge\"), style: .locked, compact: true)", "locked data actions must show compact Pro pill")
require(preferences, "presentSettingsProPrompt(for: .premiumThemes)", "premium theme selection prompt is missing")
require(preferences, "presentSettingsProPrompt(for: .customHotkeys)", "custom hotkey Pro prompt is missing")
+require(preferences, "presentSettingsProPrompt(for: .customTagColors)", "custom tag color Pro prompt is missing")
+require(preferences, "private var settingsFixedProHeader: some View", "Settings pages must share one fixed-position Pro guidance header")
+require(preferences, "private var settingsProHeaderText: String", "fixed Pro guidance header must switch copy by selected tab")
+require(preferences, "private var settingsProHeaderFeature: ProFeature", "fixed Pro guidance header must route unlock prompts by selected tab")
+require(preferences, "private var shouldShowSettingsFixedProHeader: Bool", "Language/About tabs must be able to hide the fixed Pro header")
+require(preferences, "selectedTab != .language && selectedTab != .about", "fixed Pro header must be hidden on Language and About tabs")
+require(preferences, "if shouldShowSettingsFixedProHeader", "Settings body must conditionally render the fixed Pro header")
+fixed_header_body = function_body(preferences, "private var settingsFixedProHeader: some View")
+require(fixed_header_body, "if !proEntitlement.isUnlocked", "fixed Pro header must branch on unlocked state")
+require(fixed_header_body, 'Button(tr("pro.card.restore"))', "fixed Pro header must keep restore purchase for free users")
+if fixed_header_body.find("if !proEntitlement.isUnlocked") > fixed_header_body.find('Button(tr("pro.card.restore"))'):
+ fail("fixed Pro header restore purchase button must only render for users who have not unlocked Pro")
+purchase_guidance_body = function_body(preferences, "private func proPurchaseGuidanceLine(")
+require(purchase_guidance_body, "if !proEntitlement.isUnlocked", "purchase guidance restore actions must be hidden after Pro unlock")
+for unlocked_benefit_key in [
+ "settings.proBenefit.general",
+ "pro.theme.status.unlocked",
+ "settings.proBenefit.hotkeys",
+ "settings.proBenefit.tags",
+ "settings.proBenefit.data",
+]:
+ require(preferences, unlocked_benefit_key, f"missing unlocked Pro benefit line for {unlocked_benefit_key}")
+for purchase_guidance_key in [
+ "settings.proGuide.general",
+ "settings.proGuide.hotkeys",
+ "settings.proGuide.tags",
+ "settings.proGuide.data",
+]:
+ require(preferences, purchase_guidance_key, f"missing Pro purchase guidance line for {purchase_guidance_key}")
+require(preferences, 'freeStatusKey: "settings.proStatus.unavailableFeature"', "Pro comparison locked rows must show unavailable for Free users")
+require(preferences, 'freeStatusKey: "settings.proStatus.previewFiveMinutes"', "Pro comparison preview rows must show the 5-minute preview state for Free users")
+require(preferences, 'proLockedStatusKey: "settings.proStatus.lockedFeature"', "Pro comparison Pro column must show supported before purchase")
+require(preferences, 'proUnlockedStatusKey: "settings.proStatus.unlockedFeature"', "Pro comparison Pro column must show unlocked after purchase")
+if preferences.count("freeStyle: .neutral") < 6 or preferences.count("proLockedStyle: .neutral") < 6 or preferences.count("proUnlockedStyle: .neutral") < 6:
+ fail("Pro comparison status chips must use the neutral style without crown icons")
+if 'freeStatusKey: "settings.proStatus.limitedFeature"' in preferences or 'freeStatusKey: "settings.proStatus.unsupportedFeature"' in preferences:
+ fail("Pro comparison table must not use the old Limited/Unsupported status for locked rows")
+if "settingsProStatusOverview(" in preferences or "SettingsProOverviewFeature" in preferences:
+ fail("settings pages must not repeat the bulky Pro status overview card across tabs")
+for removed_about_pro_ui in [
+ "proStatusCard",
+ "settingsProComparisonTable",
+ "SettingsProComparisonFeature",
+]:
+ if removed_about_pro_ui in preferences:
+ fail(f"about page must not render the removed Pro summary/comparison UI: {removed_about_pro_ui}")
+require(preferences, "case pro", "Settings must include a dedicated Pro tab")
+require(preferences, 'case .pro: return "pro.card.badge"', "Pro tab title must use the existing Pro label")
+require(preferences, 'case .pro: return "crown"', "Pro tab must use the line-style crown icon")
+for filled_tab_icon in ["paintpalette.fill", "tag.fill", "externaldrive.fill"]:
+ if filled_tab_icon in preferences:
+ fail(f"settings tab icons must use line style, found filled icon: {filled_tab_icon}")
+require(preferences, "HStack(spacing: 6)", "settings tab bar spacing must be tightened for 8 tabs")
+require(preferences, ".frame(width: 94, height: 72)", "settings tab buttons must be tightened for 8 tabs")
+require(preferences, "case .pro:", "Settings tab switch must render the Pro tab")
+require(content, 'static let pro = "pro"', "Settings tab target must include the Pro tab")
+require(app, "openPreferences(targetTab: SettingsTabTarget.pro)", "status menu Pro CTA must open the Pro settings tab")
+require(preferences, 'selectedTab == .pro', "fixed Pro header must render the Pro tab user status state")
+require(preferences, "proTabComparisonTable(width: dataPanelWidth)", "Pro tab must render the Free-vs-Pro comparison table")
+require(preferences, "private struct ProTabComparisonFeature", "Pro tab comparison row model is missing")
+if 'Text(tr("settings.proCompare.title"))' in preferences:
+ fail("Pro tab comparison table must not render the removed title")
+require(preferences, 'Text(tr("settings.proCompare.free"))', "Pro tab comparison table free column is missing")
+require(preferences, 'Text(tr("settings.proCompare.pro"))', "Pro tab comparison table Pro column is missing")
+require(preferences, 'Image(systemName: "crown")', "Pro tab Pro column header must show a crown icon before the text")
+if 'Text(tr("settings.language"))' in preferences:
+ fail("Language tab must not render the removed header/title block")
+require(preferences, "centeredSettingsScrollContent<Content: View>", "settings pages with sparse content must use the shared global centering container")
+require(preferences, "centeredSettingsScrollContent(width: settingsContentWidth)", "language picker matrix must use the shared centered settings container")
+if preferences.count("centeredSettingsScrollContent(width: dataPanelWidth)") < 2:
+ fail("Pro and About pages must both use the shared centered settings container")
+require(preferences, ".frame(minHeight: proxy.size.height, alignment: .center)", "centered settings content must be vertically centered in the visible area")
+if "topLeadingAccessory: AnyView(" in preferences:
+ fail("Tags page must not render a second Pro guidance row inside the tag editor")
+if preferences.count("ScrollView(.vertical, showsIndicators: true)") < 3:
+ fail("hotkeys/data/about pages must use vertical scroll containers to avoid clipping")
require(preferences, "NSEvent.addLocalMonitorForEvents(matching: .keyDown)", "custom hotkey recording must be local to Settings")
require(preferences, "proEntitlement.startThemePreview(for: theme, tuning:", "premium theme free preview is missing")
require(preferences, "proEntitlement.stopThemePreview()", "theme preview cleanup is missing")
+require(preferences, "proEntitlement.startDisplayModePreview(for: mode)", "colored display mode free preview is missing")
+require(preferences, "displayModeOptionAccessory(for mode: String)", "colored display mode Pro badge/countdown accessory is missing")
+require(preferences, "isSelected: effectiveDisplayMode ==", "display mode buttons must select by effective display mode")
+require(preferences, ".frame(width: 64, alignment: .trailing)", "display mode buttons must reserve a fixed accessory slot")
require(pro, "func remainingSeconds(at date: Date = Date()) -> Int", "theme preview remaining-seconds helper is missing")
require(pro, "ceil(endsAt.timeIntervalSince(date))", "theme preview countdown must derive from endsAt")
require(preferences, "pro.theme.status.previewCountdown", "theme preview status countdown localization is missing")
@@ -147,6 +246,8 @@
require(content, "@ObservedObject private var proEntitlement = ProEntitlementCenter.shared", "ContentView does not observe Pro entitlement")
require(content, "ProEntitlementPolicy.effectiveTheme(for: appGridTheme)", "ContentView does not apply effective Pro theme")
+require(content, "ProEntitlementPolicy.effectiveDisplayMode(for: displayMode)", "ContentView does not apply effective Pro display mode")
+require(content, "displayMode: renderedDisplayMode", "AppGrid does not render the effective display mode")
require(content, "presentProPrompt(for: .unlimitedNotes", "note quota prompt is missing from AppGrid")
require(content, "tr(\"pro.sorting.previewToast\")", "free sorting preview toast is missing")
require(content, "if let preview = proEntitlement.themePreviewState", "theme preview acceptance path is missing")
@@ -156,8 +257,24 @@
require(access_views, "struct ProUpgradePromptView", "ProUpgradePromptView is missing")
require(access_views, "let onUnlock: () -> Void", "Pro upgrade prompt purchase callback is missing")
require(access_views, "let onRestore: () -> Void", "Pro upgrade prompt restore callback is missing")
+if "localizedCaseInsensitiveContains" in access_views:
+ fail("ProStatusPill must not hide the crown based on localized text content")
require(content, "onUnlock: { proEntitlement.purchasePro() }", "AppGrid Pro prompt is not wired to purchase action")
require(content, "onRestore: { proEntitlement.restorePurchases() }", "AppGrid Pro prompt is not wired to restore action")
-print("PASS Pro feature gate QA: StoreKit entitlement, legacy unlock, theme gating, import/export locks, note quota, sorting preview, and Pro UI prompts are wired")
+tag_editor = read("TagEditorView.swift")
+require(tag_editor, "ColorPicker(", "Pro custom tag colors must use a native macOS color picker path")
+require(tag_editor, "onLockedCustomColor", "locked custom color entry must route to the Pro prompt")
+require(tag_editor, "TagEditor.setCustomColor", "tag editor must persist Pro custom colors")
+require(tag_editor, "tagCustomColors.removeValue(forKey: tagName)", "base color selection must remove existing custom color")
+require(content, "tagCustomColors = snapshot.tagDefinitions.compactMapValues { $0.customColor }", "AppGrid snapshots must propagate custom tag colors")
+require(content, "customColor: tagCustomColors[$0.name]", "tag navigation must receive custom tag colors")
+app_grid = read("AppGridCollectionView.swift")
+tag_nav = read("TagNavigationView.swift")
+require(app_grid, "let tagCustomColors: [String: TagCustomColor]", "AppGrid must accept custom tag colors")
+require(app_grid, "func tagColor(for groupName: String) -> NSColor", "AppGrid must resolve custom tag color per group")
+require(tag_nav, "let customColor: TagCustomColor?", "Tag navigation items must carry custom colors")
+require(tag_nav, "TagColor.nsColor(for: item.colorIndex, customColor: item.customColor)", "Tag navigation must render custom colors")
+
+print("PASS Pro feature gate QA: StoreKit entitlement, legacy unlock, theme gating, import/export locks, 3-note quota, custom tag colors, custom hotkeys, sorting preview, and Pro UI prompts are wired")
PY
diff --git a/src/Scripts/pro_localization_qa.sh b/src/Scripts/pro_localization_qa.sh
index 3501623..dba4f4c 100755
--- a/src/Scripts/pro_localization_qa.sh
+++ b/src/Scripts/pro_localization_qa.sh
@@ -17,11 +17,66 @@
EXPECTED_LANGUAGE_COUNT = 29
ALLOWED_ENGLISH_COPY_KEYS = {
"pro.card.badge",
+ "settings.proCompare.pro",
}
REQUIRED_PLACEHOLDERS = {
"pro.notes.remaining": {"%limit%", "%remaining%"},
"pro.theme.status.previewCountdown": {"%time%"},
}
+REQUIRED_NON_PRO_KEYS = [
+ "settings.proStatus.freeUser",
+ "settings.proStatus.proUser",
+ "settings.proStatus.lockedListTitle",
+ "settings.proStatus.unlockedListTitle",
+ "settings.proStatus.lockedFeature",
+ "settings.proStatus.unlockedFeature",
+ "settings.proStatus.freeNotes",
+ "settings.proStatus.unlimitedNotes",
+ "settings.proStatus.limitedFeature",
+ "settings.proStatus.unsupportedFeature",
+ "settings.proStatus.unavailableFeature",
+ "settings.proStatus.previewFiveMinutes",
+ "settings.proFeature.appNotes",
+ "settings.proFeature.dataBackup",
+ "settings.proBenefit.general",
+ "settings.proBenefit.hotkeys",
+ "settings.proBenefit.tags",
+ "settings.proBenefit.data",
+ "settings.proBenefit.about",
+ "settings.proGuide.general",
+ "settings.proGuide.hotkeys",
+ "settings.proGuide.tags",
+ "settings.proGuide.data",
+ "settings.proCompare.title",
+ "settings.proCompare.free",
+ "settings.proCompare.pro",
+ "tag.customColor",
+]
+REQUIRED_VISIBLE_SETTINGS_KEYS = [
+ "settings.bubbleDisplayScope",
+ "settings.bubbleAllApps",
+ "settings.bubbleUncommonOnly",
+ "quickSearch.hotkeys",
+ "quickSearch.mainHotkey",
+ "quickSearch.mainHotkeyDesc",
+ "quickSearch.internalHotkey",
+ "quickSearch.internalHotkeyDesc",
+ "quickSearch.internalHotkeyStatus",
+ "quickSearch.globalHotkey",
+ "quickSearch.globalHotkeyDesc",
+ "quickSearch.status.Active",
+ "quickSearch.status.registrationFailed",
+ "quickSearch.status.unavailable",
+ "quickSearch.mainHotkeyUnavailableMessage",
+ "quickSearch.globalHotkeyUnavailableMessage",
+ "quickSearch.spaceDisplay",
+]
+OLD_NOTE_LIMIT_PATTERNS = [
+ re.compile(r"5[- ]?(note|notes|app notes)", re.I),
+ re.compile(r"5\s*个应用备注"),
+ re.compile(r"5\s*條備註"),
+ re.compile(r"5\s*条备注"),
+]
def fail(message: str) -> None:
@@ -61,26 +116,69 @@
pro_keys = [key for key in english if key.startswith("pro.")]
if not pro_keys:
fail("en.json has no pro.* keys")
+if english.get("settings.proStatus.lockedFeature") != "✅ Supported":
+ fail("en.json Pro comparison support status must be '✅ Supported'")
+if english.get("settings.proStatus.unlimitedNotes") != "✅ Unlimited notes":
+ fail("en.json Pro comparison unlimited notes status must include the leading checkmark")
+if english.get("settings.proStatus.unlockedFeature") != "✅ Unlocked":
+ fail("en.json Pro comparison unlocked status must be '✅ Unlocked'")
+
+zh_hans = load_json(localization_dir / "zh-Hans.json")
+if zh_hans.get("settings.proStatus.lockedFeature") != "✅支持":
+ fail("zh-Hans.json Pro comparison support status must be '✅支持'")
+if zh_hans.get("settings.proStatus.unlimitedNotes") != "✅无限备注":
+ fail("zh-Hans.json Pro comparison unlimited notes status must be '✅无限备注'")
+if zh_hans.get("settings.proStatus.unlockedFeature") != "✅已解锁":
+ fail("zh-Hans.json Pro comparison unlocked status must be '✅已解锁'")
+
+ko = load_json(localization_dir / "ko.json")
+if ko.get("quickSearch.hotkeys") != "키보드 단축키":
+ fail("ko.json quickSearch.hotkeys must not fall back to English")
+if ko.get("quickSearch.mainHotkey") != "앱 목록":
+ fail("ko.json quickSearch.mainHotkey must not fall back to English")
+if ko.get("quickSearch.status.Active") != "활성":
+ fail("ko.json quickSearch.status.Active must not fall back to English")
+if ko.get("settings.bubbleDisplayScope") != "말풍선 팁 표시 대상:":
+ fail("ko.json settings.bubbleDisplayScope must not fall back to English")
+
+ar = load_json(localization_dir / "ar.json")
+if ar.get("quickSearch.hotkeys") != "اختصارات لوحة المفاتيح":
+ fail("ar.json quickSearch.hotkeys must not fall back to English")
+if ar.get("quickSearch.mainHotkey") != "قائمة التطبيقات":
+ fail("ar.json quickSearch.mainHotkey must not fall back to English")
+if ar.get("quickSearch.status.Active") != "مفعّل":
+ fail("ar.json quickSearch.status.Active must not fall back to English")
+if ar.get("settings.bubbleDisplayScope") != "إظهار تلميحات الفقاعات لـ:":
+ fail("ar.json settings.bubbleDisplayScope must not fall back to English")
for code in language_codes:
path = localization_dir / f"{code}.json"
if not path.is_file():
fail(f"missing localization file: {path}")
data = load_json(path)
+ required_keys = pro_keys + REQUIRED_NON_PRO_KEYS + REQUIRED_VISIBLE_SETTINGS_KEYS
missing = [
- key for key in pro_keys
+ key for key in required_keys
if not isinstance(data.get(key), str) or not data.get(key, "").strip()
]
if missing:
- fail(f"{code}.json is missing pro translations: {', '.join(missing)}")
+ fail(f"{code}.json is missing Pro/settings translations: {', '.join(missing)}")
badge = data["pro.card.badge"]
if data.get("pro.card.title.free") == badge:
fail(f"{code}.json uses the badge text as the upgrade title for pro.card.title.free")
- dirty_keys = [key for key in pro_keys if "__" in data[key] or "###FILE" in data[key]]
+ dirty_keys = [key for key in required_keys if "__" in data[key] or "###FILE" in data[key]]
if dirty_keys:
fail(f"{code}.json still contains placeholder artifacts: {', '.join(dirty_keys)}")
+
+ old_limit_keys = [
+ key for key, value in data.items()
+ if isinstance(value, str)
+ and any(pattern.search(value) for pattern in OLD_NOTE_LIMIT_PATTERNS)
+ ]
+ if old_limit_keys:
+ fail(f"{code}.json still contains old 5-note copy: {', '.join(old_limit_keys)}")
placeholder_errors = []
for key, placeholders in REQUIRED_PLACEHOLDERS.items():
@@ -93,7 +191,7 @@
if code != "en":
copied_english = [
- key for key in pro_keys
+ key for key in required_keys
if key not in ALLOWED_ENGLISH_COPY_KEYS and data.get(key) == english.get(key)
]
if copied_english:
@@ -101,7 +199,7 @@
print(
"PASS Pro localization QA: "
- f"{len(language_codes)} languages, {len(pro_keys)} keys, "
+ f"{len(language_codes)} languages, {len(pro_keys) + len(REQUIRED_NON_PRO_KEYS) + len(REQUIRED_VISIBLE_SETTINGS_KEYS)} Pro/settings keys, "
"no placeholder artifacts or English fallback copies"
)
PY
diff --git a/src/Scripts/pro_notes_quota_qa.sh b/src/Scripts/pro_notes_quota_qa.sh
new file mode 100644
index 0000000..136c629
--- /dev/null
+++ b/src/Scripts/pro_notes_quota_qa.sh
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+python3 - "$ROOT_DIR" <<'PY'
+import re
+import sys
+from pathlib import Path
+
+root = Path(sys.argv[1])
+app_dir = root / "Apptag"
+
+
+def fail(message: str) -> None:
+ raise SystemExit(f"FAIL: {message}")
+
+
+def read(name: str) -> str:
+ return (app_dir / name).read_text(encoding="utf-8")
+
+
+def require(source: str, needle: str, message: str) -> None:
+ if needle not in source:
+ fail(message)
+
+
+def function_body(source: str, signature: str) -> str:
+ start = source.find(signature)
+ if start == -1:
+ fail(f"missing function signature: {signature}")
+ brace = source.find("{", start)
+ depth = 0
+ for index in range(brace, len(source)):
+ char = source[index]
+ if char == "{":
+ depth += 1
+ elif char == "}":
+ depth -= 1
+ if depth == 0:
+ return source[brace + 1:index]
+ fail(f"unterminated function body for: {signature}")
+
+
+pro = read("ProEntitlement.swift")
+data_layer = read("DataLayer.swift")
+content = read("ContentView.swift")
+english = (app_dir / "Localization" / "en.json").read_text(encoding="utf-8")
+chinese = (app_dir / "Localization" / "zh-Hans.json").read_text(encoding="utf-8")
+
+require(pro, "static let freeNoteLimit = 3", "free note limit must be 3")
+decision_body = function_body(pro, "static func noteSaveDecision(note: String, for path: String, in store: TagDatabase.Store? = nil) -> ProNoteSaveDecision")
+require(decision_body, "manualNonEmptyNotePaths", "quota must count manual non-empty notes")
+require(decision_body, "let hasExistingManualNote = manualNotePaths.contains(path)", "editing an existing note must not consume new quota")
+require(decision_body, "guard manualNotePaths.count < limit else", "new notes beyond quota must be blocked")
+require(decision_body, "case (true, false):", "deleting an existing note must release quota")
+
+set_note_body = function_body(data_layer, "static func setAppNote(_ note: String, for path: String) -> ProNoteSaveDecision")
+require(set_note_body, "ProEntitlementPolicy.noteSaveDecision", "note writes must ask Pro policy")
+require(set_note_body, "guard case .allow = decision else", "blocked note writes must return before mutation")
+require(set_note_body, "store.appNotes.removeValue(forKey: path)", "empty note must delete saved note")
+require(set_note_body, "store.appNotes[path] = limited", "allowed non-empty note must save")
+
+require(content, "presentProPrompt(for: .unlimitedNotes, noteQuotaStatus: status)", "blocked note save must show Pro prompt")
+require(content, "noteQuotaHintText(for: context.app)", "editing bubble must show quota hint")
+require(english, "3 app notes", "English UI must say 3 app notes")
+require(chinese, "3 个应用备注", "Simplified Chinese UI must say 3 app notes")
+if re.search(r"5[- ]?(note|app notes)|5 个应用备注|5 条备注", english + chinese):
+ fail("old 5-note copy remains in English or Simplified Chinese")
+
+print("PASS Pro notes quota QA: free limit is 3, existing edits/deletes are handled, over-quota writes are blocked, and UI copy no longer says 5 notes")
+PY
diff --git a/src/Scripts/pro_tag_custom_color_qa.sh b/src/Scripts/pro_tag_custom_color_qa.sh
new file mode 100644
index 0000000..f0df13e
--- /dev/null
+++ b/src/Scripts/pro_tag_custom_color_qa.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+
+python3 - "$ROOT_DIR" <<'PY'
+import sys
+from pathlib import Path
+
+root = Path(sys.argv[1])
+app_dir = root / "Apptag"
+
+
+def fail(message: str) -> None:
+ raise SystemExit(f"FAIL: {message}")
+
+
+def read(name: str) -> str:
+ return (app_dir / name).read_text(encoding="utf-8")
+
+
+def require(source: str, needle: str, message: str) -> None:
+ if needle not in source:
+ fail(message)
+
+
+data_layer = read("DataLayer.swift")
+tag_editor = read("TagEditorView.swift")
+preferences = read("PreferencesView.swift")
+content = read("ContentView.swift")
+app_grid = read("AppGridCollectionView.swift")
+tag_nav = read("TagNavigationView.swift")
+pro = read("ProEntitlement.swift")
+access = read("ProAccessViews.swift")
+
+require(pro, "case customTagColors", "ProFeature.customTagColors is missing")
+require(access, "case .customTagColors:", "custom tag color prompt key is missing")
+require(data_layer, "struct TagCustomColor: Codable, Equatable", "custom color data type is missing")
+require(data_layer, "var customColor: TagCustomColor? = nil", "TagDef customColor must be optional for old data compatibility")
+require(data_layer, "customColor?.nsColor ?? nsColor(for: index)", "custom color must win over base color")
+require(data_layer, "tagDef.customColor = nil", "base color selection must clear custom color")
+require(data_layer, "guard ProEntitlementPolicy.isUnlocked(.customTagColors) else", "custom color write must be gated at data layer")
+
+require(tag_editor, "ColorPicker(", "Pro path must use native ColorPicker")
+require(tag_editor, "supportsOpacity: false", "custom color picker should avoid opacity for tag colors")
+require(tag_editor, "onLockedCustomColor", "free path must trigger Pro prompt")
+require(tag_editor, "customColorSwatch(tagName: tagName, colorIndex: colorIndex, isSelected: isSelected)", "custom color entry must use the shared horizontal Pro swatch")
+require(tag_editor, 'Image(systemName: "crown")', "custom color swatch must show a line-style crown Pro cue")
+require(tag_editor, "Color.white", "custom color selected/crown cue must use white visual contrast")
+if 'Text(tr("tag.customColor"))' in tag_editor:
+ fail("custom color entry must not show the old text label")
+require(tag_editor, "TagEditor.setCustomColor(customColor, for: tagName)", "ColorPicker changes must persist custom color")
+require(tag_editor, "tagCustomColors.removeValue(forKey: tagName)", "base swatches must allow reverting from custom color")
+
+require(preferences, "presentSettingsProPrompt(for: .customTagColors)", "Settings tag page must prompt for locked custom colors")
+require(content, "presentProPrompt(for: .customTagColors)", "overlay tag editor must prompt for locked custom colors")
+require(content, "tagCustomColors = snapshot.tagDefinitions.compactMapValues { $0.customColor }", "main snapshot must load custom colors")
+require(app_grid, "tagCustomColors: [String: TagCustomColor]", "AppGrid must receive custom colors")
+require(app_grid, "customColor: tagCustomColors[groupName]", "AppGrid must resolve custom group colors")
+require(tag_nav, "let customColor: TagCustomColor?", "tag navigation must carry custom color")
+require(tag_nav, "customColor: item.customColor", "tag navigation must render custom color")
+
+print("PASS Pro custom tag color QA: data model, Pro gates, native picker, locked prompt, base-color revert, and display propagation are wired")
+PY
diff --git a/src/Scripts/pro_theme_preview_countdown_qa.sh b/src/Scripts/pro_theme_preview_countdown_qa.sh
index 255be3b..2592237 100755
--- a/src/Scripts/pro_theme_preview_countdown_qa.sh
+++ b/src/Scripts/pro_theme_preview_countdown_qa.sh
@@ -55,6 +55,10 @@
"func remainingSeconds(at date: Date = Date()) -> Int",
"ceil(endsAt.timeIntervalSince(date))",
"max(0, Int(",
+ "struct ProDisplayModePreviewState: Equatable",
+ "func startDisplayModePreview(for displayMode: String)",
+ "endsAt: now.addingTimeInterval(ProEntitlementConfig.themePreviewDuration)",
+ "func stopDisplayModePreview()",
]
missing_pro = [needle for needle in required_pro if needle not in pro_text]
if missing_pro:
@@ -66,9 +70,11 @@
"pro.theme.status.previewCountdown",
".replacingOccurrences(of: \"%time%\", with: countdown)",
".countdown(text: themePreviewCountdownText ?? \"00:00\")",
+ "proEntitlement.displayModePreviewState",
"formatThemePreviewCountdown(seconds:",
"String(format: \"%02d:%02d\"",
"proEntitlement.stopThemePreview()",
+ "proEntitlement.stopDisplayModePreview()",
".font(.system(size: 10, weight: .semibold, design: .monospaced))",
]
missing_preferences = [needle for needle in required_preferences if needle not in preferences_text]
diff --git a/src/Scripts/quick_search_launch_contract_qa.sh b/src/Scripts/quick_search_launch_contract_qa.sh
new file mode 100755
index 0000000..8dd93e9
--- /dev/null
+++ b/src/Scripts/quick_search_launch_contract_qa.sh
@@ -0,0 +1,181 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+APP_DELEGATE="$ROOT_DIR/Apptag/ApptagApp.swift"
+QUICK_SEARCH="$ROOT_DIR/Apptag/QuickSearch.swift"
+CONTENT_VIEW="$ROOT_DIR/Apptag/ContentView.swift"
+
+python3 - "$APP_DELEGATE" "$QUICK_SEARCH" "$CONTENT_VIEW" <<'PY'
+import re
+import sys
+from pathlib import Path
+
+app_delegate = Path(sys.argv[1]).read_text(encoding="utf-8")
+quick_search = Path(sys.argv[2]).read_text(encoding="utf-8")
+content_view = Path(sys.argv[3]).read_text(encoding="utf-8")
+
+
+def fail(message: str) -> None:
+ print(f"FAIL: {message}", file=sys.stderr)
+ sys.exit(1)
+
+
+def require(condition: bool, message: str) -> None:
+ if not condition:
+ fail(message)
+
+
+def require_contains(text: str, needle: str, message: str) -> None:
+ require(needle in text, message)
+
+
+local_monitor = re.search(
+ r"private func installQuickSearchLocalMouseMonitor\(\).*?private func removeQuickSearchExternalMouseMonitor\(\)",
+ app_delegate,
+ re.S,
+)
+require(local_monitor is not None, "Quick Search local mouse monitor block is missing")
+local_monitor_body = local_monitor.group(0)
+require_contains(
+ local_monitor_body,
+ "if event.window === self.overlayWindow {\n return event\n }",
+ "local mouse monitor must pass through overlayWindow events so result rows receive clicks",
+)
+require(
+ "tagLauncherQuickSearchDismissRequested" not in local_monitor_body,
+ "local mouse monitor must not dismiss/swallow clicks inside the overlay window",
+)
+
+panel_apply = re.search(
+ r"func apply\(_ configuration: QuickSearchPanelConfiguration, anchorView: QuickSearchPanelAnchorView\).*?func closePanel\(\)",
+ quick_search,
+ re.S,
+)
+require(panel_apply is not None, "QuickSearchPanel apply block is missing")
+panel_apply_body = panel_apply.group(0)
+activate_index = panel_apply_body.find("NSApp.activate(ignoringOtherApps: true)")
+make_key_index = panel_apply_body.find("panel.makeKeyAndOrderFront(nil)")
+require(activate_index >= 0, "Quick Search panel must activate the app before accepting keyboard input")
+require(make_key_index >= 0, "Quick Search panel must be made key and ordered front")
+require(
+ activate_index < make_key_index,
+ "Quick Search panel activation must happen before makeKeyAndOrderFront",
+)
+
+panel_factory = re.search(
+ r"private func ensurePanel\(parentWindow: NSWindow\).*?let panel = QuickSearchPanel\((.*?)\n \)",
+ quick_search,
+ re.S,
+)
+require(panel_factory is not None, "QuickSearchPanel factory block is missing")
+require(
+ ".nonactivatingPanel" not in panel_factory.group(0),
+ "Quick Search panel must not use .nonactivatingPanel; Return can otherwise go to the previous app",
+)
+require_contains(
+ quick_search,
+ "override var canBecomeKey: Bool { true }",
+ "Quick Search panel must be allowed to become key",
+)
+panel_class = re.search(
+ r"private final class QuickSearchPanel: NSPanel.*?final class QuickSearchPanelAnchorView",
+ quick_search,
+ re.S,
+)
+require(panel_class is not None, "QuickSearchPanel class block is missing")
+panel_class_body = panel_class.group(0)
+for needle, message in [
+ ("override func sendEvent(_ event: NSEvent)", "Quick Search panel must intercept mouse events before SwiftUI/scroll intermediate views can drop result clicks"),
+ ("event.type == .leftMouseDown", "Quick Search panel click fallback must be limited to left mouse down"),
+ ("quickSearchResultRow(at: event.locationInWindow)", "Quick Search panel must resolve the clicked result row from the window point"),
+ ("row.launchFromMouseClick()", "Quick Search panel must launch the resolved result row directly"),
+ ("quickSearchResultRowFromHitTest(atWindowPoint: windowPoint)", "Quick Search panel should keep the direct hitTest path for normal AppKit row clicks"),
+ ("quickSearchResultRowDescendant(containingWindowPoint: windowPoint)", "Quick Search panel must use a recursive geometry fallback when SwiftUI/scroll intermediate views hide rows from hitTest"),
+]:
+ require_contains(panel_class_body, needle, message)
+
+for needle, message in [
+ ("func quickSearchResultRowDescendant(containingWindowPoint windowPoint: NSPoint) -> QuickSearchResultRowView?", "Quick Search must expose a recursive row lookup fallback"),
+ ("for subview in subviews.reversed()", "Quick Search recursive lookup must scan frontmost subviews first"),
+ ("row.containsWindowPointForLaunch(windowPoint)", "Quick Search recursive lookup must verify the clicked window point is inside a result row"),
+]:
+ require_contains(quick_search, needle, message)
+
+text_field = re.search(
+ r"private struct QuickSearchTextField: NSViewRepresentable.*?private final class QuickSearchNativeTextField",
+ quick_search,
+ re.S,
+)
+require(text_field is not None, "QuickSearchTextField block is missing")
+text_field_body = text_field.group(0)
+for needle, message in [
+ ("field.target = context.coordinator", "Quick Search text field must set a target for Return submit fallback"),
+ ("field.action = #selector(Coordinator.submitAction(_:))", "Quick Search text field must set submitAction as its action"),
+ ("@objc func submitAction(_ sender: Any?)", "Quick Search coordinator must expose submitAction"),
+ ("onCommand?(.submit)", "Quick Search submitAction/delegate path must emit .submit"),
+]:
+ require_contains(text_field_body, needle, message)
+
+row_view = re.search(
+ r"final class QuickSearchResultRowView: NSView.*?private func setup\(\)",
+ quick_search,
+ re.S,
+)
+require(row_view is not None, "QuickSearchResultRowView block is missing")
+row_view_body = row_view.group(0)
+require_contains(
+ row_view_body,
+ "override func acceptsFirstMouse(for event: NSEvent?) -> Bool {\n true\n }",
+ "Quick Search result rows must accept first mouse",
+)
+require_contains(
+ row_view_body,
+ "override func mouseDown(with event: NSEvent)",
+ "Quick Search result rows must handle mouseDown",
+)
+require_contains(
+ row_view_body,
+ "onLaunch(result)",
+ "Quick Search result rows must launch their result on click",
+)
+require_contains(
+ row_view_body,
+ "func launchFromMouseClick() -> Bool",
+ "Quick Search result rows must expose a panel-level click fallback",
+)
+require_contains(
+ row_view_body,
+ "func containsWindowPointForLaunch(_ windowPoint: NSPoint) -> Bool",
+ "Quick Search result rows must expose geometry-based click containment for panel fallback",
+)
+require_contains(
+ row_view_body,
+ "bounds.contains(localPoint) && visibleRect.contains(localPoint)",
+ "Quick Search result row geometry fallback must reject hidden or clipped row areas",
+)
+require_contains(
+ row_view_body,
+ "DispatchQueue.main.async { [onLaunch, result] in",
+ "Quick Search row launch fallback must capture the clicked result before async launch",
+)
+
+command_submit = re.search(
+ r"private func handleQuickSearchCommand\(_ command: QuickSearchCommand\).*?private var selectedQuickSearchResult",
+ content_view,
+ re.S,
+)
+require(command_submit is not None, "ContentView Quick Search command handler is missing")
+require_contains(
+ command_submit.group(0),
+ "case .submit:\n guard let selected = selectedQuickSearchResult else { return }\n launchQuickSearchResult(selected)",
+ "Quick Search submit command must launch the selected result",
+)
+require_contains(
+ content_view,
+ "NSWorkspace.shared.openApplication(at: app.path, configuration: configuration)",
+ "Quick Search launch path must still use NSWorkspace.openApplication",
+)
+
+print("PASS quick search launch contract")
+PY
diff --git a/src/Scripts/theme_settings_qa.sh b/src/Scripts/theme_settings_qa.sh
index 8e64319..e548dbe 100755
--- a/src/Scripts/theme_settings_qa.sh
+++ b/src/Scripts/theme_settings_qa.sh
@@ -73,6 +73,8 @@
raise SystemExit("theme tuning defaults are missing")
if "static let iconSize: Double = 56" not in defaults_source:
raise SystemExit("new-install default icon size must be 56")
+if 'static let displayMode = "gridContainer"' not in defaults_source:
+ raise SystemExit("new-install default display mode must remain a free mode")
if "var isPureBlackBackground: Bool" not in theme_source or "self == .black" not in theme_source:
raise SystemExit("pure black background policy is missing")
if "case .deepBlue, .black:" not in theme_source or "return true" not in theme_source:
--
Gitblit v1.9.3