mirror of
https://github.com/lobehub/lobe-chat.git
synced 2026-06-16 12:36:07 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f1be9911a |
@@ -1,959 +0,0 @@
|
||||
# createStaticStyles 迁移指南
|
||||
|
||||
## 📖 概述
|
||||
|
||||
`createStaticStyles` 是 `antd-style` 提供的静态样式创建函数,相比 `createStyles`(hook 方案)具有零运行时开销的优势。样式在模块加载时计算一次,而不是每次组件渲染时计算。
|
||||
|
||||
## 🎯 适用场景
|
||||
|
||||
### ✅ 可以优化的场景
|
||||
|
||||
1. **纯静态样式**:不依赖运行时动态值
|
||||
2. **使用标准 token**:所有 token 都在 `cssVar.json` 中有对应项
|
||||
3. **简单的条件逻辑**:可以通过静态样式拆分处理
|
||||
|
||||
### ❌ 无法优化的场景
|
||||
|
||||
1. **JS 计算函数**:`readableColor()`, `chroma()`, `mix()`, `calc()` 中使用 token 数值
|
||||
2. **复杂的动态 props**:需要运行时计算的复杂逻辑
|
||||
3. **动态 prefixCls**:需要运行时传入的类名前缀(但可以硬编码为 `'ant'`)
|
||||
|
||||
## 🔄 基本转换步骤
|
||||
|
||||
### 1. 样式文件转换
|
||||
|
||||
**之前(createStyles):**
|
||||
|
||||
```typescript
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
export const useStyles = createStyles(({ css, token }) => {
|
||||
return {
|
||||
root: css`
|
||||
color: ${token.colorText};
|
||||
font-size: ${token.fontSize}px;
|
||||
`,
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
**之后(createStaticStyles):**
|
||||
|
||||
```typescript
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => {
|
||||
return {
|
||||
root: css`
|
||||
color: ${cssVar.colorText};
|
||||
font-size: ${cssVar.fontSize};
|
||||
`,
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
### 2. 组件文件转换
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
import { useStyles } from './style';
|
||||
|
||||
const Component = () => {
|
||||
const { styles, cx } = useStyles();
|
||||
return <div className={cx(styles.root, className)} />;
|
||||
};
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
import { cx } from 'antd-style';
|
||||
import { styles } from './style';
|
||||
|
||||
const Component = () => {
|
||||
return <div className={cx(styles.root, className)} />;
|
||||
};
|
||||
```
|
||||
|
||||
## 🛠️ 常见场景处理
|
||||
|
||||
### 场景 1: Token 转换
|
||||
|
||||
**规则:**
|
||||
|
||||
- `token.xxx` → `cssVar.xxx`
|
||||
- 注意:`cssVar.fontSize` 已经包含 `px` 单位,不需要再加 `px`
|
||||
|
||||
**示例:**
|
||||
|
||||
```typescript
|
||||
// ❌ 错误
|
||||
font-size: ${cssVar.fontSize}px; // cssVar.fontSize 已经是 "14px"
|
||||
|
||||
// ✅ 正确
|
||||
font-size: ${cssVar.fontSize}; // 直接使用
|
||||
```
|
||||
|
||||
**特殊情况 - calc ():**
|
||||
|
||||
```typescript
|
||||
// ❌ 错误
|
||||
calc(${token.fontSize}px * 2.5)
|
||||
|
||||
// ✅ 正确
|
||||
calc(${cssVar.fontSize} * 2.5) // cssVar.fontSize 已经包含单位
|
||||
```
|
||||
|
||||
### 场景 2: 动态 Props → CSS 变量
|
||||
|
||||
**适用:** 数值、字符串类型的 props
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 在样式文件中使用 CSS 变量(带默认值)
|
||||
2. 在组件中通过 `style` prop 设置 CSS 变量
|
||||
|
||||
**示例:**
|
||||
|
||||
**样式文件:**
|
||||
|
||||
```typescript
|
||||
export const styles = createStaticStyles(({ css }) => {
|
||||
return {
|
||||
root: css`
|
||||
width: var(--component-size, 24px);
|
||||
height: var(--component-size, 24px);
|
||||
`,
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
**组件文件:**
|
||||
|
||||
```typescript
|
||||
import { useMemo } from 'react';
|
||||
|
||||
const Component = ({ size = 24, style, ...rest }) => {
|
||||
const cssVariables = useMemo<Record<string, string>>(
|
||||
() => ({
|
||||
'--component-size': `${size}px`,
|
||||
}),
|
||||
[size],
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.root}
|
||||
style={{
|
||||
...cssVariables,
|
||||
...style,
|
||||
}}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Video`: `maxHeight`, `maxWidth`, `minHeight`, `minWidth`
|
||||
- `ScrollShadow`: `size`
|
||||
- `MaskShadow`: `size`
|
||||
- `ColorSwatches`: `size`
|
||||
- `Grid`: `rows`, `maxItemWidth`, `gap`
|
||||
- `Layout`: `headerHeight`
|
||||
- `Footer`: `contentMaxWidth`
|
||||
|
||||
### 场景 3: 布尔值 Props → 静态样式拆分
|
||||
|
||||
**适用:** 简单的布尔值 props(2-3 个)
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 创建所有可能的组合样式
|
||||
2. 运行时使用 `cx` 组合
|
||||
|
||||
**示例:**
|
||||
|
||||
**样式文件:**
|
||||
|
||||
```typescript
|
||||
export const styles = createStaticStyles(({ css }) => {
|
||||
return {
|
||||
root: css`
|
||||
/* base styles */
|
||||
`,
|
||||
root_closable_true: css`
|
||||
/* closable styles */
|
||||
`,
|
||||
root_closable_false: css`
|
||||
/* no closable styles */
|
||||
`,
|
||||
root_hasTitle_true: css`
|
||||
/* has title styles */
|
||||
`,
|
||||
root_hasTitle_false: css`
|
||||
/* no title styles */
|
||||
`,
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
**组件文件:**
|
||||
|
||||
```typescript
|
||||
const Component = ({ closable, hasTitle }) => {
|
||||
const className = cx(
|
||||
styles.root,
|
||||
styles[`root_closable_${!!closable}`],
|
||||
styles[`root_hasTitle_${!!hasTitle}`],
|
||||
);
|
||||
return <div className={className} />;
|
||||
};
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Alert`: `closable`, `hasTitle`, `showIcon` → 8 个组合(2×2×2)
|
||||
- `Image`: `alwaysShowActions` → 2 个样式
|
||||
- `StoryBook`: `noPadding` → 2 个样式
|
||||
|
||||
### 场景 4: isDarkMode → 静态样式拆分
|
||||
|
||||
**适用:** 依赖 `isDarkMode` 的条件样式
|
||||
|
||||
**有两种处理方式:**
|
||||
|
||||
#### 方式 A: 直接条件选择(简单场景)
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 创建 `Dark` 和 `Light` 两个静态样式
|
||||
2. 运行时根据 `theme.isDarkMode` 选择
|
||||
|
||||
**示例:**
|
||||
|
||||
**样式文件:**
|
||||
|
||||
```typescript
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => {
|
||||
return {
|
||||
rootDark: css`
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
color: ${cssVar.colorTextLightSolid};
|
||||
`,
|
||||
rootLight: css`
|
||||
background: ${cssVar.colorFillQuaternary};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
**组件文件:**
|
||||
|
||||
```typescript
|
||||
import { useThemeMode } from 'antd-style';
|
||||
|
||||
const Component = () => {
|
||||
const { isDarkMode } = useThemeMode();
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
isDarkMode ? styles.rootDark : styles.rootLight
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
#### 方式 B: 使用 cva 将 isDarkMode 作为 variant(推荐,适用于复杂场景)
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 创建 `Dark` 和 `Light` 两个静态样式
|
||||
2. 在 `cva` 中将 `isDarkMode` 作为 variant prop
|
||||
3. 运行时直接传入 `isDarkMode` 值
|
||||
|
||||
**示例:**
|
||||
|
||||
**样式文件:**
|
||||
|
||||
```typescript
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { cva } from 'class-variance-authority';
|
||||
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => {
|
||||
return {
|
||||
filledDark: css`
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
color: ${cssVar.colorTextLightSolid};
|
||||
`,
|
||||
filledLight: css`
|
||||
background: ${cssVar.colorFillQuaternary};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
outlined: css`
|
||||
border: 1px solid ${cssVar.colorBorder};
|
||||
`,
|
||||
root: css`
|
||||
/* base styles */
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
export const variants = cva(styles.root, {
|
||||
defaultVariants: {
|
||||
isDarkMode: false,
|
||||
variant: 'filled',
|
||||
},
|
||||
variants: {
|
||||
isDarkMode: {
|
||||
false: null,
|
||||
true: null, // isDarkMode 本身不添加样式,通过 compoundVariants 组合
|
||||
},
|
||||
variant: {
|
||||
filled: null, // variant 本身不添加样式,通过 compoundVariants 组合
|
||||
outlined: styles.outlined,
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
class: styles.filledDark,
|
||||
isDarkMode: true,
|
||||
variant: 'filled',
|
||||
},
|
||||
{
|
||||
class: styles.filledLight,
|
||||
isDarkMode: false,
|
||||
variant: 'filled',
|
||||
},
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
**组件文件:**
|
||||
|
||||
```typescript
|
||||
import { useThemeMode } from 'antd-style';
|
||||
import { variants } from './style';
|
||||
|
||||
const Component = ({ variant = 'filled' }) => {
|
||||
const { isDarkMode } = useThemeMode();
|
||||
return (
|
||||
<div
|
||||
className={variants({ isDarkMode, variant })}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
**优势:**
|
||||
|
||||
- ✅ 不需要 `useMemo` 动态创建 variants
|
||||
- ✅ 更符合 `cva` 的设计理念
|
||||
- ✅ 代码更简洁,性能更好
|
||||
- ✅ 类型安全,IDE 自动补全
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `TypewriterEffect`: `textDark` / `textLight`(方式 A)
|
||||
- `Collapse`: `filledDark` / `filledLight`(可优化为方式 B)
|
||||
- `Hotkey`: `inverseThemeDark` / `inverseThemeLight`(可优化为方式 B)
|
||||
- `GuideCard`: `filledDark` / `filledLight`(可优化为方式 B)
|
||||
- `GradientButton`: `buttonDark` / `buttonLight`(方式 A)
|
||||
|
||||
### 场景 5: responsive → 静态 responsive
|
||||
|
||||
**适用:** 使用响应式断点
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 导入静态 `responsive` from `antd-style`
|
||||
2. 使用 `responsive.sm` 替代 `responsive.mobile`
|
||||
3. 从 `createStyles` 参数中移除 `responsive`
|
||||
|
||||
**示例:**
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
export const useStyles = createStyles(({ css, responsive }) => ({
|
||||
root: css`
|
||||
${responsive.mobile} {
|
||||
padding: 12px;
|
||||
}
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
import { responsive } from 'antd-style';
|
||||
|
||||
export const styles = createStaticStyles(({ css }) => ({
|
||||
root: css`
|
||||
${responsive.sm} {
|
||||
padding: 12px;
|
||||
}
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**注意:**
|
||||
|
||||
- `responsive.mobile` → `responsive.sm`
|
||||
- 静态 `responsive` 提供:`xs`, `sm`, `md`, `lg`, `xl`, `xxl`
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Header`: `responsive.mobile` → `responsive.sm`
|
||||
- `FormModal`: `responsive.mobile` → `responsive.sm`
|
||||
- `Hero`: `responsive.mobile` → `responsive.sm`
|
||||
|
||||
### 场景 6: stylish → lobeStaticStylish
|
||||
|
||||
**适用:** 使用自定义 `stylish` 工具
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 导入 `lobeStaticStylish` from `@/styles`
|
||||
2. 替换 `stylish.xxx` → `lobeStaticStylish.xxx`
|
||||
|
||||
**示例:**
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
export const useStyles = createStyles(({ css, stylish }) => ({
|
||||
root: css`
|
||||
${stylish.blur};
|
||||
${stylish.variantFilled};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
import { lobeStaticStylish } from '@/styles';
|
||||
|
||||
export const styles = createStaticStyles(({ css }) => ({
|
||||
root: css`
|
||||
${lobeStaticStylish.blur};
|
||||
${lobeStaticStylish.variantFilled};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Button`: `stylish.blur` → `lobeStaticStylish.blur`
|
||||
- `Hero`: `stylish.gradientAnimation` → `lobeStaticStylish.gradientAnimation`
|
||||
|
||||
### 场景 7: prefixCls → 硬编码
|
||||
|
||||
**适用:** 使用动态 `prefixCls` 参数
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 在文件顶部硬编码 `const prefixCls = 'ant'`
|
||||
2. 从 `createStyles` 参数中移除 `prefixCls`
|
||||
|
||||
**示例:**
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
export const useStyles = createStyles(({ css }, prefixCls: string) => ({
|
||||
root: css`
|
||||
.${prefixCls}-button {
|
||||
/* styles */
|
||||
}
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
const prefixCls = 'ant';
|
||||
|
||||
export const styles = createStaticStyles(({ css }) => ({
|
||||
root: css`
|
||||
.${prefixCls}-button {
|
||||
/* styles */
|
||||
}
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Alert`, `Collapse`, `FormModal`, `Image`, `Burger`, `DraggablePanel`, `DraggableSideNav`, `Toc`, `ColorSwatches`, `EmojiPicker`, `Form`, `awesome/Features`
|
||||
|
||||
### 场景 8: readableColor () → Token 替换
|
||||
|
||||
**适用:** 使用 `readableColor()` 计算对比色
|
||||
|
||||
**规则:**
|
||||
|
||||
- `readableColor(token.colorPrimary)` → `cssVar.colorTextLightSolid`(主色背景用白色文字)
|
||||
- `readableColor(token.colorTextQuaternary)` → `cssVar.colorText`(浅色背景用深色文字)
|
||||
|
||||
**示例:**
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
import { readableColor } from 'polished';
|
||||
|
||||
export const useStyles = createStyles(({ css, token }) => ({
|
||||
checked: css`
|
||||
background-color: ${token.colorPrimary};
|
||||
color: ${readableColor(token.colorPrimary)};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
checked: css`
|
||||
background-color: ${cssVar.colorPrimary};
|
||||
color: ${cssVar.colorTextLightSolid};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Checkbox`: `readableColor(token.colorPrimary)` → `cssVar.colorTextLightSolid`
|
||||
|
||||
### 场景 9: rgba () → color-mix ()
|
||||
|
||||
**适用:** 使用 `rgba()` 设置透明度
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 使用 CSS 原生的 `color-mix()` 函数
|
||||
2. 格式:`color-mix(in srgb, ${cssVar.xxx} alpha%, transparent)`
|
||||
|
||||
**示例:**
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
import { rgba } from 'polished';
|
||||
|
||||
export const useStyles = createStyles(({ css, token }) => ({
|
||||
root: css`
|
||||
background-color: ${rgba(token.colorBgLayout, 0.4)};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
root: css`
|
||||
background-color: color-mix(in srgb, ${cssVar.colorBgLayout} 40%, transparent);
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Header`: `rgba(cssVar.colorBgLayout, 0.4)` → `color-mix(...)`
|
||||
- `FormModal`: `rgba(cssVar.colorBgContainer, 0)` → `color-mix(...)`
|
||||
|
||||
### 场景 10: keyframes → css
|
||||
|
||||
**适用:** 使用 `keyframes` 创建动画
|
||||
|
||||
**步骤:**
|
||||
|
||||
1. 在 `createStaticStyles` 外部定义 `keyframes`
|
||||
2. 在样式内部使用
|
||||
|
||||
**示例:**
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
export const useStyles = createStyles(({ css, keyframes }) => {
|
||||
const spin = keyframes`
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
`;
|
||||
return {
|
||||
icon: css`
|
||||
animation: ${spin} 1s linear infinite;
|
||||
`,
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
import { keyframes } from 'antd-style';
|
||||
|
||||
const spin = keyframes`
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
`;
|
||||
|
||||
export const styles = createStaticStyles(({ css }) => ({
|
||||
icon: css`
|
||||
animation: ${spin} 1s linear infinite;
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `Icon`: `keyframes` 动画
|
||||
- `Skeleton`: `keyframes` shimmer 动画
|
||||
|
||||
## ⚠️ 反模式:避免使用 createVariants (isDarkMode)
|
||||
|
||||
**不推荐的做法:**
|
||||
|
||||
```typescript
|
||||
// ❌ 不推荐:在组件中动态创建 variants
|
||||
export const createVariants = (isDarkMode: boolean) =>
|
||||
cva(styles.root, {
|
||||
variants: {
|
||||
variant: {
|
||||
filled: isDarkMode ? styles.filledDark : styles.filledLight,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 组件中
|
||||
const variants = useMemo(() => createVariants(isDarkMode), [isDarkMode]);
|
||||
```
|
||||
|
||||
**推荐的做法:**
|
||||
|
||||
将 `isDarkMode` 作为 `cva` 的 variant prop(见场景 4 方式 B),这样:
|
||||
|
||||
- ✅ 不需要 `useMemo` 动态创建
|
||||
- ✅ 更符合 `cva` 的设计理念
|
||||
- ✅ 代码更简洁,性能更好
|
||||
- ✅ 类型安全,IDE 自动补全
|
||||
|
||||
```typescript
|
||||
// ✅ 推荐:将 isDarkMode 作为 variant prop
|
||||
export const variants = cva(styles.root, {
|
||||
variants: {
|
||||
isDarkMode: {
|
||||
false: null,
|
||||
true: null,
|
||||
},
|
||||
variant: {
|
||||
filled: null,
|
||||
},
|
||||
},
|
||||
compoundVariants: [
|
||||
{
|
||||
class: styles.filledDark,
|
||||
isDarkMode: true,
|
||||
variant: 'filled',
|
||||
},
|
||||
{
|
||||
class: styles.filledLight,
|
||||
isDarkMode: false,
|
||||
variant: 'filled',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 组件中
|
||||
const { isDarkMode } = useThemeMode();
|
||||
const className = variants({ isDarkMode, variant: 'filled' });
|
||||
```
|
||||
|
||||
## ⚠️ 无法优化的场景
|
||||
|
||||
### 1. JS 计算函数
|
||||
|
||||
**无法优化:**
|
||||
|
||||
- `chroma()` - 颜色计算库
|
||||
- `readableColor()` - 需要运行时计算(但可以用 token 替代)
|
||||
- `mix()` - 颜色混合计算
|
||||
- `calc()` 中使用 token 数值进行复杂计算
|
||||
|
||||
**示例:**
|
||||
|
||||
```typescript
|
||||
// ❌ 无法优化
|
||||
const scale = chroma.bezier([token.colorText, backgroundColor]).scale().colors(6);
|
||||
```
|
||||
|
||||
### 2. 复杂的动态 Props
|
||||
|
||||
**无法优化:**
|
||||
|
||||
- 需要复杂计算的 props
|
||||
- 对象 / 数组类型的 props
|
||||
- 函数类型的 props
|
||||
|
||||
### 3. useTheme Hook
|
||||
|
||||
**无法优化:**
|
||||
|
||||
- 直接使用 `useTheme()` hook 获取运行时值
|
||||
- 例如:`awesome/Giscus/style.ts` 使用 `useTheme()` 获取主题值
|
||||
|
||||
## 📋 迁移检查清单
|
||||
|
||||
### 样式文件检查
|
||||
|
||||
- [ ] `createStyles` → `createStaticStyles`
|
||||
- [ ] `token.xxx` → `cssVar.xxx`
|
||||
- [ ] 移除 `px` 后缀(`cssVar` 已包含单位)
|
||||
- [ ] `responsive.mobile` → `responsive.sm`(如果使用)
|
||||
- [ ] `stylish.xxx` → `lobeStaticStylish.xxx`(如果使用)
|
||||
- [ ] `rgba()` → `color-mix()`(如果使用)
|
||||
- [ ] `readableColor()` → token 替换(如果使用)
|
||||
- [ ] `prefixCls` 参数 → 硬编码 `const prefixCls = 'ant'`(如果使用)
|
||||
- [ ] `isDarkMode` → 静态样式拆分(如果使用)
|
||||
- [ ] 动态 props → CSS 变量(如果使用)
|
||||
|
||||
### 组件文件检查
|
||||
|
||||
- [ ] `useStyles()` → `import { styles } from './style'`
|
||||
- [ ] `import { cx } from 'antd-style'`(如果需要)
|
||||
- [ ] `import { useTheme } from 'antd-style'`(如果需要 `theme.isDarkMode`)
|
||||
- [ ] 动态 props → CSS 变量设置(如果使用)
|
||||
- [ ] `isDarkMode` 条件 → `theme.isDarkMode` 判断(如果使用)
|
||||
|
||||
## 🎯 优化优先级
|
||||
|
||||
### 高优先级(简单优化)
|
||||
|
||||
1. ✅ 纯静态样式(无动态 props)
|
||||
2. ✅ `isDarkMode` 拆分
|
||||
3. ✅ `responsive.mobile` → `responsive.sm`
|
||||
4. ✅ `stylish` → `lobeStaticStylish`
|
||||
5. ✅ `readableColor()` → token 替换
|
||||
|
||||
### 中优先级(需要转换)
|
||||
|
||||
6. ✅ 简单的动态 props → CSS 变量(1-2 个)
|
||||
7. ✅ 布尔值 props → 静态样式拆分(2-3 个)
|
||||
|
||||
### 低优先级(复杂优化)
|
||||
|
||||
8. ⚠️ 多个动态 props → CSS 变量(3+ 个)
|
||||
9. ⚠️ 复杂的条件逻辑拆分
|
||||
|
||||
## 📚 参考示例
|
||||
|
||||
### 完整示例 1: 简单组件
|
||||
|
||||
**样式文件:**
|
||||
|
||||
```typescript
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
root: css`
|
||||
padding: ${cssVar.padding};
|
||||
color: ${cssVar.colorText};
|
||||
border-radius: ${cssVar.borderRadius};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**组件文件:**
|
||||
|
||||
```typescript
|
||||
import { cx } from 'antd-style';
|
||||
import { styles } from './style';
|
||||
|
||||
const Component = ({ className }) => {
|
||||
return <div className={cx(styles.root, className)} />;
|
||||
};
|
||||
```
|
||||
|
||||
### 完整示例 2: 带动态 Props
|
||||
|
||||
**样式文件:**
|
||||
|
||||
```typescript
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
root: css`
|
||||
width: var(--component-size, 24px);
|
||||
height: var(--component-size, 24px);
|
||||
background: ${cssVar.colorBgContainer};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**组件文件:**
|
||||
|
||||
```typescript
|
||||
import { cx } from 'antd-style';
|
||||
import { useMemo } from 'react';
|
||||
import { styles } from './style';
|
||||
|
||||
const Component = ({ size = 24, className, style, ...rest }) => {
|
||||
const cssVariables = useMemo<Record<string, string>>(
|
||||
() => ({
|
||||
'--component-size': `${size}px`,
|
||||
}),
|
||||
[size],
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(styles.root, className)}
|
||||
style={{
|
||||
...cssVariables,
|
||||
...style,
|
||||
}}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### 完整示例 3: 带 isDarkMode
|
||||
|
||||
**样式文件:**
|
||||
|
||||
```typescript
|
||||
import { createStaticStyles } from 'antd-style';
|
||||
|
||||
export const styles = createStaticStyles(({ css, cssVar }) => ({
|
||||
rootDark: css`
|
||||
background: ${cssVar.colorFillTertiary};
|
||||
color: ${cssVar.colorTextLightSolid};
|
||||
`,
|
||||
rootLight: css`
|
||||
background: ${cssVar.colorFillQuaternary};
|
||||
color: ${cssVar.colorText};
|
||||
`,
|
||||
}));
|
||||
```
|
||||
|
||||
**组件文件:**
|
||||
|
||||
```typescript
|
||||
import { cx, useTheme } from 'antd-style';
|
||||
import { styles } from './style';
|
||||
|
||||
const Component = ({ className }) => {
|
||||
const { theme } = useTheme();
|
||||
return (
|
||||
<div
|
||||
className={cx(
|
||||
theme.isDarkMode ? styles.rootDark : styles.rootLight,
|
||||
className
|
||||
)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## 🔍 验证步骤
|
||||
|
||||
1. **类型检查:** `pnpm run type-check`
|
||||
2. **运行时测试:** 确保视觉效果一致
|
||||
3. **性能验证:** 检查样式计算是否在模块加载时完成
|
||||
|
||||
## 📊 优化效果
|
||||
|
||||
- ✅ **零运行时开销**:样式在模块加载时计算一次
|
||||
- ✅ **减少重新渲染**:组件不再依赖样式 hook
|
||||
- ✅ **更好的性能**:减少每次渲染的计算开销
|
||||
- ✅ **代码更简洁**:直接导入样式对象
|
||||
|
||||
## 🔧 场景 11: useTheme () → useThemeMode () /cssVar
|
||||
|
||||
**适用:** 组件中只使用 `theme.isDarkMode` 或其他 token 值
|
||||
|
||||
**规则:**
|
||||
|
||||
- 如果只使用 `theme.isDarkMode`,使用 `const { isDarkMode } = useThemeMode()` 替代
|
||||
- 如果使用其他 token(如 `theme.colorText`, `theme.borderRadius` 等),使用 `cssVar` 替代
|
||||
- `useThemeMode()` 比 `useTheme()` 更轻量,只返回 `isDarkMode` 值
|
||||
|
||||
**示例:**
|
||||
|
||||
**之前:**
|
||||
|
||||
```typescript
|
||||
import { useTheme } from 'antd-style';
|
||||
|
||||
const Component = () => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<div className={theme.isDarkMode ? styles.dark : styles.light}>
|
||||
{theme.colorText}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
**之后:**
|
||||
|
||||
```typescript
|
||||
import { cssVar, useThemeMode } from 'antd-style';
|
||||
|
||||
const Component = () => {
|
||||
const { isDarkMode } = useThemeMode();
|
||||
return (
|
||||
<div className={isDarkMode ? styles.dark : styles.light}>
|
||||
{cssVar.colorText}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
**已优化示例:**
|
||||
|
||||
- `AuroraBackground`, `Select`, `Input`, `Button`, `DatePicker`, `AutoComplete`, `InputNumber`, `InputPassword`, `InputOPT`, `TextArea`, `SpotlightCardItem`, `Spotlight`, `HotkeyInput` - 只使用 `isDarkMode` → `useThemeMode()`
|
||||
- `Image`, `GradientButton`, `Empty`, `FileTypeIcon`, `FormSubmitFooter`, `CodeEditor`, `LobeChat`, `Drawer`, `Modal`, `Avatar`, `AvatarGroup`, `SkeletonAvatar`, `SkeletonButton`, `SkeletonTags`, `Callout`, `LobeHub`, `GridBackground`, `FolderIcon`, `FileIcon`, `TokenTag`, `ChatSendButton`, `AvatarUploader` - 使用 token → `cssVar`
|
||||
|
||||
**无法优化的文件(需要保留 `useTheme()`):**
|
||||
|
||||
- `useMermaid`, `useStreamMermaid`, `useHighlight`, `useStreamHighlight` - 需要完整的 theme 对象传给第三方库
|
||||
- `Alert`, `Tag`, `Menu`, `EmojiPicker` - 需要实际颜色值传给颜色计算函数
|
||||
- `SkeletonTitle`, `SkeletonTags` - 需要数值进行数学运算
|
||||
- `GridShowcase`, `GridBackground/demos` - 需要实际颜色值传给 `rgba()` 函数
|
||||
- `CustomFonts` - 需要实际字符串值进行字符串拼接
|
||||
- `Giscus/style.ts` - 需要实际颜色值传给 `readableColor()` 和 `rgba()` 函数(其他 token 已优化为 `cssVar`)
|
||||
|
||||
**注意事项:**
|
||||
|
||||
- `useThemeMode()` 只返回 `{ isDarkMode }`,不返回完整的 theme 对象
|
||||
- `cssVar` 的值是字符串(如 `"14px"`, `"#ffffff"`),可以直接在 JSX 中使用
|
||||
- 如果 token 需要用于数值计算(如 `Math.round(theme.fontSize * 1.5)`),需要保留 `useTheme()`
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
`createStaticStyles` 迁移是一个渐进式的优化过程。对于简单的静态样式,可以直接转换;对于复杂的动态场景,需要根据具体情况选择合适的优化策略。关键是要理解每种场景的处理方式,并灵活运用 CSS 变量、静态样式拆分等技术。
|
||||
|
||||
### useTheme () 优化总结
|
||||
|
||||
- ✅ **使用 `useThemeMode()`**:当组件只使用 `theme.isDarkMode` 时
|
||||
- ✅ **使用 `cssVar`**:当组件使用其他 token 值(颜色、尺寸等)时
|
||||
- ⚠️ **保留 `useTheme()`**:当 token 需要用于数值计算或传给第三方库时
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
const config = require('@lobehub/lint').eslint;
|
||||
|
||||
config.root = true;
|
||||
config.extends.push('plugin:@next/next/recommended-legacy');
|
||||
config.extends.push('plugin:@next/next/recommended');
|
||||
|
||||
config.rules['unicorn/no-negated-condition'] = 0;
|
||||
config.rules['unicorn/prefer-type-error'] = 0;
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
name: Bundle Analyzer
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
actions: write
|
||||
|
||||
env:
|
||||
NODE_VERSION: 24.11.1
|
||||
BUN_VERSION: 1.2.23
|
||||
|
||||
jobs:
|
||||
bundle-analyzer:
|
||||
name: Analyze Bundle Size
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: ${{ env.BUN_VERSION }}
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm i
|
||||
|
||||
- name: Ensure lockfile exists
|
||||
run: |
|
||||
# Temporarily override .npmrc lockfile=false setting
|
||||
# to generate pnpm-lock.yaml for reproducible builds
|
||||
if [ ! -f "pnpm-lock.yaml" ]; then
|
||||
echo "Generating pnpm-lock.yaml..."
|
||||
# Create temporary .npmrc override
|
||||
mv .npmrc .npmrc.bak
|
||||
echo "lockfile=true" > .npmrc
|
||||
cat .npmrc.bak >> .npmrc
|
||||
pnpm i
|
||||
mv .npmrc.bak .npmrc
|
||||
fi
|
||||
|
||||
- name: Generate build secrets
|
||||
id: generate-secret
|
||||
run: echo "secret=$(openssl rand -base64 32)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build with bundle analyzer
|
||||
run: bun run build:analyze || true
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
KEY_VAULTS_SECRET: ${{ secrets.KEY_VAULTS_SECRET || steps.generate-secret.outputs.secret }}
|
||||
|
||||
- name: Prepare analyzer reports
|
||||
run: |
|
||||
mkdir -p bundle-report
|
||||
# Copy analyzer HTML reports if they exist
|
||||
if [ -d ".next/analyze" ]; then
|
||||
cp -r .next/analyze/* bundle-report/ || true
|
||||
fi
|
||||
# Also check if reports are in .vercel/output
|
||||
if [ -d ".vercel/output/.next/analyze" ]; then
|
||||
cp -r .vercel/output/.next/analyze/* bundle-report/ || true
|
||||
fi
|
||||
# Include pnpm lockfile for reproducible builds
|
||||
if [ -f "pnpm-lock.yaml" ]; then
|
||||
cp pnpm-lock.yaml bundle-report/pnpm-lock.yaml
|
||||
echo "Copied pnpm-lock.yaml to bundle-report"
|
||||
else
|
||||
echo "Warning: pnpm-lock.yaml not found"
|
||||
fi
|
||||
# Create a summary with build metadata
|
||||
echo "# Bundle Analysis Report" > bundle-report/README.md
|
||||
echo "" >> bundle-report/README.md
|
||||
echo "**Build Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> bundle-report/README.md
|
||||
echo "**Commit:** ${{ github.sha }}" >> bundle-report/README.md
|
||||
echo "**Branch:** ${{ github.ref_name }}" >> bundle-report/README.md
|
||||
echo "" >> bundle-report/README.md
|
||||
echo "## How to view" >> bundle-report/README.md
|
||||
echo "" >> bundle-report/README.md
|
||||
echo "1. Download the \`bundle-report\` artifact from this workflow run" >> bundle-report/README.md
|
||||
echo "2. Extract the archive" >> bundle-report/README.md
|
||||
echo "3. Open \`client.html\` and \`server.html\` in your browser" >> bundle-report/README.md
|
||||
echo "" >> bundle-report/README.md
|
||||
echo "## Files in this report" >> bundle-report/README.md
|
||||
echo "" >> bundle-report/README.md
|
||||
echo "- \`client.html\` - Client-side bundle analysis" >> bundle-report/README.md
|
||||
echo "- \`server.html\` - Server-side bundle analysis" >> bundle-report/README.md
|
||||
echo "- \`pnpm-lock.yaml\` - pnpm lockfile (for reproducible builds)" >> bundle-report/README.md
|
||||
|
||||
- name: Upload bundle analyzer reports
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: bundle-report-${{ github.run_id }}
|
||||
path: bundle-report/
|
||||
retention-days: 30
|
||||
if-no-files-found: warn
|
||||
|
||||
- name: Create summary comment
|
||||
run: |
|
||||
echo "## Bundle Analysis Complete :chart_with_upwards_trend:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Commit:** \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Artifact:** \`bundle-report-${{ github.run_id }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "Download the artifact to view the detailed bundle analysis reports." >> $GITHUB_STEP_SUMMARY
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
name: Build desktop Next bundle
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
UPDATE_CHANNEL: nightly
|
||||
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_PROJECT_ID || 'dummy-desktop-project' }}
|
||||
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_BASE_URL || 'https://analytics.example.com' }}
|
||||
|
||||
@@ -10,19 +10,6 @@ concurrency:
|
||||
group: e2e-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
|
||||
DATABASE_DRIVER: node
|
||||
KEY_VAULTS_SECRET: LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=
|
||||
BETTER_AUTH_SECRET: e2e-test-secret-key-for-better-auth-32chars!
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH: '1'
|
||||
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION: '0'
|
||||
# Mock S3 env vars to prevent initialization errors
|
||||
S3_ACCESS_KEY_ID: e2e-mock-access-key
|
||||
S3_SECRET_ACCESS_KEY: e2e-mock-secret-key
|
||||
S3_BUCKET: e2e-mock-bucket
|
||||
S3_ENDPOINT: https://e2e-mock-s3.localhost
|
||||
|
||||
jobs:
|
||||
e2e:
|
||||
name: Test Web App
|
||||
@@ -38,7 +25,7 @@ jobs:
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
timeout-minutes: 30
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
@@ -54,15 +41,12 @@ jobs:
|
||||
- name: Install Playwright browsers (with system deps)
|
||||
run: bunx playwright install --with-deps chromium
|
||||
|
||||
- name: Run database migrations
|
||||
run: bun run db:migrate
|
||||
|
||||
- name: Build application
|
||||
run: bun run build
|
||||
env:
|
||||
SKIP_LINT: '1'
|
||||
|
||||
- name: Run E2E tests
|
||||
env:
|
||||
PORT: 3010
|
||||
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
|
||||
DATABASE_DRIVER: node
|
||||
KEY_VAULTS_SECRET: LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=
|
||||
run: bun run e2e
|
||||
|
||||
- name: Upload Cucumber HTML report (on failure)
|
||||
|
||||
@@ -62,9 +62,13 @@ jobs:
|
||||
|
||||
- name: Install deps
|
||||
run: bun i
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
|
||||
- name: Lint
|
||||
run: bun run lint
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
|
||||
version:
|
||||
name: Determine version
|
||||
|
||||
@@ -39,12 +39,12 @@ jobs:
|
||||
- name: Install deps
|
||||
run: bun i
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
|
||||
- name: Lint
|
||||
run: bun run lint
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
|
||||
version:
|
||||
name: Determine version
|
||||
@@ -80,7 +80,7 @@ jobs:
|
||||
echo "📦 Release Version: ${version} (based on base version ${base_version})"
|
||||
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
|
||||
# 输出版本信息总结,方便在 GitHub Actions 界面查看
|
||||
- name: Version Summary
|
||||
|
||||
@@ -143,7 +143,7 @@ jobs:
|
||||
run: pnpm install
|
||||
working-directory: apps/desktop
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
|
||||
- name: Typecheck Desktop
|
||||
run: pnpm type-check
|
||||
@@ -173,7 +173,6 @@ jobs:
|
||||
options: >-
|
||||
--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
||||
|
||||
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
name: Verify Desktop Patch
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- next
|
||||
- dev
|
||||
paths:
|
||||
- 'scripts/electronWorkflow/**'
|
||||
- 'src/libs/next/config/**'
|
||||
- 'src/app/**'
|
||||
- 'src/layout/**'
|
||||
- 'src/components/mdx/**'
|
||||
- 'src/features/DevPanel/**'
|
||||
- 'src/server/translation.ts'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'scripts/electronWorkflow/**'
|
||||
- 'src/libs/next/config/**'
|
||||
- 'src/app/**'
|
||||
- 'src/layout/**'
|
||||
- 'src/components/mdx/**'
|
||||
- 'src/features/DevPanel/**'
|
||||
- 'src/server/translation.ts'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
NODE_VERSION: 24.11.1
|
||||
BUN_VERSION: 1.2.23
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
name: Desktop patch smoke test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node & Bun
|
||||
uses: ./.github/actions/setup-node-bun
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
bun-version: ${{ env.BUN_VERSION }}
|
||||
|
||||
- name: Install deps
|
||||
run: bun i
|
||||
|
||||
- name: Verify desktop patch
|
||||
run: bun scripts/electronWorkflow/modifiers/index.mts
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
const { defineConfig } = require('@lobehub/i18n-cli');
|
||||
|
||||
module.exports = defineConfig({
|
||||
entry: 'locales/en-US',
|
||||
entryLocale: 'en-US',
|
||||
entry: 'locales/zh-CN',
|
||||
entryLocale: 'zh-CN',
|
||||
output: 'locales',
|
||||
outputLocales: [
|
||||
'ar',
|
||||
'bg-BG',
|
||||
'zh-CN',
|
||||
'zh-TW',
|
||||
'en-US',
|
||||
'ru-RU',
|
||||
'ja-JP',
|
||||
'ko-KR',
|
||||
|
||||
Vendored
+6
-8
@@ -7,16 +7,14 @@
|
||||
"editor.formatOnSave": true,
|
||||
// don't show errors, but fix when save and git pre commit
|
||||
"eslint.rules.customizations": [
|
||||
// { "rule": "import/order", "severity": "off" },
|
||||
// { "rule": "prettier/prettier", "severity": "off" },
|
||||
// { "rule": "react/jsx-sort-props", "severity": "off" },
|
||||
// { "rule": "sort-keys-fix/sort-keys-fix", "severity": "off" },
|
||||
// { "rule": "simple-import-sort/exports", "severity": "off" },
|
||||
// { "rule": "typescript-sort-keys/interface", "severity": "off" }
|
||||
{ "rule": "import/order", "severity": "off" },
|
||||
{ "rule": "prettier/prettier", "severity": "off" },
|
||||
{ "rule": "react/jsx-sort-props", "severity": "off" },
|
||||
{ "rule": "sort-keys-fix/sort-keys-fix", "severity": "off" },
|
||||
{ "rule": "simple-import-sort/exports", "severity": "off" },
|
||||
{ "rule": "typescript-sort-keys/interface", "severity": "off" }
|
||||
],
|
||||
"eslint.validate": [
|
||||
// vscode eslint not 插件兼容性有问题
|
||||
// "json",
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
|
||||
-550
@@ -2,556 +2,6 @@
|
||||
|
||||
# Changelog
|
||||
|
||||
## [Version 2.0.0-next.190](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.189...v2.0.0-next.190)
|
||||
|
||||
<sup>Released on **2026-01-02**</sup>
|
||||
|
||||
#### 💄 Styles
|
||||
|
||||
- **misc**: Update i18n.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Styles
|
||||
|
||||
- **misc**: Update i18n, closes [#11100](https://github.com/lobehub/lobe-chat/issues/11100) ([bb4571b](https://github.com/lobehub/lobe-chat/commit/bb4571b))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.189](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.188...v2.0.0-next.189)
|
||||
|
||||
<sup>Released on **2026-01-01**</sup>
|
||||
|
||||
#### ♻ Code Refactoring
|
||||
|
||||
- **misc**: Migrate to new DropdownMenuV2 and showContextMenu API.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Code refactoring
|
||||
|
||||
- **misc**: Migrate to new DropdownMenuV2 and showContextMenu API, closes [#11079](https://github.com/lobehub/lobe-chat/issues/11079) ([04cfc0e](https://github.com/lobehub/lobe-chat/commit/04cfc0e))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.188](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.187...v2.0.0-next.188)
|
||||
|
||||
<sup>Released on **2026-01-01**</sup>
|
||||
|
||||
#### 💄 Styles
|
||||
|
||||
- **misc**: Improve tools UI and fix Google schema compatibility.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Styles
|
||||
|
||||
- **misc**: Improve tools UI and fix Google schema compatibility, closes [#11096](https://github.com/lobehub/lobe-chat/issues/11096) ([70a9cff](https://github.com/lobehub/lobe-chat/commit/70a9cff))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.187](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.186...v2.0.0-next.187)
|
||||
|
||||
<sup>Released on **2026-01-01**</sup>
|
||||
|
||||
#### 💄 Styles
|
||||
|
||||
- **misc**: Add Gemini 3 Flash & Doubao Seed 1.8 models.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Styles
|
||||
|
||||
- **misc**: Add Gemini 3 Flash & Doubao Seed 1.8 models, closes [#10832](https://github.com/lobehub/lobe-chat/issues/10832) ([cb35935](https://github.com/lobehub/lobe-chat/commit/cb35935))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.186](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.185...v2.0.0-next.186)
|
||||
|
||||
<sup>Released on **2026-01-01**</sup>
|
||||
|
||||
#### ♻ Code Refactoring
|
||||
|
||||
- **misc**: Refactor oidc env to auth env.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Code refactoring
|
||||
|
||||
- **misc**: Refactor oidc env to auth env, closes [#11095](https://github.com/lobehub/lobe-chat/issues/11095) ([6e8d4ff](https://github.com/lobehub/lobe-chat/commit/6e8d4ff))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.185](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.184...v2.0.0-next.185)
|
||||
|
||||
<sup>Released on **2026-01-01**</sup>
|
||||
|
||||
#### 💄 Styles
|
||||
|
||||
- **misc**: Update i18n.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Styles
|
||||
|
||||
- **misc**: Update i18n, closes [#11085](https://github.com/lobehub/lobe-chat/issues/11085) ([0941a52](https://github.com/lobehub/lobe-chat/commit/0941a52))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.184](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.183...v2.0.0-next.184)
|
||||
|
||||
<sup>Released on **2026-01-01**</sup>
|
||||
|
||||
#### 💄 Styles
|
||||
|
||||
- **misc**: Improve loading and local-system render.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Styles
|
||||
|
||||
- **misc**: Improve loading and local-system render, closes [#11087](https://github.com/lobehub/lobe-chat/issues/11087) ([44630bc](https://github.com/lobehub/lobe-chat/commit/44630bc))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.183](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.182...v2.0.0-next.183)
|
||||
|
||||
<sup>Released on **2025-12-31**</sup>
|
||||
|
||||
#### 🐛 Bug Fixes
|
||||
|
||||
- **store**: Clear new key data when switchTopic to new state.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### What's fixed
|
||||
|
||||
- **store**: Clear new key data when switchTopic to new state, closes [#11078](https://github.com/lobehub/lobe-chat/issues/11078) ([180ea14](https://github.com/lobehub/lobe-chat/commit/180ea14))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.182](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.181...v2.0.0-next.182)
|
||||
|
||||
<sup>Released on **2025-12-31**</sup>
|
||||
|
||||
#### ✨ Features
|
||||
|
||||
- **misc**: Brand new 2.0 ui for next.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### What's improved
|
||||
|
||||
- **misc**: Brand new 2.0 ui for next ([e5d6d3d](https://github.com/lobehub/lobe-chat/commit/e5d6d3d))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.181](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.180...v2.0.0-next.181)
|
||||
|
||||
<sup>Released on **2025-12-31**</sup>
|
||||
|
||||
#### ♻ Code Refactoring
|
||||
|
||||
- **userMemories**: Added `benchmark_locomo` as source unify use the of source type.
|
||||
- **misc**: Add builtin tools, clean code, clean desktop relative code, clean page editor, flatten i18n keys and extract hardcoded strings in desktop, i18n formatting optimization, improve modal handling with createRawModal, move code-interpreter to single packages, refactor builtin-tool implement, refactor hooks, refactor implement, refactor implement for desktop, refactor local-system, refactor service, refactor static style, refactor to use better underline style, refactor to use better underline style, refactor tool prompt injection, refactor ui and layout, refactor with editor runtime, refactor with electron, refactor with es-toolkit, remove desktop-specific upload logic, rename browser identifier from 'chat' to 'app', tools ui, use /f/:fid as file mode, use supervisor role for agent group supervisor.
|
||||
|
||||
#### ✨ Features
|
||||
|
||||
- **auth**: Add confirm password field and integrate business signup logic, add useBusinessSignup hook for business signup functionality, enhance BetterAuthSignUpForm with businessElement and update useSignUp hook for improved signup process, integrate business sign-in features and update social sign-in logic, update useBusinessSignin to include getAdditionalData function for enhanced sign-in process.
|
||||
- **desktop**: MacOS About menu should navigate to Settings About tab.
|
||||
- **layout**: Integrate BusinessGlobalProvider for conditional rendering based on business features.
|
||||
- **memory-user-memory**: Added LoCoMo dataset loader & converter & exporter, support to extract memories from LoCoMo dataset, support to load in memory, and extract from in-memory memory sources.
|
||||
- **model**: Improve model list UI and add disabled models management.
|
||||
- **referral**: Add backfill referral code i18n keys.
|
||||
- **userMemories**: Apply userMemories.enable from settings for injecting, use capturedAt for time of memory entries, use honorific title for identity memory.
|
||||
- **misc**: Add a white waitlist in edge config env, add always show tools render in createPlan & createDoc tools, add batch tasks ui, add Bundle Analyzer workflow for detailed bundle size analysis, add business features support with new components and hooks, add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add db and schema feature, add home page create group builder button, Add i18n UI locales and improve tool types, add like action in community detail, add memory implement, add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add the market auth auto generate way, Add turbopack configuration support to CustomNextConfig, add user memory, agent builder, agent builder, agent builder and group builder, app ui page, brand new 2.0 ui for next, buildin some tools should save into docs, code-interpreter tool, code-interpreter tool, code-interpreter tool, desktop feature, enhance desktop onboarding with sign out and localization, enhance macOS desktop permissions and onboarding, enhance onboarding process by removing mode selection step and adding export functionality in advanced settings, file search feature, gtd create plan support streaming render, implement agent builder, implement builtin agents packages, implement memories package, implement Redis caching for presigned URLs in file proxy service, implement server data feature, include Subscription settings group in the Accordion component, Integrate bcryptjs for password verification in BetterAuth, integrate BrandingProviderCard and update Provider components for branding support, onboarding ui, page and knowledge base, rebranding total UI of app, refactor authentication handler to support dynamic loading of better-auth and next-auth, refactor desktop implement with brand new 2.0, rename codeinterpreter into lobe sandbox, server implement, support CMD K, support exec async sub agent task, support export and import topic JSON, support files upload in chat input, support notebook tool, support swr local cache, topic message swr cache, translate AI model descriptions to English, update agent builder ui, update create group chat use builder, update gtd tools( use editor & update metadata ), update user memory embedding model selection based on business features, user memory, user memory, user onboarding, when use usesend to create agent/group, the model should override by lobeAi, wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI.
|
||||
|
||||
#### 🐛 Bug Fixes
|
||||
|
||||
- **ci**: Skip backend routes in bundle analyzer build.
|
||||
- **desktop**: prevent window resize when onboarding, add safe top edge for message container.
|
||||
- **i18n**: Translate plugin.ts locale to English.
|
||||
- **image-generation**: Update chargeBeforeGenerate to return ChargeResult and include configForDatabase in parameters.
|
||||
- **memory-user-memory**: Should pre-process date & time.
|
||||
- **observability-otel**: Typo in package name.
|
||||
- **prebuild**: Correct syntax in partialBuildPages array.
|
||||
- **translation**: Add fallback for all English locale variants.
|
||||
- **userMemories**: 404/405 issue due to incorrectly used workflow name and mounted catch-all route, missing base memory as part of context, must assign workflow id, should use `context.invoke` for workflow instead of `context.run`, skip to handle WorkflowAbort, use date & time for building context, workflow id build issue.
|
||||
- **misc**: Agent profiles update, agent tools config set, editor placeholder, bump charts 3.0.4 to fix import es path, fix anthropic thinking budget, fix async task and improve tool style, fix default waitlist bug, fix delete agent group bug, Fix desktop test cases and refactor translations, Fix desktop test cases and refactor translations, fix gemini 3 model thinking issue, fix gemini 3 pro parallel tool use, fix gemini 3 thinking params, fix identity memory not working, fix supervisor flag, fix thread not working issue, fix when use branch topic,the branch index error problem, fixed the welcome card the create button not work, handle session invalidation on 401 error by logging out signed-in users, improve test infrastructure and mock configurations, locale resolve bug with ESM module loading, page agent editor, prevent redundant login redirect when already on auth pages, redis read json object, remove openapi pkg patch file, slove input editor on pause emit, slove swr mutate not work in Cache Provider, slove the group add member checkbox not work, slove the model select null problem, slove the mutate not work problem, slove when click agentbuilder should clean topic, slove when first call thread, not show ai chat message, support retry error message and fix continueGenerationMessage, update contextMenu in group tools message, update OFFICIAL_URL to app.lobehub.com, update PlanTag link paths for subscription settings, update test snapshots for model description changes, when use agentbuilder the topic id should use new & clear topic….
|
||||
|
||||
#### 💄 Styles
|
||||
|
||||
- **misc**: Improve ExecTask and task message UI, improve gtd tool inspector and todo list, improve page document tool inspector UI, improve RunCommand Inspector, rebranding chat ui, refactor UI in features, rerun i18n, setting style, support streaming and display ui for group mode, support tool streaming and title custom render, update i18n, Update i18n microcopy, update ui.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### Code refactoring
|
||||
|
||||
- **userMemories**: Added `benchmark_locomo` as source unify use the of source type, closes [#10922](https://github.com/lobehub/lobe-chat/issues/10922) ([03342a7](https://github.com/lobehub/lobe-chat/commit/03342a7))
|
||||
- **misc**: Add builtin tools ([26e73cc](https://github.com/lobehub/lobe-chat/commit/26e73cc))
|
||||
- **misc**: Clean code ([4ddb491](https://github.com/lobehub/lobe-chat/commit/4ddb491))
|
||||
- **misc**: Clean desktop relative code ([ffd7d23](https://github.com/lobehub/lobe-chat/commit/ffd7d23))
|
||||
- **misc**: Clean page editor, closes [#10966](https://github.com/lobehub/lobe-chat/issues/10966) ([15410d1](https://github.com/lobehub/lobe-chat/commit/15410d1))
|
||||
- **misc**: Flatten i18n keys and extract hardcoded strings in desktop, closes [#10939](https://github.com/lobehub/lobe-chat/issues/10939) ([e5f3a58](https://github.com/lobehub/lobe-chat/commit/e5f3a58))
|
||||
- **misc**: I18n formatting optimization, closes [#10929](https://github.com/lobehub/lobe-chat/issues/10929) [#10933](https://github.com/lobehub/lobe-chat/issues/10933) ([d692a37](https://github.com/lobehub/lobe-chat/commit/d692a37))
|
||||
- **misc**: Improve modal handling with createRawModal, closes [#11071](https://github.com/lobehub/lobe-chat/issues/11071) ([f5314c5](https://github.com/lobehub/lobe-chat/commit/f5314c5))
|
||||
- **misc**: Move code-interpreter to single packages ([1fa4357](https://github.com/lobehub/lobe-chat/commit/1fa4357))
|
||||
- **misc**: Refactor builtin-tool implement ([9ede8e7](https://github.com/lobehub/lobe-chat/commit/9ede8e7))
|
||||
- **misc**: Refactor hooks ([e3fa62e](https://github.com/lobehub/lobe-chat/commit/e3fa62e))
|
||||
- **misc**: Refactor implement ([34d059f](https://github.com/lobehub/lobe-chat/commit/34d059f))
|
||||
- **misc**: Refactor implement for desktop ([27f101f](https://github.com/lobehub/lobe-chat/commit/27f101f))
|
||||
- **misc**: Refactor local-system ([a69221f](https://github.com/lobehub/lobe-chat/commit/a69221f))
|
||||
- **misc**: Refactor service ([91bbbf5](https://github.com/lobehub/lobe-chat/commit/91bbbf5))
|
||||
- **misc**: Refactor static style, closes [#11010](https://github.com/lobehub/lobe-chat/issues/11010) ([d865e27](https://github.com/lobehub/lobe-chat/commit/d865e27))
|
||||
- **misc**: Refactor to use better underline style ([784bb58](https://github.com/lobehub/lobe-chat/commit/784bb58))
|
||||
- **misc**: Refactor to use better underline style ([5e10ac8](https://github.com/lobehub/lobe-chat/commit/5e10ac8))
|
||||
- **misc**: Refactor tool prompt injection ([6099ac3](https://github.com/lobehub/lobe-chat/commit/6099ac3))
|
||||
- **misc**: Refactor ui and layout ([436d9e5](https://github.com/lobehub/lobe-chat/commit/436d9e5))
|
||||
- **misc**: Refactor with editor runtime ([be2b41c](https://github.com/lobehub/lobe-chat/commit/be2b41c))
|
||||
- **misc**: Refactor with electron ([849ee3d](https://github.com/lobehub/lobe-chat/commit/849ee3d))
|
||||
- **misc**: Refactor with es-toolkit ([1848d27](https://github.com/lobehub/lobe-chat/commit/1848d27))
|
||||
- **misc**: Remove desktop-specific upload logic, closes [#11070](https://github.com/lobehub/lobe-chat/issues/11070) ([475065e](https://github.com/lobehub/lobe-chat/commit/475065e))
|
||||
- **misc**: Rename browser identifier from 'chat' to 'app', closes [#10940](https://github.com/lobehub/lobe-chat/issues/10940) ([dc870c7](https://github.com/lobehub/lobe-chat/commit/dc870c7))
|
||||
- **misc**: Tools ui ([6bf4546](https://github.com/lobehub/lobe-chat/commit/6bf4546))
|
||||
- **misc**: Use /f/:fid as file mode ([3b01174](https://github.com/lobehub/lobe-chat/commit/3b01174))
|
||||
- **misc**: Use supervisor role for agent group supervisor ([0ca823f](https://github.com/lobehub/lobe-chat/commit/0ca823f))
|
||||
|
||||
#### What's improved
|
||||
|
||||
- **auth**: Add confirm password field and integrate business signup logic ([2ccd5c7](https://github.com/lobehub/lobe-chat/commit/2ccd5c7))
|
||||
- **auth**: Add useBusinessSignup hook for business signup functionality ([3efb6cc](https://github.com/lobehub/lobe-chat/commit/3efb6cc))
|
||||
- **auth**: Enhance BetterAuthSignUpForm with businessElement and update useSignUp hook for improved signup process ([991d8c1](https://github.com/lobehub/lobe-chat/commit/991d8c1))
|
||||
- **auth**: Integrate business sign-in features and update social sign-in logic ([6dc7916](https://github.com/lobehub/lobe-chat/commit/6dc7916))
|
||||
- **auth**: Update useBusinessSignin to include getAdditionalData function for enhanced sign-in process ([c8e3bc9](https://github.com/lobehub/lobe-chat/commit/c8e3bc9))
|
||||
- **desktop**: MacOS About menu should navigate to Settings About tab, closes [#10942](https://github.com/lobehub/lobe-chat/issues/10942) ([1a4f456](https://github.com/lobehub/lobe-chat/commit/1a4f456))
|
||||
- **layout**: Integrate BusinessGlobalProvider for conditional rendering based on business features ([52c7a49](https://github.com/lobehub/lobe-chat/commit/52c7a49))
|
||||
- **memory-user-memory**: Added LoCoMo dataset loader & converter & exporter, closes [#10923](https://github.com/lobehub/lobe-chat/issues/10923) ([a5dd785](https://github.com/lobehub/lobe-chat/commit/a5dd785))
|
||||
- **memory-user-memory**: Support to extract memories from LoCoMo dataset, closes [#10925](https://github.com/lobehub/lobe-chat/issues/10925) ([c7c7d6f](https://github.com/lobehub/lobe-chat/commit/c7c7d6f))
|
||||
- **memory-user-memory**: Support to load in memory, and extract from in-memory memory sources, closes [#10924](https://github.com/lobehub/lobe-chat/issues/10924) ([9ac3ce7](https://github.com/lobehub/lobe-chat/commit/9ac3ce7))
|
||||
- **model**: Improve model list UI and add disabled models management, closes [#11036](https://github.com/lobehub/lobe-chat/issues/11036) ([4faa65c](https://github.com/lobehub/lobe-chat/commit/4faa65c))
|
||||
- **referral**: Add backfill referral code i18n keys ([bbf62ce](https://github.com/lobehub/lobe-chat/commit/bbf62ce))
|
||||
- **userMemories**: Apply userMemories.enable from settings for injecting, closes [#11038](https://github.com/lobehub/lobe-chat/issues/11038) ([1cc0e8c](https://github.com/lobehub/lobe-chat/commit/1cc0e8c))
|
||||
- **userMemories**: Use capturedAt for time of memory entries, closes [#11037](https://github.com/lobehub/lobe-chat/issues/11037) ([5615d20](https://github.com/lobehub/lobe-chat/commit/5615d20))
|
||||
- **userMemories**: Use honorific title for identity memory, closes [#11039](https://github.com/lobehub/lobe-chat/issues/11039) ([ab61c69](https://github.com/lobehub/lobe-chat/commit/ab61c69))
|
||||
- **misc**: Add a white waitlist in edge config env, closes [#11009](https://github.com/lobehub/lobe-chat/issues/11009) ([88f22f4](https://github.com/lobehub/lobe-chat/commit/88f22f4))
|
||||
- **misc**: Add always show tools render in createPlan & createDoc tools, closes [#10937](https://github.com/lobehub/lobe-chat/issues/10937) ([c224951](https://github.com/lobehub/lobe-chat/commit/c224951))
|
||||
- **misc**: Add batch tasks ui ([80587ae](https://github.com/lobehub/lobe-chat/commit/80587ae))
|
||||
- **misc**: Add Bundle Analyzer workflow for detailed bundle size analysis ([596e489](https://github.com/lobehub/lobe-chat/commit/596e489))
|
||||
- **misc**: Add business features support with new components and hooks ([1dccc04](https://github.com/lobehub/lobe-chat/commit/1dccc04))
|
||||
- **misc**: Add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs ([35c6ad9](https://github.com/lobehub/lobe-chat/commit/35c6ad9))
|
||||
- **misc**: Add db and schema feature ([9e47c33](https://github.com/lobehub/lobe-chat/commit/9e47c33))
|
||||
- **misc**: Add home page create group builder button, closes [#10904](https://github.com/lobehub/lobe-chat/issues/10904) ([3183189](https://github.com/lobehub/lobe-chat/commit/3183189))
|
||||
- **misc**: Add i18n UI locales and improve tool types, closes [#10964](https://github.com/lobehub/lobe-chat/issues/10964) ([0e89ce5](https://github.com/lobehub/lobe-chat/commit/0e89ce5))
|
||||
- **misc**: Add like action in community detail, closes [#10971](https://github.com/lobehub/lobe-chat/issues/10971) ([c11d802](https://github.com/lobehub/lobe-chat/commit/c11d802))
|
||||
- **misc**: Add memory implement ([fdae83c](https://github.com/lobehub/lobe-chat/commit/fdae83c))
|
||||
- **misc**: Add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs ([2ddc876](https://github.com/lobehub/lobe-chat/commit/2ddc876))
|
||||
- **misc**: Add the market auth auto generate way, closes [#10993](https://github.com/lobehub/lobe-chat/issues/10993) ([849ac73](https://github.com/lobehub/lobe-chat/commit/849ac73))
|
||||
- **misc**: Add turbopack configuration support to CustomNextConfig ([2e7076a](https://github.com/lobehub/lobe-chat/commit/2e7076a))
|
||||
- **misc**: Add user memory ([c305889](https://github.com/lobehub/lobe-chat/commit/c305889))
|
||||
- **misc**: Agent builder ([ede0ed6](https://github.com/lobehub/lobe-chat/commit/ede0ed6))
|
||||
- **misc**: Agent builder ([e3c9454](https://github.com/lobehub/lobe-chat/commit/e3c9454))
|
||||
- **misc**: Agent builder and group builder ([d735e2c](https://github.com/lobehub/lobe-chat/commit/d735e2c))
|
||||
- **misc**: App ui page ([78d07c0](https://github.com/lobehub/lobe-chat/commit/78d07c0))
|
||||
- **misc**: Brand new 2.0 ui for next ([f7d724f](https://github.com/lobehub/lobe-chat/commit/f7d724f))
|
||||
- **misc**: Buildin some tools should save into docs, closes [#10935](https://github.com/lobehub/lobe-chat/issues/10935) ([be4c17d](https://github.com/lobehub/lobe-chat/commit/be4c17d))
|
||||
- **misc**: Code-interpreter tool ([1940914](https://github.com/lobehub/lobe-chat/commit/1940914))
|
||||
- **misc**: Code-interpreter tool ([c931909](https://github.com/lobehub/lobe-chat/commit/c931909))
|
||||
- **misc**: Code-interpreter tool ([baa29c8](https://github.com/lobehub/lobe-chat/commit/baa29c8))
|
||||
- **misc**: Desktop feature ([ac93637](https://github.com/lobehub/lobe-chat/commit/ac93637))
|
||||
- **misc**: Enhance desktop onboarding with sign out and localization, closes [#11033](https://github.com/lobehub/lobe-chat/issues/11033) ([34a6312](https://github.com/lobehub/lobe-chat/commit/34a6312))
|
||||
- **misc**: Enhance macOS desktop permissions and onboarding, closes [#11016](https://github.com/lobehub/lobe-chat/issues/11016) ([9db8da8](https://github.com/lobehub/lobe-chat/commit/9db8da8))
|
||||
- **misc**: Enhance onboarding process by removing mode selection step and adding export functionality in advanced settings ([8b6c30e](https://github.com/lobehub/lobe-chat/commit/8b6c30e))
|
||||
- **misc**: File search feature ([9786d64](https://github.com/lobehub/lobe-chat/commit/9786d64))
|
||||
- **misc**: Gtd create plan support streaming render, closes [#11034](https://github.com/lobehub/lobe-chat/issues/11034) ([74d3555](https://github.com/lobehub/lobe-chat/commit/74d3555))
|
||||
- **misc**: Implement agent builder ([f638b97](https://github.com/lobehub/lobe-chat/commit/f638b97))
|
||||
- **misc**: Implement builtin agents packages ([2255a7c](https://github.com/lobehub/lobe-chat/commit/2255a7c))
|
||||
- **misc**: Implement memories package ([7f94ef1](https://github.com/lobehub/lobe-chat/commit/7f94ef1))
|
||||
- **misc**: Implement Redis caching for presigned URLs in file proxy service ([15722f1](https://github.com/lobehub/lobe-chat/commit/15722f1))
|
||||
- **misc**: Implement server data feature ([9c46c6e](https://github.com/lobehub/lobe-chat/commit/9c46c6e))
|
||||
- **misc**: Include Subscription settings group in the Accordion component ([8f2d57d](https://github.com/lobehub/lobe-chat/commit/8f2d57d))
|
||||
- **misc**: Integrate bcryptjs for password verification in BetterAuth ([180ebfd](https://github.com/lobehub/lobe-chat/commit/180ebfd))
|
||||
- **misc**: Integrate BrandingProviderCard and update Provider components for branding support ([6b5ce79](https://github.com/lobehub/lobe-chat/commit/6b5ce79))
|
||||
- **misc**: Onboarding ui ([81d33a6](https://github.com/lobehub/lobe-chat/commit/81d33a6))
|
||||
- **misc**: Page and knowledge base ([492d3cc](https://github.com/lobehub/lobe-chat/commit/492d3cc))
|
||||
- **misc**: Rebranding total UI of app ([13ca81b](https://github.com/lobehub/lobe-chat/commit/13ca81b))
|
||||
- **misc**: Refactor authentication handler to support dynamic loading of better-auth and next-auth ([d6419e4](https://github.com/lobehub/lobe-chat/commit/d6419e4))
|
||||
- **misc**: Refactor desktop implement with brand new 2.0 ([10e048c](https://github.com/lobehub/lobe-chat/commit/10e048c))
|
||||
- **misc**: Rename codeinterpreter into lobe sandbox, closes [#11076](https://github.com/lobehub/lobe-chat/issues/11076) ([2a631b4](https://github.com/lobehub/lobe-chat/commit/2a631b4))
|
||||
- **misc**: Server implement ([685a6cd](https://github.com/lobehub/lobe-chat/commit/685a6cd))
|
||||
- **misc**: Support CMD K ([d2bd8a6](https://github.com/lobehub/lobe-chat/commit/d2bd8a6))
|
||||
- **misc**: Support exec async sub agent task ([dba1acf](https://github.com/lobehub/lobe-chat/commit/dba1acf))
|
||||
- **misc**: Support export and import topic JSON, closes [#10885](https://github.com/lobehub/lobe-chat/issues/10885) ([0c5a41f](https://github.com/lobehub/lobe-chat/commit/0c5a41f))
|
||||
- **misc**: Support files upload in chat input, closes [#10967](https://github.com/lobehub/lobe-chat/issues/10967) ([60eba45](https://github.com/lobehub/lobe-chat/commit/60eba45))
|
||||
- **misc**: Support notebook tool, closes [#10902](https://github.com/lobehub/lobe-chat/issues/10902) ([e05375f](https://github.com/lobehub/lobe-chat/commit/e05375f))
|
||||
- **misc**: Support swr local cache, closes [#10884](https://github.com/lobehub/lobe-chat/issues/10884) ([bc3f3e2](https://github.com/lobehub/lobe-chat/commit/bc3f3e2))
|
||||
- **misc**: Topic message swr cache, closes [#10886](https://github.com/lobehub/lobe-chat/issues/10886) ([613a404](https://github.com/lobehub/lobe-chat/commit/613a404))
|
||||
- **misc**: Translate AI model descriptions to English, closes [#10989](https://github.com/lobehub/lobe-chat/issues/10989) ([36ea258](https://github.com/lobehub/lobe-chat/commit/36ea258))
|
||||
- **misc**: Update agent builder ui, closes [#10996](https://github.com/lobehub/lobe-chat/issues/10996) ([704ef7f](https://github.com/lobehub/lobe-chat/commit/704ef7f))
|
||||
- **misc**: Update create group chat use builder, closes [#11030](https://github.com/lobehub/lobe-chat/issues/11030) ([7ae24c2](https://github.com/lobehub/lobe-chat/commit/7ae24c2))
|
||||
- **misc**: Update gtd tools( use editor & update metadata ), closes [#11029](https://github.com/lobehub/lobe-chat/issues/11029) ([4a47ea0](https://github.com/lobehub/lobe-chat/commit/4a47ea0))
|
||||
- **misc**: Update user memory embedding model selection based on business features ([c026117](https://github.com/lobehub/lobe-chat/commit/c026117))
|
||||
- **misc**: User memory ([d5ce144](https://github.com/lobehub/lobe-chat/commit/d5ce144))
|
||||
- **misc**: User memory ([49ffcb5](https://github.com/lobehub/lobe-chat/commit/49ffcb5))
|
||||
- **misc**: User onboarding ([5e59388](https://github.com/lobehub/lobe-chat/commit/5e59388))
|
||||
- **misc**: When use usesend to create agent/group, the model should override by lobeAi, closes [#11048](https://github.com/lobehub/lobe-chat/issues/11048) ([754ffe1](https://github.com/lobehub/lobe-chat/commit/754ffe1))
|
||||
- **misc**: Wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI ([672bcf7](https://github.com/lobehub/lobe-chat/commit/672bcf7))
|
||||
|
||||
#### What's fixed
|
||||
|
||||
- **ci**: Skip backend routes in bundle analyzer build, closes [#10944](https://github.com/lobehub/lobe-chat/issues/10944) ([2fc3b42](https://github.com/lobehub/lobe-chat/commit/2fc3b42))
|
||||
- **desktop**: prevent window resize when onboarding, closes [#10887](https://github.com/lobehub/lobe-chat/issues/10887) ([c29c02b](https://github.com/lobehub/lobe-chat/commit/c29c02b))
|
||||
- **desktop**: Add safe top edge for message container, closes [#10908](https://github.com/lobehub/lobe-chat/issues/10908) ([2558b47](https://github.com/lobehub/lobe-chat/commit/2558b47))
|
||||
- **i18n**: Translate plugin.ts locale to English, closes [#10972](https://github.com/lobehub/lobe-chat/issues/10972) ([89f89c7](https://github.com/lobehub/lobe-chat/commit/89f89c7))
|
||||
- **image-generation**: Update chargeBeforeGenerate to return ChargeResult and include configForDatabase in parameters ([4f2a683](https://github.com/lobehub/lobe-chat/commit/4f2a683))
|
||||
- **memory-user-memory**: Should pre-process date & time, closes [#10979](https://github.com/lobehub/lobe-chat/issues/10979) ([c2bcf73](https://github.com/lobehub/lobe-chat/commit/c2bcf73))
|
||||
- **observability-otel**: Typo in package name, closes [#11025](https://github.com/lobehub/lobe-chat/issues/11025) ([63224dd](https://github.com/lobehub/lobe-chat/commit/63224dd))
|
||||
- **prebuild**: Correct syntax in partialBuildPages array ([9580672](https://github.com/lobehub/lobe-chat/commit/9580672))
|
||||
- **translation**: Add fallback for all English locale variants, closes [#10984](https://github.com/lobehub/lobe-chat/issues/10984) ([ce46996](https://github.com/lobehub/lobe-chat/commit/ce46996))
|
||||
- **userMemories**: 404/405 issue due to incorrectly used workflow name and mounted catch-all route, closes [#10995](https://github.com/lobehub/lobe-chat/issues/10995) ([45996c6](https://github.com/lobehub/lobe-chat/commit/45996c6))
|
||||
- **userMemories**: Missing base memory as part of context, closes [#11040](https://github.com/lobehub/lobe-chat/issues/11040) ([3c9bafe](https://github.com/lobehub/lobe-chat/commit/3c9bafe))
|
||||
- **userMemories**: Must assign workflow id, closes [#11021](https://github.com/lobehub/lobe-chat/issues/11021) ([78b0c7b](https://github.com/lobehub/lobe-chat/commit/78b0c7b))
|
||||
- **userMemories**: Should use `context.invoke` for workflow instead of `context.run`, closes [#10994](https://github.com/lobehub/lobe-chat/issues/10994) ([6592d10](https://github.com/lobehub/lobe-chat/commit/6592d10))
|
||||
- **userMemories**: Skip to handle WorkflowAbort, closes [#11031](https://github.com/lobehub/lobe-chat/issues/11031) ([17124a8](https://github.com/lobehub/lobe-chat/commit/17124a8))
|
||||
- **userMemories**: Use date & time for building context, closes [#10978](https://github.com/lobehub/lobe-chat/issues/10978) ([15bc6bc](https://github.com/lobehub/lobe-chat/commit/15bc6bc))
|
||||
- **userMemories**: Workflow id build issue, closes [#10998](https://github.com/lobehub/lobe-chat/issues/10998) ([0b110b6](https://github.com/lobehub/lobe-chat/commit/0b110b6))
|
||||
- **misc**: Agent profiles update, agent tools config set, editor placeholder, closes [#11074](https://github.com/lobehub/lobe-chat/issues/11074) ([f7cbfe4](https://github.com/lobehub/lobe-chat/commit/f7cbfe4))
|
||||
- **misc**: Bump charts 3.0.4 to fix import es path, closes [#10898](https://github.com/lobehub/lobe-chat/issues/10898) ([6d7dce7](https://github.com/lobehub/lobe-chat/commit/6d7dce7))
|
||||
- **misc**: Fix anthropic thinking budget ([6e19bd3](https://github.com/lobehub/lobe-chat/commit/6e19bd3))
|
||||
- **misc**: Fix async task and improve tool style ([1aa1c04](https://github.com/lobehub/lobe-chat/commit/1aa1c04))
|
||||
- **misc**: Fix default waitlist bug ([de62035](https://github.com/lobehub/lobe-chat/commit/de62035))
|
||||
- **misc**: Fix delete agent group bug ([0fe0d6f](https://github.com/lobehub/lobe-chat/commit/0fe0d6f))
|
||||
- **misc**: Fix desktop test cases and refactor translations, closes [#10956](https://github.com/lobehub/lobe-chat/issues/10956) ([568235c](https://github.com/lobehub/lobe-chat/commit/568235c))
|
||||
- **misc**: Fix desktop test cases and refactor translations, closes [#10955](https://github.com/lobehub/lobe-chat/issues/10955) ([b3520a2](https://github.com/lobehub/lobe-chat/commit/b3520a2))
|
||||
- **misc**: Fix gemini 3 model thinking issue ([69f4cf3](https://github.com/lobehub/lobe-chat/commit/69f4cf3))
|
||||
- **misc**: Fix gemini 3 pro parallel tool use ([a0cc9c3](https://github.com/lobehub/lobe-chat/commit/a0cc9c3))
|
||||
- **misc**: Fix gemini 3 thinking params ([89363b2](https://github.com/lobehub/lobe-chat/commit/89363b2))
|
||||
- **misc**: Fix identity memory not working, closes [#10916](https://github.com/lobehub/lobe-chat/issues/10916) ([fbd0b66](https://github.com/lobehub/lobe-chat/commit/fbd0b66))
|
||||
- **misc**: Fix supervisor flag ([fc20dbc](https://github.com/lobehub/lobe-chat/commit/fc20dbc))
|
||||
- **misc**: Fix thread not working issue ([7dd30eb](https://github.com/lobehub/lobe-chat/commit/7dd30eb))
|
||||
- **misc**: Fix when use branch topic,the branch index error problem, closes [#11049](https://github.com/lobehub/lobe-chat/issues/11049) ([34b5a32](https://github.com/lobehub/lobe-chat/commit/34b5a32))
|
||||
- **misc**: Fixed the welcome card the create button not work, closes [#11055](https://github.com/lobehub/lobe-chat/issues/11055) ([00e81f1](https://github.com/lobehub/lobe-chat/commit/00e81f1))
|
||||
- **misc**: Handle session invalidation on 401 error by logging out signed-in users ([499bd4a](https://github.com/lobehub/lobe-chat/commit/499bd4a))
|
||||
- **misc**: Improve test infrastructure and mock configurations, closes [#11028](https://github.com/lobehub/lobe-chat/issues/11028) ([da4eb9c](https://github.com/lobehub/lobe-chat/commit/da4eb9c))
|
||||
- **misc**: Locale resolve bug with ESM module loading, closes [#11018](https://github.com/lobehub/lobe-chat/issues/11018) ([770c872](https://github.com/lobehub/lobe-chat/commit/770c872))
|
||||
- **misc**: Page agent editor, closes [#10953](https://github.com/lobehub/lobe-chat/issues/10953) ([61b3031](https://github.com/lobehub/lobe-chat/commit/61b3031))
|
||||
- **misc**: Prevent redundant login redirect when already on auth pages ([1a5049c](https://github.com/lobehub/lobe-chat/commit/1a5049c))
|
||||
- **misc**: Redis read json object ([1718fa3](https://github.com/lobehub/lobe-chat/commit/1718fa3))
|
||||
- **misc**: Remove openapi pkg patch file, closes [#10910](https://github.com/lobehub/lobe-chat/issues/10910) ([a34c111](https://github.com/lobehub/lobe-chat/commit/a34c111))
|
||||
- **misc**: Slove input editor on pause emit, closes [#11051](https://github.com/lobehub/lobe-chat/issues/11051) ([d102d47](https://github.com/lobehub/lobe-chat/commit/d102d47))
|
||||
- **misc**: Slove swr mutate not work in Cache Provider, closes [#10895](https://github.com/lobehub/lobe-chat/issues/10895) ([b3fbffe](https://github.com/lobehub/lobe-chat/commit/b3fbffe))
|
||||
- **misc**: Slove the group add member checkbox not work, closes [#11045](https://github.com/lobehub/lobe-chat/issues/11045) [#11042](https://github.com/lobehub/lobe-chat/issues/11042) ([91d3f74](https://github.com/lobehub/lobe-chat/commit/91d3f74))
|
||||
- **misc**: Slove the model select null problem, closes [#10988](https://github.com/lobehub/lobe-chat/issues/10988) ([50aa304](https://github.com/lobehub/lobe-chat/commit/50aa304))
|
||||
- **misc**: Slove the mutate not work problem, closes [#10947](https://github.com/lobehub/lobe-chat/issues/10947) ([78ca5eb](https://github.com/lobehub/lobe-chat/commit/78ca5eb))
|
||||
- **misc**: Slove when click agentbuilder should clean topic, closes [#11068](https://github.com/lobehub/lobe-chat/issues/11068) ([048bd66](https://github.com/lobehub/lobe-chat/commit/048bd66))
|
||||
- **misc**: Slove when first call thread, not show ai chat message, closes [#10878](https://github.com/lobehub/lobe-chat/issues/10878) ([5a79cb9](https://github.com/lobehub/lobe-chat/commit/5a79cb9))
|
||||
- **misc**: Support retry error message and fix continueGenerationMessage ([8bf85fb](https://github.com/lobehub/lobe-chat/commit/8bf85fb))
|
||||
- **misc**: Update contextMenu in group tools message, closes [#11056](https://github.com/lobehub/lobe-chat/issues/11056) ([8b49414](https://github.com/lobehub/lobe-chat/commit/8b49414))
|
||||
- **misc**: Update OFFICIAL_URL to app.lobehub.com, closes [#11015](https://github.com/lobehub/lobe-chat/issues/11015) ([f9e11d0](https://github.com/lobehub/lobe-chat/commit/f9e11d0))
|
||||
- **misc**: Update PlanTag link paths for subscription settings ([ada71d3](https://github.com/lobehub/lobe-chat/commit/ada71d3))
|
||||
- **misc**: Update test snapshots for model description changes, closes [#11008](https://github.com/lobehub/lobe-chat/issues/11008) ([626e808](https://github.com/lobehub/lobe-chat/commit/626e808))
|
||||
- **misc**: When use agentbuilder the topic id should use new & clear topic…, closes [#10983](https://github.com/lobehub/lobe-chat/issues/10983) ([0b2b096](https://github.com/lobehub/lobe-chat/commit/0b2b096))
|
||||
|
||||
#### Styles
|
||||
|
||||
- **misc**: Improve ExecTask and task message UI ([977a700](https://github.com/lobehub/lobe-chat/commit/977a700))
|
||||
- **misc**: Improve gtd tool inspector and todo list ([0664563](https://github.com/lobehub/lobe-chat/commit/0664563))
|
||||
- **misc**: Improve page document tool inspector UI, closes [#10977](https://github.com/lobehub/lobe-chat/issues/10977) ([7f69cb1](https://github.com/lobehub/lobe-chat/commit/7f69cb1))
|
||||
- **misc**: Improve RunCommand Inspector ([0751fa4](https://github.com/lobehub/lobe-chat/commit/0751fa4))
|
||||
- **misc**: Rebranding chat ui ([ad14222](https://github.com/lobehub/lobe-chat/commit/ad14222))
|
||||
- **misc**: Refactor UI in features ([83e689f](https://github.com/lobehub/lobe-chat/commit/83e689f))
|
||||
- **misc**: Rerun i18n ([80f511c](https://github.com/lobehub/lobe-chat/commit/80f511c))
|
||||
- **misc**: Setting style ([e8c755f](https://github.com/lobehub/lobe-chat/commit/e8c755f))
|
||||
- **misc**: Support streaming and display ui for group mode ([f708cdb](https://github.com/lobehub/lobe-chat/commit/f708cdb))
|
||||
- **misc**: Support tool streaming and title custom render, closes [#10976](https://github.com/lobehub/lobe-chat/issues/10976) ([576ccd6](https://github.com/lobehub/lobe-chat/commit/576ccd6))
|
||||
- **misc**: Update i18n ([2e6fd07](https://github.com/lobehub/lobe-chat/commit/2e6fd07))
|
||||
- **misc**: Update i18n microcopy, closes [#10905](https://github.com/lobehub/lobe-chat/issues/10905) ([024aeb2](https://github.com/lobehub/lobe-chat/commit/024aeb2))
|
||||
- **misc**: Update ui ([1693fc5](https://github.com/lobehub/lobe-chat/commit/1693fc5))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.180](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.179...v2.0.0-next.180)
|
||||
|
||||
<sup>Released on **2025-12-26**</sup>
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.179](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.178...v2.0.0-next.179)
|
||||
|
||||
<sup>Released on **2025-12-25**</sup>
|
||||
|
||||
#### 🐛 Bug Fixes
|
||||
|
||||
- **scripts**: Fix syntax error in prebuild.mts.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### What's fixed
|
||||
|
||||
- **scripts**: Fix syntax error in prebuild.mts, closes [#10952](https://github.com/lobehub/lobe-chat/issues/10952) ([3d46c13](https://github.com/lobehub/lobe-chat/commit/3d46c13))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.178](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.177...v2.0.0-next.178)
|
||||
|
||||
<sup>Released on **2025-12-24**</sup>
|
||||
|
||||
#### 🐛 Bug Fixes
|
||||
|
||||
- **ci**: Always continue build to upload bundle analyzer report, skip backend routes in bundle analyzer build.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### What's fixed
|
||||
|
||||
- **ci**: Always continue build to upload bundle analyzer report, closes [#10946](https://github.com/lobehub/lobe-chat/issues/10946) ([8d37811](https://github.com/lobehub/lobe-chat/commit/8d37811))
|
||||
- **ci**: Skip backend routes in bundle analyzer build, closes [#10944](https://github.com/lobehub/lobe-chat/issues/10944) ([0276b87](https://github.com/lobehub/lobe-chat/commit/0276b87))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.177](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.176...v2.0.0-next.177)
|
||||
|
||||
<sup>Released on **2025-12-24**</sup>
|
||||
|
||||
#### ✨ Features
|
||||
|
||||
- **ci**: Add bundle analyzer workflow.
|
||||
|
||||
<br/>
|
||||
|
||||
<details>
|
||||
<summary><kbd>Improvements and Fixes</kbd></summary>
|
||||
|
||||
#### What's improved
|
||||
|
||||
- **ci**: Add bundle analyzer workflow, closes [#10932](https://github.com/lobehub/lobe-chat/issues/10932) ([c470cfb](https://github.com/lobehub/lobe-chat/commit/c470cfb))
|
||||
|
||||
</details>
|
||||
|
||||
<div align="right">
|
||||
|
||||
[](#readme-top)
|
||||
|
||||
</div>
|
||||
|
||||
## [Version 2.0.0-next.176](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.175...v2.0.0-next.176)
|
||||
|
||||
<sup>Released on **2025-12-23**</sup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This document serves as a shared guideline for all team members when using Claude Code in this opensource lobe-chat(also known as lobehub) repository.
|
||||
This document serves as a shared guideline for all team members when using Claude Code in this repository.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -14,6 +14,7 @@ read @.cursor/rules/project-structure.mdc
|
||||
|
||||
### Git Workflow
|
||||
|
||||
- The current release branch is `next` instead of `main` until v2.0.0 is officially released
|
||||
- use rebase for git pull
|
||||
- git commit message should prefix with gitmoji
|
||||
- git branch name format template: <type>/<feature-name>
|
||||
|
||||
+1
-2
@@ -74,14 +74,13 @@ ENV NEXT_PUBLIC_ANALYTICS_UMAMI="${NEXT_PUBLIC_ANALYTICS_UMAMI}" \
|
||||
NEXT_PUBLIC_UMAMI_WEBSITE_ID="${NEXT_PUBLIC_UMAMI_WEBSITE_ID}"
|
||||
|
||||
# Node
|
||||
ENV NODE_OPTIONS="--max-old-space-size=8192"
|
||||
ENV NODE_OPTIONS="--max-old-space-size=6144"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package.json pnpm-workspace.yaml ./
|
||||
COPY .npmrc ./
|
||||
COPY packages ./packages
|
||||
COPY patches ./patches
|
||||
# bring in desktop workspace manifest so pnpm can resolve it
|
||||
COPY apps/desktop/src/main/package.json ./apps/desktop/src/main/package.json
|
||||
|
||||
|
||||
@@ -165,16 +165,12 @@ const config = {
|
||||
CFBundleURLSchemes: [protocolScheme],
|
||||
},
|
||||
],
|
||||
NSAppleEventsUsageDescription:
|
||||
'Application needs to control System Settings to help you grant Full Disk Access automatically.',
|
||||
NSCameraUsageDescription: "Application requests access to the device's camera.",
|
||||
NSDocumentsFolderUsageDescription:
|
||||
"Application requests access to the user's Documents folder.",
|
||||
NSDownloadsFolderUsageDescription:
|
||||
"Application requests access to the user's Downloads folder.",
|
||||
NSMicrophoneUsageDescription: "Application requests access to the device's microphone.",
|
||||
NSScreenCaptureUsageDescription:
|
||||
'Application requests access to record and analyze screen content for AI assistance.',
|
||||
},
|
||||
gatekeeperAssess: false,
|
||||
hardenedRuntime: hasAppleCertificate,
|
||||
|
||||
@@ -96,8 +96,6 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
||||
const merged = this.normalizeConfig({ ...prev, ...config });
|
||||
storeManager.set('dataSyncConfig', merged);
|
||||
|
||||
this.broadcastRemoteServerConfigUpdated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,16 +113,9 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
||||
// Clear tokens (if any)
|
||||
await this.clearTokens();
|
||||
|
||||
this.broadcastRemoteServerConfigUpdated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private broadcastRemoteServerConfigUpdated() {
|
||||
logger.debug('Broadcasting remoteServerConfigUpdated event to all windows');
|
||||
this.app.browserManager.broadcastToAllWindows('remoteServerConfigUpdated', undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypted tokens
|
||||
* Stored in memory for quick access, loaded from persistent storage on init.
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import { ElectronAppState, ThemeMode } from '@lobechat/electron-client-ipc';
|
||||
import { app, nativeTheme, shell, systemPreferences } from 'electron';
|
||||
import { macOS } from 'electron-is';
|
||||
import { spawn } from 'node:child_process';
|
||||
import path from 'node:path';
|
||||
import process from 'node:process';
|
||||
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
import { ControllerModule, IpcMethod } from './index';
|
||||
import fullDiskAccessAutoAddScript from './scripts/full-disk-access.applescript?raw';
|
||||
|
||||
const logger = createLogger('controllers:SystemCtr');
|
||||
|
||||
@@ -79,114 +76,17 @@ export default class SystemController extends ControllerModule {
|
||||
}
|
||||
|
||||
@IpcMethod()
|
||||
async requestScreenAccess(): Promise<boolean> {
|
||||
if (!macOS()) return true;
|
||||
|
||||
// IMPORTANT:
|
||||
// On macOS, the app may NOT appear in "Screen Recording" list until it actually
|
||||
// requests the permission once (TCC needs to register this app).
|
||||
// So we try to proactively request it first, then open System Settings for manual toggle.
|
||||
// 1) Best-effort: try Electron runtime API if available (not typed in Electron 38).
|
||||
try {
|
||||
const status = systemPreferences.getMediaAccessStatus('screen');
|
||||
if (status !== 'granted') {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
await (systemPreferences as any).askForMediaAccess?.('screen');
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn('Failed to request screen recording access via systemPreferences', error);
|
||||
}
|
||||
|
||||
// 2) Reliable trigger: run a one-shot getDisplayMedia in renderer to register TCC entry.
|
||||
// This will show the OS capture picker; once the user selects/cancels, we stop tracks immediately.
|
||||
try {
|
||||
const status = systemPreferences.getMediaAccessStatus('screen');
|
||||
if (status !== 'granted') {
|
||||
const mainWindow = this.app.browserManager.getMainWindow()?.browserWindow;
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
const script = `
|
||||
(() => {
|
||||
const stop = (stream) => {
|
||||
try { stream.getTracks().forEach((t) => t.stop()); } catch {}
|
||||
};
|
||||
return navigator.mediaDevices.getDisplayMedia({ video: true, audio: false })
|
||||
.then((stream) => { stop(stream); return true; })
|
||||
.catch(() => false);
|
||||
})()
|
||||
`.trim();
|
||||
|
||||
await mainWindow.webContents.executeJavaScript(script, true);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn('Failed to request screen recording access via getDisplayMedia', error);
|
||||
}
|
||||
|
||||
await shell.openExternal(
|
||||
async requestScreenAccess(): Promise<void> {
|
||||
if (!macOS()) return;
|
||||
shell.openExternal(
|
||||
'x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture',
|
||||
);
|
||||
|
||||
return systemPreferences.getMediaAccessStatus('screen') === 'granted';
|
||||
}
|
||||
|
||||
@IpcMethod()
|
||||
openFullDiskAccessSettings(payload?: { autoAdd?: boolean }) {
|
||||
openFullDiskAccessSettings() {
|
||||
if (!macOS()) return;
|
||||
const { autoAdd = false } = payload || {};
|
||||
|
||||
// NOTE:
|
||||
// - Full Disk Access cannot be requested programmatically like microphone/screen.
|
||||
// - On macOS 13+ (Ventura), System Preferences is replaced by System Settings,
|
||||
// and deep links may differ. We try multiple known schemes for compatibility.
|
||||
const candidates = [
|
||||
// macOS 13+ (System Settings)
|
||||
'com.apple.settings:Privacy&path=FullDiskAccess',
|
||||
// Older macOS (System Preferences)
|
||||
'x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles',
|
||||
];
|
||||
if (autoAdd) this.tryAutoAddFullDiskAccess();
|
||||
|
||||
(async () => {
|
||||
for (const url of candidates) {
|
||||
try {
|
||||
await shell.openExternal(url);
|
||||
return;
|
||||
} catch (error) {
|
||||
logger.warn(`Failed to open Full Disk Access settings via ${url}`, error);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Best-effort UI automation to add this app into Full Disk Access list.
|
||||
*
|
||||
* Limitations:
|
||||
* - This uses AppleScript UI scripting (System Events) and may require the user to grant
|
||||
* additional "Automation" permission (to control System Settings).
|
||||
* - UI structure differs across macOS versions/languages; we fall back silently.
|
||||
*/
|
||||
private tryAutoAddFullDiskAccess() {
|
||||
if (!macOS()) return;
|
||||
|
||||
const exePath = app.getPath('exe');
|
||||
// /Applications/App.app/Contents/MacOS/App -> /Applications/App.app
|
||||
const appBundlePath = path.resolve(path.dirname(exePath), '..', '..');
|
||||
|
||||
// Keep the script minimal and resilient; failure should not break onboarding flow.
|
||||
const script = fullDiskAccessAutoAddScript.trim();
|
||||
|
||||
try {
|
||||
const child = spawn('osascript', ['-e', script, appBundlePath], { env: process.env });
|
||||
child.on('error', (error) => {
|
||||
logger.warn('Full Disk Access auto-add (osascript) failed to start', error);
|
||||
});
|
||||
child.on('exit', (code) => {
|
||||
logger.debug('Full Disk Access auto-add (osascript) exited', { code });
|
||||
});
|
||||
} catch (error) {
|
||||
logger.warn('Full Disk Access auto-add failed', error);
|
||||
}
|
||||
shell.openExternal('x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles');
|
||||
}
|
||||
|
||||
@IpcMethod()
|
||||
|
||||
@@ -43,12 +43,7 @@ const mockStoreManager = {
|
||||
set: vi.fn(),
|
||||
};
|
||||
|
||||
const mockBrowserManager = {
|
||||
broadcastToAllWindows: vi.fn(),
|
||||
};
|
||||
|
||||
const mockApp = {
|
||||
browserManager: mockBrowserManager,
|
||||
storeManager: mockStoreManager,
|
||||
} as unknown as App;
|
||||
|
||||
|
||||
@@ -44,22 +44,6 @@ vi.mock('@/utils/logger', () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
const { spawnMock } = vi.hoisted(() => ({
|
||||
spawnMock: vi.fn(() => {
|
||||
const handlers = new Map<string, (...args: any[]) => void>();
|
||||
return {
|
||||
on: vi.fn((event: string, cb: (...args: any[]) => void) => {
|
||||
handlers.set(event, cb);
|
||||
return undefined;
|
||||
}),
|
||||
} as any;
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('node:child_process', () => ({
|
||||
spawn: (...args: any[]) => spawnMock.call(null, ...args),
|
||||
}));
|
||||
|
||||
// Mock electron
|
||||
vi.mock('electron', () => ({
|
||||
app: {
|
||||
@@ -77,8 +61,6 @@ vi.mock('electron', () => ({
|
||||
openExternal: vi.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
systemPreferences: {
|
||||
askForMediaAccess: vi.fn(async () => true),
|
||||
getMediaAccessStatus: vi.fn(() => 'not-determined'),
|
||||
isTrustedAccessibilityClient: vi.fn(() => true),
|
||||
},
|
||||
}));
|
||||
@@ -91,14 +73,6 @@ vi.mock('electron-is', () => ({
|
||||
// Mock browserManager
|
||||
const mockBrowserManager = {
|
||||
broadcastToAllWindows: vi.fn(),
|
||||
getMainWindow: vi.fn(() => ({
|
||||
browserWindow: {
|
||||
isDestroyed: vi.fn(() => false),
|
||||
webContents: {
|
||||
executeJavaScript: vi.fn(async () => true),
|
||||
},
|
||||
},
|
||||
})),
|
||||
handleAppThemeChange: vi.fn(),
|
||||
};
|
||||
|
||||
@@ -189,68 +163,6 @@ describe('SystemController', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('screen recording', () => {
|
||||
it('should request screen recording access and open System Settings on macOS', async () => {
|
||||
const { shell, systemPreferences } = await import('electron');
|
||||
|
||||
const result = await invokeIpc('system.requestScreenAccess');
|
||||
|
||||
expect(systemPreferences.getMediaAccessStatus).toHaveBeenCalledWith('screen');
|
||||
expect(systemPreferences.askForMediaAccess).toHaveBeenCalledWith('screen');
|
||||
expect(mockBrowserManager.getMainWindow).toHaveBeenCalled();
|
||||
expect(shell.openExternal).toHaveBeenCalledWith(
|
||||
'x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture',
|
||||
);
|
||||
expect(typeof result).toBe('boolean');
|
||||
});
|
||||
|
||||
it('should return true on non-macOS and not open settings', async () => {
|
||||
const { macOS } = await import('electron-is');
|
||||
const { shell, systemPreferences } = await import('electron');
|
||||
vi.mocked(macOS).mockReturnValue(false);
|
||||
|
||||
const result = await invokeIpc('system.requestScreenAccess');
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(systemPreferences.askForMediaAccess).not.toHaveBeenCalled();
|
||||
expect(shell.openExternal).not.toHaveBeenCalled();
|
||||
|
||||
// Reset
|
||||
vi.mocked(macOS).mockReturnValue(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('full disk access', () => {
|
||||
it('should try to open Full Disk Access settings with fallbacks', async () => {
|
||||
const { shell } = await import('electron');
|
||||
vi.mocked(shell.openExternal)
|
||||
.mockRejectedValueOnce(new Error('fail first'))
|
||||
.mockResolvedValueOnce(undefined);
|
||||
|
||||
await invokeIpc('system.openFullDiskAccessSettings');
|
||||
|
||||
expect(shell.openExternal).toHaveBeenCalledWith(
|
||||
'com.apple.settings:Privacy&path=FullDiskAccess',
|
||||
);
|
||||
expect(shell.openExternal).toHaveBeenCalledWith(
|
||||
'x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles',
|
||||
);
|
||||
});
|
||||
|
||||
it('should spawn osascript when autoAdd is enabled', async () => {
|
||||
const { shell } = await import('electron');
|
||||
vi.mocked(shell.openExternal).mockResolvedValueOnce(undefined);
|
||||
|
||||
await invokeIpc('system.openFullDiskAccessSettings', { autoAdd: true });
|
||||
|
||||
expect(spawnMock).toHaveBeenCalledWith(
|
||||
'osascript',
|
||||
expect.arrayContaining(['-e', expect.any(String), expect.any(String)]),
|
||||
expect.objectContaining({ env: expect.any(Object) }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('openExternalLink', () => {
|
||||
it('should open external link', async () => {
|
||||
const { shell } = await import('electron');
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
on run argv
|
||||
set appBundlePath to item 1 of argv
|
||||
|
||||
set settingsBundleIds to {"com.apple.SystemSettings", "com.apple.systempreferences"}
|
||||
|
||||
-- Bring System Settings/Preferences to front (Ventura+ / older). If it doesn't exist, ignore.
|
||||
repeat with bundleId in settingsBundleIds
|
||||
try
|
||||
tell application id bundleId to activate
|
||||
exit repeat
|
||||
end try
|
||||
end repeat
|
||||
|
||||
tell application "System Events"
|
||||
set settingsProcess to missing value
|
||||
repeat 30 times
|
||||
repeat with bundleId in settingsBundleIds
|
||||
try
|
||||
if exists (first process whose bundle identifier is bundleId) then
|
||||
set settingsProcess to first process whose bundle identifier is bundleId
|
||||
exit repeat
|
||||
end if
|
||||
end try
|
||||
end repeat
|
||||
|
||||
if settingsProcess is not missing value then exit repeat
|
||||
delay 0.2
|
||||
end repeat
|
||||
|
||||
if settingsProcess is missing value then return "no-settings-process"
|
||||
|
||||
tell settingsProcess
|
||||
set frontmost to true
|
||||
|
||||
repeat 30 times
|
||||
if exists window 1 then exit repeat
|
||||
delay 0.2
|
||||
end repeat
|
||||
if not (exists window 1) then return "no-window"
|
||||
|
||||
-- Best-effort: find an "add" button in the front window and click it.
|
||||
set clickedAdd to false
|
||||
repeat 30 times
|
||||
try
|
||||
repeat with b in (buttons of window 1)
|
||||
set bDesc to ""
|
||||
set bName to ""
|
||||
set bTitle to ""
|
||||
try set bDesc to description of b end try
|
||||
try set bName to name of b end try
|
||||
try set bTitle to title of b end try
|
||||
|
||||
if (bDesc is "Add") or (bTitle is "Add") or (bName is "+") or (bTitle is "+") then
|
||||
click b
|
||||
set clickedAdd to true
|
||||
exit repeat
|
||||
end if
|
||||
end repeat
|
||||
end try
|
||||
|
||||
if clickedAdd is true then exit repeat
|
||||
delay 0.2
|
||||
end repeat
|
||||
|
||||
if clickedAdd is false then return "no-add-button"
|
||||
|
||||
-- Wait for open panel / sheet
|
||||
repeat 30 times
|
||||
if exists sheet 1 of window 1 then exit repeat
|
||||
delay 0.2
|
||||
end repeat
|
||||
if not (exists sheet 1 of window 1) then return "no-sheet"
|
||||
|
||||
-- Open "Go to the folder" and input the app bundle path, then confirm.
|
||||
keystroke "G" using {command down, shift down}
|
||||
delay 0.3
|
||||
keystroke appBundlePath
|
||||
key code 36
|
||||
delay 0.6
|
||||
-- Confirm "Open" in the panel (Enter usually triggers default)
|
||||
key code 36
|
||||
return "ok"
|
||||
end tell
|
||||
end tell
|
||||
end run
|
||||
@@ -1,6 +1,5 @@
|
||||
import { BrowserWindow, type Session } from 'electron';
|
||||
import type { Session } from 'electron';
|
||||
|
||||
import { isDev } from '@/const/env';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
interface BackendProxyProtocolManagerOptions {
|
||||
@@ -31,15 +30,6 @@ export class BackendProxyProtocolManager {
|
||||
private readonly handledSessions = new WeakSet<Session>();
|
||||
private readonly logger = createLogger('core:BackendProxyProtocolManager');
|
||||
|
||||
private notifyAuthorizationRequired() {
|
||||
const allWindows = BrowserWindow.getAllWindows();
|
||||
for (const win of allWindows) {
|
||||
if (!win.isDestroyed()) {
|
||||
win.webContents.send('authorizationRequired');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerWithRemoteBaseUrl(
|
||||
session: Session,
|
||||
options: BackendProxyProtocolManagerRemoteBaseOptions,
|
||||
@@ -95,9 +85,7 @@ export class BackendProxyProtocolManager {
|
||||
|
||||
const headers = new Headers(request.headers);
|
||||
const token = await options.getAccessToken();
|
||||
if (token) {
|
||||
headers.set('Oidc-Auth', token);
|
||||
}
|
||||
if (token) headers.set('Oidc-Auth', token);
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
const requestInit: RequestInit & { duplex?: 'half' } = {
|
||||
@@ -138,18 +126,10 @@ export class BackendProxyProtocolManager {
|
||||
responseHeaders.set('Access-Control-Allow-Credentials', 'true');
|
||||
}
|
||||
|
||||
if (isDev) {
|
||||
responseHeaders.set('x-dev-oidc-auth', token);
|
||||
}
|
||||
|
||||
responseHeaders.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
||||
responseHeaders.set('Access-Control-Allow-Headers', '*');
|
||||
responseHeaders.set('X-Src-Url', rewrittenUrl);
|
||||
|
||||
if (!token && upstreamResponse.status === 401) {
|
||||
this.notifyAuthorizationRequired();
|
||||
}
|
||||
|
||||
return new Response(upstreamResponse.body, {
|
||||
headers: responseHeaders,
|
||||
status: upstreamResponse.status,
|
||||
|
||||
@@ -175,7 +175,6 @@ export class I18nManager {
|
||||
try {
|
||||
logger.debug(`Loading namespace: ${lng}/${ns}`);
|
||||
const resources = await loadResources(lng, ns);
|
||||
|
||||
this.i18n.addResourceBundle(lng, ns, resources, true, true);
|
||||
return true;
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import log from 'electron-log';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
|
||||
import { isDev, isWindows } from '@/const/env';
|
||||
import { isDev } from '@/const/env';
|
||||
import { UPDATE_CHANNEL as channel, updaterConfig } from '@/modules/updater/configs';
|
||||
import { createLogger } from '@/utils/logger';
|
||||
|
||||
@@ -144,16 +144,12 @@ export class UpdaterManager {
|
||||
// Close all windows first to ensure clean exit
|
||||
logger.info('Closing all windows before update installation...');
|
||||
const { BrowserWindow, app } = require('electron');
|
||||
// do not close windows and quit first
|
||||
// on Windows, window-all-closed -> app.quit()` can terminate the process before the timer fires
|
||||
if (!isWindows) {
|
||||
const allWindows = BrowserWindow.getAllWindows();
|
||||
allWindows.forEach((window) => {
|
||||
if (!window.isDestroyed()) {
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
const allWindows = BrowserWindow.getAllWindows();
|
||||
allWindows.forEach((window) => {
|
||||
if (!window.isDestroyed()) {
|
||||
window.close();
|
||||
}
|
||||
});
|
||||
|
||||
// Release single instance lock before quitting
|
||||
// This ensures the new instance can acquire the lock
|
||||
|
||||
-7
@@ -21,13 +21,6 @@ const { mockProtocol, protocolHandlerRef } = vi.hoisted(() => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('electron-is', () => ({
|
||||
dev: vi.fn(() => false),
|
||||
macOS: vi.fn(() => false),
|
||||
windows: vi.fn(() => false),
|
||||
linux: vi.fn(() => true),
|
||||
}));
|
||||
|
||||
vi.mock('@/utils/logger', () => ({
|
||||
createLogger: () => ({
|
||||
debug: vi.fn(),
|
||||
|
||||
@@ -76,7 +76,7 @@ export const getDesktopEnv = memoize(() =>
|
||||
MCP_TOOL_TIMEOUT: envNumber(60_000),
|
||||
|
||||
// cloud server url (can be overridden for selfhost/dev)
|
||||
OFFICIAL_CLOUD_SERVER: z.string().optional().default('https://app.lobehub.com'),
|
||||
OFFICIAL_CLOUD_SERVER: z.string().optional().default('https://lobechat.com'),
|
||||
},
|
||||
clientPrefix: 'PUBLIC_',
|
||||
client: {},
|
||||
|
||||
@@ -22,9 +22,7 @@ export const loadResources = async (lng: string, ns: string) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const { default: content } = await import(`@/../../resources/locales/${lng}/${ns}.json`);
|
||||
|
||||
return content;
|
||||
return await import(`@/../../resources/locales/${lng}/${ns}.json`);
|
||||
} catch (error) {
|
||||
console.error(`无法加载翻译文件: ${lng} - ${ns}`, error);
|
||||
return {};
|
||||
|
||||
@@ -1,100 +1,4 @@
|
||||
[
|
||||
{
|
||||
"children": {
|
||||
"improvements": ["Update i18n."]
|
||||
},
|
||||
"date": "2026-01-02",
|
||||
"version": "2.0.0-next.190"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"improvements": ["Migrate to new DropdownMenuV2 and showContextMenu API."]
|
||||
},
|
||||
"date": "2026-01-01",
|
||||
"version": "2.0.0-next.189"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"improvements": ["Improve tools UI and fix Google schema compatibility."]
|
||||
},
|
||||
"date": "2026-01-01",
|
||||
"version": "2.0.0-next.188"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"improvements": ["Add Gemini 3 Flash & Doubao Seed 1.8 models."]
|
||||
},
|
||||
"date": "2026-01-01",
|
||||
"version": "2.0.0-next.187"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"improvements": ["Refactor oidc env to auth env."]
|
||||
},
|
||||
"date": "2026-01-01",
|
||||
"version": "2.0.0-next.186"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"improvements": ["Update i18n."]
|
||||
},
|
||||
"date": "2026-01-01",
|
||||
"version": "2.0.0-next.185"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"improvements": ["Improve loading and local-system render."]
|
||||
},
|
||||
"date": "2026-01-01",
|
||||
"version": "2.0.0-next.184"
|
||||
},
|
||||
{
|
||||
"children": {},
|
||||
"date": "2025-12-31",
|
||||
"version": "2.0.0-next.183"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"features": ["Brand new 2.0 ui for next."]
|
||||
},
|
||||
"date": "2025-12-31",
|
||||
"version": "2.0.0-next.182"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"improvements": [
|
||||
"Improve ExecTask and task message UI, improve gtd tool inspector and todo list, improve page document tool inspector UI, improve RunCommand Inspector, rebranding chat ui, refactor UI in features, rerun i18n, setting style, support streaming and display ui for group mode, support tool streaming and title custom render, update i18n, Update i18n microcopy, update ui."
|
||||
],
|
||||
"features": [
|
||||
"Add a white waitlist in edge config env, add always show tools render in createPlan & createDoc tools, add batch tasks ui, add Bundle Analyzer workflow for detailed bundle size analysis, add business features support with new components and hooks, add business settings features with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add db and schema feature, add home page create group builder button, Add i18n UI locales and improve tool types, add like action in community detail, add memory implement, add subscription settings group with dynamic loading for Plans, Funds, Usage, Billing, and Referral tabs, add the market auth auto generate way, Add turbopack configuration support to CustomNextConfig, add user memory, agent builder, agent builder, agent builder and group builder, app ui page, brand new 2.0 ui for next, buildin some tools should save into docs, code-interpreter tool, code-interpreter tool, code-interpreter tool, desktop feature, enhance desktop onboarding with sign out and localization, enhance macOS desktop permissions and onboarding, enhance onboarding process by removing mode selection step and adding export functionality in advanced settings, file search feature, gtd create plan support streaming render, implement agent builder, implement builtin agents packages, implement memories package, implement Redis caching for presigned URLs in file proxy service, implement server data feature, include Subscription settings group in the Accordion component, Integrate bcryptjs for password verification in BetterAuth, integrate BrandingProviderCard and update Provider components for branding support, onboarding ui, page and knowledge base, rebranding total UI of app, refactor authentication handler to support dynamic loading of better-auth and next-auth, refactor desktop implement with brand new 2.0, rename codeinterpreter into lobe sandbox, server implement, support CMD K, support exec async sub agent task, support export and import topic JSON, support files upload in chat input, support notebook tool, support swr local cache, topic message swr cache, translate AI model descriptions to English, update agent builder ui, update create group chat use builder, update gtd tools( use editor & update metadata ), update user memory embedding model selection based on business features, user memory, user memory, user onboarding, when use usesend to create agent/group, the model should override by lobeAi, wrap ConversationArea and ModelSwitchPanel in TooltipGroup for enhanced UI."
|
||||
],
|
||||
"fixes": [
|
||||
"Agent profiles update, agent tools config set, editor placeholder, bump charts 3.0.4 to fix import es path, fix anthropic thinking budget, fix async task and improve tool style, fix default waitlist bug, fix delete agent group bug, Fix desktop test cases and refactor translations, Fix desktop test cases and refactor translations, fix gemini 3 model thinking issue, fix gemini 3 pro parallel tool use, fix gemini 3 thinking params, fix identity memory not working, fix supervisor flag, fix thread not working issue, fix when use branch topic,the branch index error problem, fixed the welcome card the create button not work, handle session invalidation on 401 error by logging out signed-in users, improve test infrastructure and mock configurations, locale resolve bug with ESM module loading, page agent editor, prevent redundant login redirect when already on auth pages, redis read json object, remove openapi pkg patch file, slove input editor on pause emit, slove swr mutate not work in Cache Provider, slove the group add member checkbox not work, slove the model select null problem, slove the mutate not work problem, slove when click agentbuilder should clean topic, slove when first call thread, not show ai chat message, support retry error message and fix continueGenerationMessage, update contextMenu in group tools message, update OFFICIAL_URL to app.lobehub.com, update PlanTag link paths for subscription settings, update test snapshots for model description changes, when use agentbuilder the topic id should use new & clear topic…."
|
||||
]
|
||||
},
|
||||
"date": "2025-12-31",
|
||||
"version": "2.0.0-next.181"
|
||||
},
|
||||
{
|
||||
"children": {},
|
||||
"date": "2025-12-26",
|
||||
"version": "2.0.0-next.180"
|
||||
},
|
||||
{
|
||||
"children": {},
|
||||
"date": "2025-12-25",
|
||||
"version": "2.0.0-next.179"
|
||||
},
|
||||
{
|
||||
"children": {},
|
||||
"date": "2025-12-24",
|
||||
"version": "2.0.0-next.178"
|
||||
},
|
||||
{
|
||||
"children": {},
|
||||
"date": "2025-12-24",
|
||||
"version": "2.0.0-next.177"
|
||||
},
|
||||
{
|
||||
"children": {
|
||||
"features": ["Mobile native better auth support."]
|
||||
|
||||
@@ -44,14 +44,12 @@ Before connecting the desktop to your self-hosted instance, ensure that your sel
|
||||
|
||||
#### OIDC Environment Variable Configuration
|
||||
|
||||
You need to add the following two environment variables, `ENABLE_OIDC` and `JWKS_KEY`, to your self-hosted instance. You can click the button below to generate them with one click:
|
||||
You need to add the following two environment variables, `ENABLE_OIDC` and `OIDC_JWKS_KEY`, to your self-hosted instance. You can click the button below to generate them with one click:
|
||||
|
||||
<OIDCJWKs />
|
||||
|
||||
Add the generated JWK key to your environment variables.
|
||||
|
||||
<Callout>If you have already configured `OIDC_JWKS_KEY`, no changes are needed. The system will automatically fall back to `OIDC_JWKS_KEY` for backward compatibility.</Callout>
|
||||
|
||||
If you are deploying LobeChat using one-click deployment methods (such as Vercel, Railway, etc.), you need to:
|
||||
|
||||
1. Add the above environment variables to the environment variable configuration of your deployment platform.
|
||||
@@ -73,8 +71,8 @@ If you are deploying LobeChat using one-click deployment methods (such as Vercel
|
||||
|
||||
**Solution:**
|
||||
|
||||
- Confirm that you have correctly set the `ENABLE_OIDC=1` and `JWKS_KEY` environment variables.
|
||||
- Ensure that `JWKS_KEY` is in valid JSON format without extra single quotes.
|
||||
- Confirm that you have correctly set the `ENABLE_OIDC=1` and `OIDC_JWKS_KEY` environment variables.
|
||||
- Ensure that `OIDC_JWKS_KEY` is in valid JSON format without extra single quotes.
|
||||
- Check your server logs for specific error messages.
|
||||
|
||||
If you are using Nginx as a reverse proxy, the issue may be due to oversized request headers. You can try adding the following settings to your Nginx configuration:
|
||||
|
||||
@@ -42,14 +42,12 @@ LobeChat 桌面端可以与您自托管的 LobeChat 实例连接,以便您可
|
||||
|
||||
#### OIDC 环境变量配置
|
||||
|
||||
您需要在自托管实例中添加以下`ENABLE_OIDC` 和 `JWKS_KEY` 这两个环境变量,你可以点击下方按钮一键生成:
|
||||
您需要在自托管实例中添加以下`ENABLE_OIDC` 和 `OIDC_JWKS_KEY` 这两个环境变量,你可以点击下方按钮一键生成:
|
||||
|
||||
<OIDCJWKs />
|
||||
|
||||
将生成的 JWK 密钥添加到您的环境变量中。
|
||||
|
||||
<Callout>如果您之前已配置 `OIDC_JWKS_KEY`,无需修改。系统会自动回退使用 `OIDC_JWKS_KEY`(向后兼容)。</Callout>
|
||||
|
||||
如果您使用一键部署方式(如 Vercel、Railway 等平台)部署 LobeChat,您需要:
|
||||
|
||||
1. 将上述环境变量添加到部署平台的环境变量配置中
|
||||
@@ -71,8 +69,8 @@ LobeChat 桌面端可以与您自托管的 LobeChat 实例连接,以便您可
|
||||
|
||||
**解决方案:**
|
||||
|
||||
- 确认您已经正确设置了 `ENABLE_OIDC=1` 和 `JWKS_KEY` 环境变量
|
||||
- 确保 `JWKS_KEY` 是有效的 JSON 格式,没有额外的单引号
|
||||
- 确认您已经正确设置了 `ENABLE_OIDC=1` 和 `OIDC_JWKS_KEY` 环境变量
|
||||
- 确保 `OIDC_JWKS_KEY` 是有效的 JSON 格式,没有额外的单引号
|
||||
- 检查您的服务端日志,查看具体错误信息
|
||||
|
||||
如果您使用 Nginx 作为反向代理,可能是请求头太大导致的问题。可以尝试在 Nginx 配置中添加以下设置:
|
||||
|
||||
@@ -55,14 +55,6 @@ LobeChat provides a complete authentication service capability when deployed. Th
|
||||
- Default: `-`
|
||||
- Example: `google,github,microsoft,cognito`
|
||||
|
||||
#### `JWKS_KEY`
|
||||
|
||||
- Type: Required
|
||||
- Description: Generic JWKS (JSON Web Key Set) key for signing and verifying JWTs. Used for internal service authentication and other cryptographic operations. Must be a JWKS JSON string containing an RS256 RSA key pair. Falls back to `OIDC_JWKS_KEY` if not set (for backward compatibility).
|
||||
- Default: `-`
|
||||
|
||||
<OIDCJWKs />
|
||||
|
||||
### Email Service (SMTP)
|
||||
|
||||
These settings are required for email verification and password reset features.
|
||||
|
||||
@@ -53,14 +53,6 @@ LobeChat 在部署时提供了完善的身份验证服务能力,以下是相
|
||||
- 默认值:`-`
|
||||
- 示例:`google,github,microsoft,cognito`
|
||||
|
||||
#### `JWKS_KEY`
|
||||
|
||||
- 类型:必选
|
||||
- 描述:用于签名和验证 JWT 的通用 JWKS(JSON Web Key Set)密钥。用于内部服务认证和其他加密操作。必须是包含 RS256 RSA 密钥对的 JWKS JSON 字符串。如果未设置,将回退到 `OIDC_JWKS_KEY`(向后兼容)。
|
||||
- 默认值:`-`
|
||||
|
||||
<OIDCJWKs />
|
||||
|
||||
### 邮件服务(SMTP)
|
||||
|
||||
启用邮箱验证和密码重置功能需要配置以下设置。
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
reports
|
||||
screenshots
|
||||
-428
@@ -1,428 +0,0 @@
|
||||
# E2E Testing Guide for Claude
|
||||
|
||||
本文档记录了在 LobeHub E2E 测试开发中的经验和最佳实践。
|
||||
|
||||
Related: [LOBE-2417](https://linear.app/lobehub/issue/LOBE-2417/建立核心产品功能-e2e-测试体验基准线)
|
||||
|
||||
## 测试策略:体验驱动的 E2E 测试
|
||||
|
||||
### 核心理念
|
||||
|
||||
建立完整的**用户体验链路 E2E 测试**,作为未来变更和重构的**体验基准线**。
|
||||
|
||||
**目的**:
|
||||
|
||||
- 确保核心用户体验在代码变更后不会退化
|
||||
- 为重构提供安全网,敢于大胆改进代码
|
||||
- 从用户视角验证功能完整性
|
||||
|
||||
### 产品架构覆盖
|
||||
|
||||
| 模块 | 子功能 | 优先级 | 状态 |
|
||||
| ---------------- | -------------------- | ------ | ---- |
|
||||
| **Agent** | Builder, 对话,Task | P0 | 🚧 |
|
||||
| **Agent Group** | Builder, 群聊 | P1 | ⏳ |
|
||||
| **Page(文稿)** | 创建,编辑,分享 | P1 | ⏳ |
|
||||
| **知识库** | 创建,上传,RAG 对话 | P1 | ⏳ |
|
||||
| **记忆** | 查看,编辑,关联 | P2 | ⏳ |
|
||||
|
||||
### 标签系统
|
||||
|
||||
```gherkin
|
||||
@journey # 用户旅程测试(体验基准线)
|
||||
@smoke # 冒烟测试(快速验证)
|
||||
@regression # 回归测试
|
||||
|
||||
@P0 # 最高优先级(CI 必跑)
|
||||
@P1 # 高优先级(Nightly)
|
||||
@P2 # 中优先级(发版前)
|
||||
|
||||
@agent # Agent 模块
|
||||
@agent-group # Agent Group 模块
|
||||
@page # Page 文稿模块
|
||||
@knowledge # 知识库模块
|
||||
@memory # 记忆模块
|
||||
```
|
||||
|
||||
### 执行策略
|
||||
|
||||
```bash
|
||||
# CI - P0 冒烟测试(每次 PR)
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@smoke and @P0"
|
||||
|
||||
# Nightly - 所有用户旅程
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@journey"
|
||||
|
||||
# 发版前 - 完整回归
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@P0 or @P1"
|
||||
|
||||
# 完整测试
|
||||
pnpm exec cucumber-js --config cucumber.config.js
|
||||
```
|
||||
|
||||
### 测试设计原则
|
||||
|
||||
1. **按 CRUD + 核心交互覆盖**:每个模块覆盖创建、读取、更新、删除及核心交互流程
|
||||
2. **LLM 响应必须 Mock**:保证测试稳定性和可重复性
|
||||
3. **中文描述场景**:Feature 文件使用中文,贴近产品需求
|
||||
4. **优先级分层**:合理分配 P0/P1/P2,控制 CI 执行时间
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
e2e/
|
||||
├── src/
|
||||
│ ├── features/ # Cucumber feature 文件
|
||||
│ │ ├── journeys/ # 用户旅程(体验基准线)
|
||||
│ │ │ ├── agent/
|
||||
│ │ │ │ ├── agent-builder.feature
|
||||
│ │ │ │ ├── agent-conversation.feature ✅
|
||||
│ │ │ │ └── agent-task.feature
|
||||
│ │ │ ├── agent-group/
|
||||
│ │ │ │ ├── group-builder.feature
|
||||
│ │ │ │ └── group-chat.feature
|
||||
│ │ │ ├── page/
|
||||
│ │ │ │ └── page-crud.feature
|
||||
│ │ │ ├── knowledge/
|
||||
│ │ │ │ └── knowledge-rag.feature
|
||||
│ │ │ └── memory/
|
||||
│ │ │ └── memory-crud.feature
|
||||
│ │ ├── smoke/ # 冒烟测试
|
||||
│ │ │ └── discover/
|
||||
│ │ └── regression/ # 回归测试
|
||||
│ ├── steps/ # Step definitions
|
||||
│ │ ├── agent/ # Agent 相关 steps
|
||||
│ │ ├── common/ # 通用 steps (auth, navigation)
|
||||
│ │ └── hooks.ts # Before/After hooks
|
||||
│ ├── mocks/ # Mock 框架
|
||||
│ │ └── llm/ # LLM Mock (拦截 AI 请求) ✅
|
||||
│ └── support/ # 测试支持文件
|
||||
│ └── world.ts # CustomWorld 定义
|
||||
├── screenshots/ # 失败截图
|
||||
├── reports/ # 测试报告
|
||||
├── cucumber.config.js # Cucumber 配置
|
||||
└── CLAUDE.md # 本文档
|
||||
```
|
||||
|
||||
## 本地环境启动
|
||||
|
||||
> 详细流程参考 [e2e/docs/local-setup.md](./docs/local-setup.md)
|
||||
|
||||
### 快速启动流程
|
||||
|
||||
```bash
|
||||
# Step 1: 清理环境
|
||||
docker stop postgres-e2e 2> /dev/null; docker rm postgres-e2e 2> /dev/null
|
||||
lsof -ti:3006 | xargs kill -9 2> /dev/null
|
||||
lsof -ti:5433 | xargs kill -9 2> /dev/null
|
||||
|
||||
# Step 2: 启动数据库(使用 paradedb 镜像,支持 pgvector)
|
||||
docker run -d --name postgres-e2e \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-p 5433:5432 \
|
||||
paradedb/paradedb:latest
|
||||
|
||||
# 等待数据库就绪
|
||||
until docker exec postgres-e2e pg_isready; do sleep 2; done
|
||||
|
||||
# Step 3: 运行数据库迁移(项目根目录)
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
bun run db:migrate
|
||||
|
||||
# Step 4: 构建应用(首次或代码变更后)
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
|
||||
SKIP_LINT=1 \
|
||||
bun run build
|
||||
|
||||
# Step 5: 启动服务器(必须在项目根目录运行!)
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
|
||||
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
|
||||
S3_ACCESS_KEY_ID=e2e-mock-access-key \
|
||||
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
|
||||
S3_BUCKET=e2e-mock-bucket \
|
||||
S3_ENDPOINT=https://e2e-mock-s3.localhost \
|
||||
bunx next start -p 3006
|
||||
```
|
||||
|
||||
**重要提示**:
|
||||
|
||||
- 必须使用 `paradedb/paradedb:latest` 镜像(支持 pgvector 扩展)
|
||||
- 服务器必须在**项目根目录**启动,不能在 e2e 目录
|
||||
- S3 环境变量是**必需**的,即使不测试文件上传
|
||||
|
||||
## 运行测试
|
||||
|
||||
```bash
|
||||
# 从 e2e 目录运行
|
||||
cd e2e
|
||||
|
||||
# 运行特定标签的测试
|
||||
BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@AGENT-CHAT-001"
|
||||
|
||||
# 调试模式(显示浏览器)
|
||||
HEADLESS=false BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
|
||||
|
||||
# 运行所有测试
|
||||
BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js
|
||||
```
|
||||
|
||||
**重要**: 必须显式指定 `--config cucumber.config.js`,否则配置不会被正确加载。
|
||||
|
||||
## LLM Mock 实现
|
||||
|
||||
### 核心原理
|
||||
|
||||
LLM Mock 通过 Playwright 的 `page.route()` 拦截对 `/webapi/chat/openai` 的请求,返回预设的 SSE 流式响应。
|
||||
|
||||
### SSE 响应格式
|
||||
|
||||
LobeHub 使用特定的 SSE 格式,必须严格匹配:
|
||||
|
||||
```typescript
|
||||
// 1. 初始 data 事件
|
||||
id: msg_xxx
|
||||
event: data
|
||||
data: {"id":"msg_xxx","model":"gpt-4o-mini","role":"assistant","type":"message",...}
|
||||
|
||||
// 2. 文本内容分块(text 事件)
|
||||
id: msg_xxx
|
||||
event: text
|
||||
data: "Hello"
|
||||
|
||||
id: msg_xxx
|
||||
event: text
|
||||
data: "! I am"
|
||||
|
||||
// 3. 停止事件
|
||||
id: msg_xxx
|
||||
event: stop
|
||||
data: "end_turn"
|
||||
|
||||
// 4. 使用量统计
|
||||
id: msg_xxx
|
||||
event: usage
|
||||
data: {"totalTokens":100,...}
|
||||
|
||||
// 5. 最终停止
|
||||
id: msg_xxx
|
||||
event: stop
|
||||
data: "message_stop"
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```typescript
|
||||
import { llmMockManager, presetResponses } from '../../mocks/llm';
|
||||
|
||||
// 在测试步骤中设置 mock
|
||||
llmMockManager.setResponse('hello', presetResponses.greeting);
|
||||
await llmMockManager.setup(this.page);
|
||||
```
|
||||
|
||||
### 添加自定义响应
|
||||
|
||||
```typescript
|
||||
// 为特定用户消息设置响应
|
||||
llmMockManager.setResponse('你好', '你好!我是 Lobe AI,有什么可以帮助你的?');
|
||||
|
||||
// 清除所有自定义响应
|
||||
llmMockManager.clearResponses();
|
||||
```
|
||||
|
||||
## 页面元素定位技巧
|
||||
|
||||
### 富文本编辑器 (contenteditable) 输入
|
||||
|
||||
LobeHub 使用 `@lobehub/editor` 作为聊天输入框,是一个 contenteditable 的富文本编辑器。
|
||||
|
||||
**关键点**:
|
||||
|
||||
1. 不能直接用 `locator.fill()` - 对 contenteditable 不生效
|
||||
2. 需要先 click 容器让编辑器获得焦点
|
||||
3. 使用 `keyboard.type()` 输入文本
|
||||
|
||||
```typescript
|
||||
// 正确的输入方式
|
||||
await chatInputContainer.click();
|
||||
await this.page.waitForTimeout(500); // 等待焦点
|
||||
await this.page.keyboard.type(message, { delay: 30 });
|
||||
await this.page.keyboard.press('Enter'); // 发送
|
||||
```
|
||||
|
||||
### 添加 data-testid
|
||||
|
||||
为了更可靠的元素定位,可以在组件上添加 `data-testid`:
|
||||
|
||||
```tsx
|
||||
// src/features/ChatInput/Desktop/index.tsx
|
||||
<ChatInput
|
||||
data-testid="chat-input"
|
||||
...
|
||||
/>
|
||||
```
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 添加步骤日志
|
||||
|
||||
在每个关键步骤添加 console.log,帮助定位问题:
|
||||
|
||||
```typescript
|
||||
Given('用户进入页面', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 导航到首页...');
|
||||
await this.page.goto('/');
|
||||
|
||||
console.log(' 📍 Step: 查找元素...');
|
||||
const element = this.page.locator('...');
|
||||
|
||||
console.log(' ✅ 步骤完成');
|
||||
});
|
||||
```
|
||||
|
||||
### 查看失败截图
|
||||
|
||||
测试失败时会自动保存截图到 `e2e/screenshots/` 目录。
|
||||
|
||||
### 非 headless 模式
|
||||
|
||||
设置 `HEADLESS=false` 可以看到浏览器操作:
|
||||
|
||||
```bash
|
||||
HEADLESS=false pnpm exec cucumber-js --config cucumber.config.js --tags "@smoke"
|
||||
```
|
||||
|
||||
## 环境变量
|
||||
|
||||
运行测试需要以下环境变量:
|
||||
|
||||
```bash
|
||||
BASE_URL=http://localhost:3010 # 测试服务器地址
|
||||
DATABASE_URL=postgresql://... # 数据库连接
|
||||
DATABASE_DRIVER=node # 数据库驱动
|
||||
KEY_VAULTS_SECRET=... # 密钥
|
||||
BETTER_AUTH_SECRET=... # Auth 密钥
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 # 启用 Better Auth
|
||||
|
||||
# 可选:S3 相关(如果测试涉及文件上传)
|
||||
S3_ACCESS_KEY_ID=e2e-mock-access-key
|
||||
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key
|
||||
S3_BUCKET=e2e-mock-bucket
|
||||
S3_ENDPOINT=https://e2e-mock-s3.localhost
|
||||
```
|
||||
|
||||
## 清理环境
|
||||
|
||||
测试完成后或需要重置环境时,执行以下清理操作:
|
||||
|
||||
### 停止服务器
|
||||
|
||||
```bash
|
||||
# 查找并停止占用端口的进程
|
||||
lsof -ti:3006 | xargs kill -9 2> /dev/null
|
||||
lsof -ti:3010 | xargs kill -9 2> /dev/null
|
||||
```
|
||||
|
||||
### 停止 Docker 容器
|
||||
|
||||
```bash
|
||||
# 停止并删除 PostgreSQL 容器
|
||||
docker stop postgres-e2e 2> /dev/null
|
||||
docker rm postgres-e2e 2> /dev/null
|
||||
```
|
||||
|
||||
### 一键清理(推荐)
|
||||
|
||||
```bash
|
||||
# 清理所有 E2E 相关进程和容器
|
||||
docker stop postgres-e2e 2> /dev/null
|
||||
docker rm postgres-e2e 2> /dev/null
|
||||
lsof -ti:3006 | xargs kill -9 2> /dev/null
|
||||
lsof -ti:3010 | xargs kill -9 2> /dev/null
|
||||
lsof -ti:5433 | xargs kill -9 2> /dev/null
|
||||
echo "Cleanup done"
|
||||
```
|
||||
|
||||
### 清理端口占用
|
||||
|
||||
如果遇到端口被占用的错误,可以清理特定端口:
|
||||
|
||||
```bash
|
||||
# 清理 Next.js 服务器端口
|
||||
lsof -ti:3006 | xargs kill -9
|
||||
|
||||
# 清理 PostgreSQL 端口
|
||||
lsof -ti:5433 | xargs kill -9
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. 测试超时 (function timed out)
|
||||
|
||||
**原因**: 元素定位失败或等待时间不足
|
||||
|
||||
**解决**:
|
||||
|
||||
- 检查选择器是否正确
|
||||
- 增加 timeout 参数
|
||||
- 添加显式等待 `waitForTimeout()`
|
||||
|
||||
### 2. strict mode violation (多个元素匹配)
|
||||
|
||||
**原因**: 选择器匹配到多个元素(如 desktop/mobile 双组件)
|
||||
|
||||
**解决**:
|
||||
|
||||
- 使用 `.first()` 或 `.nth(n)`
|
||||
- 使用 `boundingBox()` 过滤可见元素
|
||||
|
||||
### 3. LLM Mock 未生效
|
||||
|
||||
**原因**: 路由拦截设置在页面导航之后
|
||||
|
||||
**解决**: 确保在 `page.goto()` 之前调用 `llmMockManager.setup(page)`
|
||||
|
||||
### 4. 输入框内容为空
|
||||
|
||||
**原因**: contenteditable 编辑器的特殊性
|
||||
|
||||
**解决**:
|
||||
|
||||
- 先 click 容器确保焦点
|
||||
- 使用 `keyboard.type()` 而非 `fill()`
|
||||
- 添加适当的等待时间
|
||||
|
||||
## 编写新测试的流程
|
||||
|
||||
1. **创建 Feature 文件** (`src/features/xxx/xxx.feature`)
|
||||
- 使用中文描述场景
|
||||
- 添加适当的标签 (@journey, @P0, @smoke 等)
|
||||
|
||||
2. **创建 Step Definitions** (`src/steps/xxx/xxx.steps.ts`)
|
||||
- 导入必要的 mock 和工具
|
||||
- 每个步骤添加日志
|
||||
- 处理元素定位的边界情况
|
||||
|
||||
3. **设置 Mock**(如需要)
|
||||
- 在 `src/mocks/` 下创建对应的 mock
|
||||
- 在步骤中初始化 mock
|
||||
|
||||
4. **调试和验证**
|
||||
- 先用 `HEADLESS=false` 运行观察
|
||||
- 检查失败截图
|
||||
- 确保稳定通过后再提交
|
||||
@@ -10,11 +10,11 @@ export default {
|
||||
formatOptions: {
|
||||
snippetInterface: 'async-await',
|
||||
},
|
||||
parallel: 1,
|
||||
parallel: process.env.CI ? 1 : 4,
|
||||
paths: ['src/features/**/*.feature'],
|
||||
publishQuiet: true,
|
||||
require: ['src/steps/**/*.ts', 'src/support/**/*.ts'],
|
||||
requireModule: ['tsx/cjs'],
|
||||
retry: 0,
|
||||
timeout: 30_000,
|
||||
timeout: 120_000,
|
||||
};
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
# LLM Mock 实现
|
||||
|
||||
## 核心原理
|
||||
|
||||
LLM Mock 通过 Playwright 的 `page.route()` 拦截对 `/webapi/chat/openai` 的请求,返回预设的 SSE 流式响应。
|
||||
|
||||
## SSE 响应格式
|
||||
|
||||
LobeHub 使用特定的 SSE 格式,必须严格匹配:
|
||||
|
||||
```
|
||||
// 1. 初始 data 事件
|
||||
id: msg_xxx
|
||||
event: data
|
||||
data: {"id":"msg_xxx","model":"gpt-4o-mini","role":"assistant","type":"message",...}
|
||||
|
||||
// 2. 文本内容分块(text 事件)
|
||||
id: msg_xxx
|
||||
event: text
|
||||
data: "Hello"
|
||||
|
||||
id: msg_xxx
|
||||
event: text
|
||||
data: "! I am"
|
||||
|
||||
// 3. 停止事件
|
||||
id: msg_xxx
|
||||
event: stop
|
||||
data: "end_turn"
|
||||
|
||||
// 4. 使用量统计
|
||||
id: msg_xxx
|
||||
event: usage
|
||||
data: {"totalTokens":100,...}
|
||||
|
||||
// 5. 最终停止
|
||||
id: msg_xxx
|
||||
event: stop
|
||||
data: "message_stop"
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
```typescript
|
||||
import { llmMockManager, presetResponses } from '../../mocks/llm';
|
||||
|
||||
// 在测试步骤中设置 mock
|
||||
llmMockManager.setResponse('hello', presetResponses.greeting);
|
||||
await llmMockManager.setup(this.page);
|
||||
```
|
||||
|
||||
## 添加自定义响应
|
||||
|
||||
```typescript
|
||||
// 为特定用户消息设置响应
|
||||
llmMockManager.setResponse('你好', '你好!我是 Lobe AI,有什么可以帮助你的?');
|
||||
|
||||
// 清除所有自定义响应
|
||||
llmMockManager.clearResponses();
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### LLM Mock 未生效
|
||||
|
||||
**原因**: 路由拦截设置在页面导航之后
|
||||
|
||||
**解决**: 确保在 `page.goto()` 之前调用 `llmMockManager.setup(page)`
|
||||
@@ -1,354 +0,0 @@
|
||||
# 本地运行 E2E 测试
|
||||
|
||||
## 前置要求
|
||||
|
||||
- Docker Desktop 已安装并**正在运行**
|
||||
- Node.js 18+
|
||||
- pnpm 已安装
|
||||
- 项目已 `pnpm install`
|
||||
|
||||
## 完整启动流程
|
||||
|
||||
### Step 0: 环境清理(重要!)
|
||||
|
||||
每次运行测试前,建议先清理环境,避免残留状态导致问题。
|
||||
|
||||
```bash
|
||||
# 0.1 确保 Docker Desktop 正在运行
|
||||
# 如果未运行,请先启动 Docker Desktop
|
||||
|
||||
# 0.2 清理旧的 PostgreSQL 容器
|
||||
docker stop postgres-e2e 2> /dev/null
|
||||
docker rm postgres-e2e 2> /dev/null
|
||||
|
||||
# 0.3 清理占用的端口
|
||||
lsof -ti:3006 | xargs kill -9 2> /dev/null # Next.js 服务器端口
|
||||
lsof -ti:5433 | xargs kill -9 2> /dev/null # PostgreSQL 端口
|
||||
```
|
||||
|
||||
### Step 1: 启动数据库
|
||||
|
||||
```bash
|
||||
# 启动 PostgreSQL (端口 5433)
|
||||
docker run -d --name postgres-e2e \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-p 5433:5432 \
|
||||
paradedb/paradedb:latest
|
||||
|
||||
# 等待数据库就绪
|
||||
until docker exec postgres-e2e pg_isready; do sleep 2; done
|
||||
echo "PostgreSQL is ready!"
|
||||
```
|
||||
|
||||
### Step 2: 运行数据库迁移
|
||||
|
||||
```bash
|
||||
# 在项目根目录运行
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
bun run db:migrate
|
||||
```
|
||||
|
||||
### Step 3: 构建应用(首次或代码变更后)
|
||||
|
||||
```bash
|
||||
# 在项目根目录运行
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
|
||||
SKIP_LINT=1 \
|
||||
bun run build
|
||||
```
|
||||
|
||||
### Step 4: 启动应用服务器
|
||||
|
||||
**重要**: 必须在**项目根目录**运行,不能在 e2e 目录运行!
|
||||
|
||||
```bash
|
||||
# 在项目根目录运行(注意:不是 e2e 目录)
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
|
||||
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
|
||||
S3_ACCESS_KEY_ID=e2e-mock-access-key \
|
||||
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
|
||||
S3_BUCKET=e2e-mock-bucket \
|
||||
S3_ENDPOINT=https://e2e-mock-s3.localhost \
|
||||
bunx next start -p 3006
|
||||
```
|
||||
|
||||
### Step 5: 等待服务器就绪
|
||||
|
||||
```bash
|
||||
# 在另一个终端运行,确认服务器已启动
|
||||
until curl -s http://localhost:3006 > /dev/null; do
|
||||
sleep 2
|
||||
echo "Waiting..."
|
||||
done
|
||||
echo "Server is ready!"
|
||||
```
|
||||
|
||||
### Step 6: 运行测试
|
||||
|
||||
```bash
|
||||
# 在 e2e 目录运行测试
|
||||
cd e2e
|
||||
|
||||
# 运行特定标签(默认无头模式)
|
||||
BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
|
||||
|
||||
# 运行所有测试
|
||||
BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js
|
||||
|
||||
# 调试模式(显示浏览器,观察执行过程)
|
||||
HEADLESS=false \
|
||||
BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
|
||||
```
|
||||
|
||||
## 一键启动脚本
|
||||
|
||||
### 完整初始化(首次运行或需要重建)
|
||||
|
||||
在项目根目录创建 `e2e-init.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "🧹 Step 0: Cleaning up..."
|
||||
docker stop postgres-e2e 2> /dev/null || true
|
||||
docker rm postgres-e2e 2> /dev/null || true
|
||||
lsof -ti:3006 | xargs kill -9 2> /dev/null || true
|
||||
lsof -ti:5433 | xargs kill -9 2> /dev/null || true
|
||||
|
||||
echo "🐘 Step 1: Starting PostgreSQL..."
|
||||
docker run -d --name postgres-e2e \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-p 5433:5432 \
|
||||
paradedb/paradedb:latest
|
||||
|
||||
echo "⏳ Waiting for PostgreSQL..."
|
||||
until docker exec postgres-e2e pg_isready 2> /dev/null; do sleep 2; done
|
||||
echo "✅ PostgreSQL is ready!"
|
||||
|
||||
echo "🔄 Step 2: Running migrations..."
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
bun run db:migrate
|
||||
|
||||
echo "🔨 Step 3: Building application..."
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
|
||||
SKIP_LINT=1 \
|
||||
bun run build
|
||||
|
||||
echo "✅ Initialization complete! Now run e2e-start.sh to start the server."
|
||||
```
|
||||
|
||||
### 快速启动服务器
|
||||
|
||||
在项目根目录创建 `e2e-start.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "🧹 Cleaning up ports..."
|
||||
lsof -ti:3006 | xargs kill -9 2> /dev/null || true
|
||||
|
||||
echo "🚀 Starting Next.js server on port 3006..."
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
|
||||
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
|
||||
S3_ACCESS_KEY_ID=e2e-mock-access-key \
|
||||
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
|
||||
S3_BUCKET=e2e-mock-bucket \
|
||||
S3_ENDPOINT=https://e2e-mock-s3.localhost \
|
||||
bunx next start -p 3006
|
||||
```
|
||||
|
||||
### 运行测试
|
||||
|
||||
在 e2e 目录创建 `run-test.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# 默认参数
|
||||
TAGS="${1:-@journey}"
|
||||
HEADLESS="${HEADLESS:-true}" # 默认无头模式
|
||||
|
||||
echo "🧪 Running E2E tests with tags: $TAGS"
|
||||
echo " Headless: $HEADLESS"
|
||||
|
||||
HEADLESS=$HEADLESS \
|
||||
BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "$TAGS"
|
||||
```
|
||||
|
||||
使用方式:
|
||||
|
||||
```bash
|
||||
# 运行特定标签(默认无头模式)
|
||||
./run-test.sh "@conversation"
|
||||
|
||||
# 调试模式(显示浏览器)
|
||||
HEADLESS=false ./run-test.sh "@conversation"
|
||||
```
|
||||
|
||||
## 快速启动(假设数据库和构建已完成)
|
||||
|
||||
```bash
|
||||
# Terminal 1: 启动服务器(项目根目录)
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
DATABASE_DRIVER=node \
|
||||
KEY_VAULTS_SECRET=LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s= \
|
||||
BETTER_AUTH_SECRET=e2e-test-secret-key-for-better-auth-32chars! \
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH=1 \
|
||||
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION=0 \
|
||||
S3_ACCESS_KEY_ID=e2e-mock-access-key \
|
||||
S3_SECRET_ACCESS_KEY=e2e-mock-secret-key \
|
||||
S3_BUCKET=e2e-mock-bucket \
|
||||
S3_ENDPOINT=https://e2e-mock-s3.localhost \
|
||||
bunx next start -p 3006
|
||||
|
||||
# Terminal 2: 运行测试(e2e 目录,默认无头模式)
|
||||
cd e2e
|
||||
BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
|
||||
|
||||
# 调试模式(显示浏览器)
|
||||
HEADLESS=false BASE_URL=http://localhost:3006 \
|
||||
DATABASE_URL=postgresql://postgres:postgres@localhost:5433/postgres \
|
||||
pnpm exec cucumber-js --config cucumber.config.js --tags "@conversation"
|
||||
```
|
||||
|
||||
## 环境变量参考
|
||||
|
||||
### 测试运行时环境变量
|
||||
|
||||
| 变量 | 值 | 说明 |
|
||||
| -------------- | -------------------------------------------------------- | --------------------------------------------------- |
|
||||
| `BASE_URL` | `http://localhost:3006` | 测试服务器地址 |
|
||||
| `DATABASE_URL` | `postgresql://postgres:postgres@localhost:5433/postgres` | 数据库连接 |
|
||||
| `HEADLESS` | `true`(默认)/`false` | 是否无头模式运行浏览器,设为 `false` 可观察执行过程 |
|
||||
|
||||
### 服务器启动环境变量(全部必需)
|
||||
|
||||
| 变量 | 值 | 说明 |
|
||||
| ------------------------------------- | -------------------------------------------------------- | ---------------- |
|
||||
| `DATABASE_URL` | `postgresql://postgres:postgres@localhost:5433/postgres` | 数据库连接 |
|
||||
| `DATABASE_DRIVER` | `node` | 数据库驱动 |
|
||||
| `KEY_VAULTS_SECRET` | `LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=` | 密钥保险库密钥 |
|
||||
| `BETTER_AUTH_SECRET` | `e2e-test-secret-key-for-better-auth-32chars!` | 认证密钥 |
|
||||
| `NEXT_PUBLIC_ENABLE_BETTER_AUTH` | `1` | 启用 Better Auth |
|
||||
| `NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION` | `0` | 禁用邮箱验证 |
|
||||
|
||||
### S3 Mock 变量(必需!)
|
||||
|
||||
| 变量 | 值 |
|
||||
| ---------------------- | ------------------------------- |
|
||||
| `S3_ACCESS_KEY_ID` | `e2e-mock-access-key` |
|
||||
| `S3_SECRET_ACCESS_KEY` | `e2e-mock-secret-key` |
|
||||
| `S3_BUCKET` | `e2e-mock-bucket` |
|
||||
| `S3_ENDPOINT` | `https://e2e-mock-s3.localhost` |
|
||||
|
||||
**注意**: S3 环境变量是**必需**的,即使不测试文件上传功能。缺少这些变量会导致发送消息时报错 "S3 environment variables are not set completely"。
|
||||
|
||||
## 常见问题排查
|
||||
|
||||
### Docker daemon is not running
|
||||
|
||||
**症状**: `Cannot connect to the Docker daemon`
|
||||
|
||||
**解决**: 启动 Docker Desktop 应用
|
||||
|
||||
### PostgreSQL 容器已存在
|
||||
|
||||
**症状**: `docker: Error response from daemon: Conflict. The container name "/postgres-e2e" is already in use`
|
||||
|
||||
**解决**:
|
||||
|
||||
```bash
|
||||
docker stop postgres-e2e
|
||||
docker rm postgres-e2e
|
||||
```
|
||||
|
||||
### S3 environment variables are not set completely
|
||||
|
||||
**原因**: 服务器启动时缺少 S3 环境变量
|
||||
|
||||
**解决**: 启动服务器时必须设置所有 S3 mock 变量
|
||||
|
||||
### Cannot find module './src/libs/next/config/define-config'
|
||||
|
||||
**原因**: 在 e2e 目录下运行 `next start`
|
||||
|
||||
**解决**: 必须在**项目根目录**运行 `bunx next start`,不能在 e2e 目录运行
|
||||
|
||||
### EADDRINUSE: address already in use
|
||||
|
||||
**原因**: 端口被占用
|
||||
|
||||
**解决**:
|
||||
|
||||
```bash
|
||||
# 查找并杀掉占用端口的进程
|
||||
lsof -ti:3006 | xargs kill -9
|
||||
lsof -ti:5433 | xargs kill -9
|
||||
```
|
||||
|
||||
### BeforeAll hook errored: net::ERR_CONNECTION_REFUSED
|
||||
|
||||
**原因**: 服务器未启动或未就绪
|
||||
|
||||
**解决**:
|
||||
|
||||
1. 确认服务器已启动:`curl http://localhost:3006`
|
||||
2. 确认 `BASE_URL` 环境变量设置正确
|
||||
3. 等待服务器完全就绪后再运行测试
|
||||
|
||||
### 测试超时或不稳定
|
||||
|
||||
**可能原因**:
|
||||
|
||||
1. 网络延迟
|
||||
2. 服务器响应慢
|
||||
3. 元素定位问题
|
||||
|
||||
**解决**:
|
||||
|
||||
1. 使用 `HEADLESS=false` 观察测试执行过程
|
||||
2. 检查 `screenshots/` 目录中的失败截图
|
||||
3. 增加等待时间或使用更稳定的定位器
|
||||
|
||||
## 清理环境
|
||||
|
||||
测试完成后,清理环境:
|
||||
|
||||
```bash
|
||||
# 停止服务器
|
||||
lsof -ti:3006 | xargs kill -9
|
||||
|
||||
# 停止并删除 PostgreSQL 容器
|
||||
docker stop postgres-e2e
|
||||
docker rm postgres-e2e
|
||||
```
|
||||
@@ -1,94 +0,0 @@
|
||||
# 测试技巧
|
||||
|
||||
## 页面元素定位
|
||||
|
||||
### 富文本编辑器 (contenteditable) 输入
|
||||
|
||||
LobeHub 使用 `@lobehub/editor` 作为聊天输入框,是一个 contenteditable 的富文本编辑器。
|
||||
|
||||
**关键点**:
|
||||
|
||||
1. 不能直接用 `locator.fill()` - 对 contenteditable 不生效
|
||||
2. 需要先 click 容器让编辑器获得焦点
|
||||
3. 使用 `keyboard.type()` 输入文本
|
||||
|
||||
```typescript
|
||||
// 正确的输入方式
|
||||
await chatInputContainer.click();
|
||||
await this.page.waitForTimeout(500); // 等待焦点
|
||||
await this.page.keyboard.type(message, { delay: 30 });
|
||||
await this.page.keyboard.press('Enter'); // 发送
|
||||
```
|
||||
|
||||
### 添加 data-testid
|
||||
|
||||
为了更可靠的元素定位,可以在组件上添加 `data-testid`:
|
||||
|
||||
```tsx
|
||||
// src/features/ChatInput/Desktop/index.tsx
|
||||
<ChatInput
|
||||
data-testid="chat-input"
|
||||
...
|
||||
/>
|
||||
```
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 添加步骤日志
|
||||
|
||||
在每个关键步骤添加 console.log,帮助定位问题:
|
||||
|
||||
```typescript
|
||||
Given('用户进入页面', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 导航到首页...');
|
||||
await this.page.goto('/');
|
||||
|
||||
console.log(' 📍 Step: 查找元素...');
|
||||
const element = this.page.locator('...');
|
||||
|
||||
console.log(' ✅ 步骤完成');
|
||||
});
|
||||
```
|
||||
|
||||
### 查看失败截图
|
||||
|
||||
测试失败时会自动保存截图到 `e2e/screenshots/` 目录。
|
||||
|
||||
### 非 headless 模式
|
||||
|
||||
设置 `HEADLESS=false` 可以看到浏览器操作:
|
||||
|
||||
```bash
|
||||
HEADLESS=false pnpm exec cucumber-js --config cucumber.config.js --tags "@smoke"
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 测试超时 (function timed out)
|
||||
|
||||
**原因**: 元素定位失败或等待时间不足
|
||||
|
||||
**解决**:
|
||||
|
||||
- 检查选择器是否正确
|
||||
- 增加 timeout 参数
|
||||
- 添加显式等待 `waitForTimeout()`
|
||||
|
||||
### strict mode violation (多个元素匹配)
|
||||
|
||||
**原因**: 选择器匹配到多个元素(如 desktop/mobile 双组件)
|
||||
|
||||
**解决**:
|
||||
|
||||
- 使用 `.first()` 或 `.nth(n)`
|
||||
- 使用 `boundingBox()` 过滤可见元素
|
||||
|
||||
### 输入框内容为空
|
||||
|
||||
**原因**: contenteditable 编辑器的特殊性
|
||||
|
||||
**解决**:
|
||||
|
||||
- 先 click 容器确保焦点
|
||||
- 使用 `keyboard.type()` 而非 `fill()`
|
||||
- 添加适当的等待时间
|
||||
@@ -4,9 +4,7 @@
|
||||
"private": true,
|
||||
"description": "E2E tests for LobeChat using Cucumber and Playwright",
|
||||
"scripts": {
|
||||
"build": "cd .. && bun run build",
|
||||
"test": "cucumber-js --config cucumber.config.js",
|
||||
"test:ci": "bun run build && bun run test",
|
||||
"test:discover": "cucumber-js --config cucumber.config.js src/features/discover/",
|
||||
"test:headed": "HEADLESS=false cucumber-js --config cucumber.config.js",
|
||||
"test:routes": "cucumber-js --config cucumber.config.js --tags '@routes'",
|
||||
@@ -16,8 +14,6 @@
|
||||
"dependencies": {
|
||||
"@cucumber/cucumber": "^12.2.0",
|
||||
"@playwright/test": "^1.57.0",
|
||||
"bcryptjs": "^3.0.3",
|
||||
"pg": "^8.16.0",
|
||||
"playwright": "^1.57.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -11,7 +11,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-001 @P1
|
||||
Scenario: Load assistant detail page and verify content
|
||||
Given I navigate to "/community/assistant"
|
||||
Given I navigate to "/discover/assistant"
|
||||
And I wait for the page to fully load
|
||||
When I click on the first assistant card
|
||||
Then I should be on an assistant detail page
|
||||
@@ -22,7 +22,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-002 @P1
|
||||
Scenario: Navigate back from assistant detail page
|
||||
Given I navigate to "/community/assistant"
|
||||
Given I navigate to "/discover/assistant"
|
||||
And I wait for the page to fully load
|
||||
And I click on the first assistant card
|
||||
When I click the back button
|
||||
@@ -34,7 +34,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-003 @P1
|
||||
Scenario: Load model detail page and verify content
|
||||
Given I navigate to "/community/model"
|
||||
Given I navigate to "/discover/model"
|
||||
And I wait for the page to fully load
|
||||
When I click on the first model card
|
||||
Then I should be on a model detail page
|
||||
@@ -44,7 +44,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-004 @P1
|
||||
Scenario: Navigate back from model detail page
|
||||
Given I navigate to "/community/model"
|
||||
Given I navigate to "/discover/model"
|
||||
And I wait for the page to fully load
|
||||
And I click on the first model card
|
||||
When I click the back button
|
||||
@@ -56,7 +56,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-005 @P1
|
||||
Scenario: Load provider detail page and verify content
|
||||
Given I navigate to "/community/provider"
|
||||
Given I navigate to "/discover/provider"
|
||||
And I wait for the page to fully load
|
||||
When I click on the first provider card
|
||||
Then I should be on a provider detail page
|
||||
@@ -66,7 +66,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-006 @P1
|
||||
Scenario: Navigate back from provider detail page
|
||||
Given I navigate to "/community/provider"
|
||||
Given I navigate to "/discover/provider"
|
||||
And I wait for the page to fully load
|
||||
And I click on the first provider card
|
||||
When I click the back button
|
||||
@@ -78,7 +78,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-007 @P1
|
||||
Scenario: Load MCP detail page and verify content
|
||||
Given I navigate to "/community/mcp"
|
||||
Given I navigate to "/discover/mcp"
|
||||
And I wait for the page to fully load
|
||||
When I click on the first MCP card
|
||||
Then I should be on an MCP detail page
|
||||
@@ -88,7 +88,7 @@ Feature: Discover Detail Pages
|
||||
|
||||
@DISCOVER-DETAIL-008 @P1
|
||||
Scenario: Navigate back from MCP detail page
|
||||
Given I navigate to "/community/mcp"
|
||||
Given I navigate to "/discover/mcp"
|
||||
And I wait for the page to fully load
|
||||
And I click on the first MCP card
|
||||
When I click the back button
|
||||
|
||||
@@ -11,14 +11,14 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-001 @P1
|
||||
Scenario: Search for assistants
|
||||
Given I navigate to "/community/assistant"
|
||||
Given I navigate to "/discover/assistant"
|
||||
When I type "developer" in the search bar
|
||||
And I wait for the search results to load
|
||||
Then I should see filtered assistant cards
|
||||
|
||||
@DISCOVER-INTERACT-002 @P1
|
||||
Scenario: Filter assistants by category
|
||||
Given I navigate to "/community/assistant"
|
||||
Given I navigate to "/discover/assistant"
|
||||
When I click on a category in the category menu
|
||||
And I wait for the filtered results to load
|
||||
Then I should see assistant cards filtered by the selected category
|
||||
@@ -26,7 +26,7 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-003 @P1
|
||||
Scenario: Navigate to next page of assistants
|
||||
Given I navigate to "/community/assistant"
|
||||
Given I navigate to "/discover/assistant"
|
||||
When I click the next page button
|
||||
And I wait for the next page to load
|
||||
Then I should see different assistant cards
|
||||
@@ -34,7 +34,7 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-004 @P1
|
||||
Scenario: Navigate to assistant detail page
|
||||
Given I navigate to "/community/assistant"
|
||||
Given I navigate to "/discover/assistant"
|
||||
When I click on the first assistant card
|
||||
Then I should be navigated to the assistant detail page
|
||||
And I should see the assistant detail content
|
||||
@@ -45,7 +45,7 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-005 @P1
|
||||
Scenario: Sort models
|
||||
Given I navigate to "/community/model"
|
||||
Given I navigate to "/discover/model"
|
||||
When I click on the sort dropdown
|
||||
And I select a sort option
|
||||
And I wait for the sorted results to load
|
||||
@@ -53,7 +53,7 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-006 @P1
|
||||
Scenario: Navigate to model detail page
|
||||
Given I navigate to "/community/model"
|
||||
Given I navigate to "/discover/model"
|
||||
When I click on the first model card
|
||||
Then I should be navigated to the model detail page
|
||||
And I should see the model detail content
|
||||
@@ -64,7 +64,7 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-007 @P1
|
||||
Scenario: Navigate to provider detail page
|
||||
Given I navigate to "/community/provider"
|
||||
Given I navigate to "/discover/provider"
|
||||
When I click on the first provider card
|
||||
Then I should be navigated to the provider detail page
|
||||
And I should see the provider detail content
|
||||
@@ -75,14 +75,14 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-008 @P1
|
||||
Scenario: Filter MCP tools by category
|
||||
Given I navigate to "/community/mcp"
|
||||
Given I navigate to "/discover/mcp"
|
||||
When I click on a category in the category filter
|
||||
And I wait for the filtered results to load
|
||||
Then I should see MCP cards filtered by the selected category
|
||||
|
||||
@DISCOVER-INTERACT-009 @P1
|
||||
Scenario: Navigate to MCP detail page
|
||||
Given I navigate to "/community/mcp"
|
||||
Given I navigate to "/discover/mcp"
|
||||
When I click on the first MCP card
|
||||
Then I should be navigated to the MCP detail page
|
||||
And I should see the MCP detail content
|
||||
@@ -93,21 +93,21 @@ Feature: Discover Interactions
|
||||
|
||||
@DISCOVER-INTERACT-010 @P1
|
||||
Scenario: Navigate from home to assistant list
|
||||
Given I navigate to "/community"
|
||||
Given I navigate to "/discover"
|
||||
When I click on the "more" link in the featured assistants section
|
||||
Then I should be navigated to "/community/assistant"
|
||||
Then I should be navigated to "/discover/assistant"
|
||||
And I should see the page body
|
||||
|
||||
@DISCOVER-INTERACT-011 @P1
|
||||
Scenario: Navigate from home to MCP list
|
||||
Given I navigate to "/community"
|
||||
Given I navigate to "/discover"
|
||||
When I click on the "more" link in the featured MCP tools section
|
||||
Then I should be navigated to "/community/mcp"
|
||||
Then I should be navigated to "/discover/mcp"
|
||||
And I should see the page body
|
||||
|
||||
@DISCOVER-INTERACT-012 @P1
|
||||
Scenario: Click featured assistant from home
|
||||
Given I navigate to "/community"
|
||||
Given I navigate to "/discover"
|
||||
When I click on the first featured assistant card
|
||||
Then I should be navigated to the assistant detail page
|
||||
And I should see the assistant detail content
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
@discover @smoke
|
||||
Feature: Community Smoke Tests
|
||||
Critical path tests to ensure the community/discover module is functional
|
||||
Feature: Discover Smoke Tests
|
||||
Critical path tests to ensure the discover module is functional
|
||||
|
||||
@DISCOVER-SMOKE-001 @P0
|
||||
Scenario: Load Community Home Page
|
||||
Given I navigate to "/community"
|
||||
Scenario: Load Discover Home Page
|
||||
Given I navigate to "/discover"
|
||||
Then the page should load without errors
|
||||
And I should see the page body
|
||||
And I should see the featured assistants section
|
||||
@@ -12,7 +12,7 @@ Feature: Community Smoke Tests
|
||||
|
||||
@DISCOVER-SMOKE-002 @P0
|
||||
Scenario: Load Assistant List Page
|
||||
Given I navigate to "/community/assistant"
|
||||
Given I navigate to "/discover/assistant"
|
||||
Then the page should load without errors
|
||||
And I should see the page body
|
||||
And I should see the search bar
|
||||
@@ -22,7 +22,7 @@ Feature: Community Smoke Tests
|
||||
|
||||
@DISCOVER-SMOKE-003 @P0
|
||||
Scenario: Load Model List Page
|
||||
Given I navigate to "/community/model"
|
||||
Given I navigate to "/discover/model"
|
||||
Then the page should load without errors
|
||||
And I should see the page body
|
||||
And I should see model cards
|
||||
@@ -30,14 +30,14 @@ Feature: Community Smoke Tests
|
||||
|
||||
@DISCOVER-SMOKE-004 @P0
|
||||
Scenario: Load Provider List Page
|
||||
Given I navigate to "/community/provider"
|
||||
Given I navigate to "/discover/provider"
|
||||
Then the page should load without errors
|
||||
And I should see the page body
|
||||
And I should see provider cards
|
||||
|
||||
@DISCOVER-SMOKE-005 @P0
|
||||
Scenario: Load MCP List Page
|
||||
Given I navigate to "/community/mcp"
|
||||
Given I navigate to "/discover/mcp"
|
||||
Then the page should load without errors
|
||||
And I should see the page body
|
||||
And I should see MCP cards
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
@journey @agent @conversation-mgmt
|
||||
Feature: Agent 对话管理用户体验链路
|
||||
作为用户,我希望能够管理我的对话历史
|
||||
|
||||
Background:
|
||||
Given 用户已登录系统
|
||||
And 用户进入 Lobe AI 对话页面
|
||||
|
||||
@AGENT-CONV-001 @P0
|
||||
Scenario: 创建新对话
|
||||
Given 用户已有一个对话
|
||||
When 用户点击新建对话按钮
|
||||
Then 应该创建一个新的空白对话
|
||||
And 页面应该显示欢迎界面
|
||||
|
||||
@AGENT-CONV-002 @P0
|
||||
Scenario: 切换不同对话
|
||||
Given 用户有多个对话历史
|
||||
When 用户点击另一个对话
|
||||
Then 应该切换到该对话
|
||||
And 显示该对话的历史消息
|
||||
|
||||
@AGENT-CONV-003 @P0
|
||||
Scenario: 重命名对话
|
||||
Given 用户已有一个对话
|
||||
When 用户右键点击对话
|
||||
And 用户选择重命名选项
|
||||
And 用户输入新的对话名称 "测试对话"
|
||||
Then 对话名称应该更新为 "测试对话"
|
||||
|
||||
@AGENT-CONV-004 @P0
|
||||
Scenario: 删除对话
|
||||
Given 用户有多个对话历史
|
||||
When 用户右键点击一个对话
|
||||
And 用户选择删除选项
|
||||
And 用户确认删除
|
||||
Then 该对话应该被删除
|
||||
And 对话列表中不再显示该对话
|
||||
|
||||
@AGENT-CONV-005 @P1
|
||||
Scenario: 搜索历史对话
|
||||
Given 用户有多个对话历史
|
||||
When 用户在搜索框中输入 "测试"
|
||||
Then 应该显示包含 "测试" 的对话
|
||||
And 不相关的对话应该被过滤
|
||||
@@ -1,13 +0,0 @@
|
||||
@journey @agent @conversation
|
||||
Feature: Agent 对话用户体验链路
|
||||
作为用户,我希望能够与 AI 助手进行流畅的对话
|
||||
|
||||
Background:
|
||||
Given 用户已登录系统
|
||||
|
||||
@AGENT-CHAT-001 @P0 @smoke
|
||||
Scenario: 使用 Lobe AI 发送消息并获得回复
|
||||
Given 用户进入 Lobe AI 对话页面
|
||||
When 用户发送消息 "hello"
|
||||
Then 用户应该收到助手的回复
|
||||
And 回复内容应该可见
|
||||
@@ -1,36 +0,0 @@
|
||||
@journey @agent @message-ops
|
||||
Feature: Agent 消息操作用户体验链路
|
||||
作为用户,我希望能够对消息进行各种操作
|
||||
|
||||
Background:
|
||||
Given 用户已登录系统
|
||||
And 用户进入 Lobe AI 对话页面
|
||||
And 用户已发送消息 "hello"
|
||||
|
||||
@AGENT-MSG-001 @P1
|
||||
Scenario: 复制消息内容
|
||||
When 用户点击消息的复制按钮
|
||||
Then 消息内容应该被复制到剪贴板
|
||||
|
||||
@AGENT-MSG-002 @P1
|
||||
Scenario: 编辑助手消息
|
||||
When 用户点击助手消息的编辑按钮
|
||||
And 用户修改消息内容为 "这是编辑后的内容"
|
||||
And 用户保存编辑
|
||||
Then 消息内容应该更新为 "这是编辑后的内容"
|
||||
|
||||
@AGENT-MSG-003 @P1
|
||||
Scenario: 删除单条消息
|
||||
When 用户点击消息的更多操作按钮
|
||||
And 用户选择删除消息选项
|
||||
And 用户确认删除消息
|
||||
Then 该消息应该从对话中移除
|
||||
|
||||
@AGENT-MSG-004 @P1
|
||||
Scenario: 折叠和展开消息
|
||||
When 用户点击消息的更多操作按钮
|
||||
And 用户选择折叠消息选项
|
||||
Then 消息内容应该被折叠
|
||||
When 用户点击消息的更多操作按钮
|
||||
And 用户选择展开消息选项
|
||||
Then 消息内容应该完整显示
|
||||
@@ -1,212 +0,0 @@
|
||||
/**
|
||||
* Mock data for Discover/Community module
|
||||
*/
|
||||
import type {
|
||||
AssistantListResponse,
|
||||
McpListResponse,
|
||||
ModelListResponse,
|
||||
ProviderListResponse,
|
||||
} from './types';
|
||||
|
||||
// ============================================
|
||||
// Assistant Mock Data
|
||||
// ============================================
|
||||
|
||||
export const mockAssistantList: AssistantListResponse = {
|
||||
items: [
|
||||
{
|
||||
author: 'LobeHub',
|
||||
avatar: '🤖',
|
||||
backgroundColor: '#1890ff',
|
||||
category: 'general',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
description: 'A versatile AI assistant for general tasks and conversations.',
|
||||
identifier: 'general-assistant',
|
||||
installCount: 1000,
|
||||
knowledgeCount: 5,
|
||||
pluginCount: 3,
|
||||
title: 'General Assistant',
|
||||
tokenUsage: 4096,
|
||||
userName: 'lobehub',
|
||||
},
|
||||
{
|
||||
author: 'LobeHub',
|
||||
avatar: '💻',
|
||||
backgroundColor: '#52c41a',
|
||||
category: 'programming',
|
||||
createdAt: '2024-01-02T00:00:00.000Z',
|
||||
description: 'Expert coding assistant for software development.',
|
||||
identifier: 'code-assistant',
|
||||
installCount: 800,
|
||||
knowledgeCount: 10,
|
||||
pluginCount: 5,
|
||||
title: 'Code Assistant',
|
||||
tokenUsage: 8192,
|
||||
userName: 'lobehub',
|
||||
},
|
||||
{
|
||||
author: 'LobeHub',
|
||||
avatar: '✍️',
|
||||
backgroundColor: '#722ed1',
|
||||
category: 'copywriting',
|
||||
createdAt: '2024-01-03T00:00:00.000Z',
|
||||
description: 'Professional writing assistant for content creation.',
|
||||
identifier: 'writing-assistant',
|
||||
installCount: 600,
|
||||
knowledgeCount: 3,
|
||||
pluginCount: 2,
|
||||
title: 'Writing Assistant',
|
||||
tokenUsage: 4096,
|
||||
userName: 'lobehub',
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
total: 3,
|
||||
totalPages: 1,
|
||||
},
|
||||
};
|
||||
|
||||
export const mockAssistantCategories = [
|
||||
{ id: 'general', name: 'General' },
|
||||
{ id: 'programming', name: 'Programming' },
|
||||
{ id: 'copywriting', name: 'Copywriting' },
|
||||
{ id: 'education', name: 'Education' },
|
||||
];
|
||||
|
||||
// ============================================
|
||||
// Model Mock Data
|
||||
// ============================================
|
||||
|
||||
export const mockModelList: ModelListResponse = {
|
||||
items: [
|
||||
{
|
||||
abilities: { functionCall: true, reasoning: true, vision: true },
|
||||
contextWindowTokens: 128_000,
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
description: 'Most capable model for complex tasks',
|
||||
displayName: 'GPT-4o',
|
||||
id: 'gpt-4o',
|
||||
providerId: 'openai',
|
||||
providerName: 'OpenAI',
|
||||
type: 'chat',
|
||||
},
|
||||
{
|
||||
abilities: { functionCall: true, reasoning: true, vision: false },
|
||||
contextWindowTokens: 200_000,
|
||||
createdAt: '2024-01-02T00:00:00.000Z',
|
||||
description: 'Advanced AI assistant by Anthropic',
|
||||
displayName: 'Claude 3.5 Sonnet',
|
||||
id: 'claude-3-5-sonnet-20241022',
|
||||
providerId: 'anthropic',
|
||||
providerName: 'Anthropic',
|
||||
type: 'chat',
|
||||
},
|
||||
{
|
||||
abilities: { functionCall: false, reasoning: false, vision: false },
|
||||
contextWindowTokens: 32_768,
|
||||
createdAt: '2024-01-03T00:00:00.000Z',
|
||||
description: 'Open source language model',
|
||||
displayName: 'Llama 3.1 70B',
|
||||
id: 'llama-3.1-70b',
|
||||
providerId: 'meta',
|
||||
providerName: 'Meta',
|
||||
type: 'chat',
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
total: 3,
|
||||
totalPages: 1,
|
||||
},
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// Provider Mock Data
|
||||
// ============================================
|
||||
|
||||
export const mockProviderList: ProviderListResponse = {
|
||||
items: [
|
||||
{
|
||||
description: 'Leading AI research company',
|
||||
id: 'openai',
|
||||
logo: 'https://example.com/openai.png',
|
||||
modelCount: 10,
|
||||
name: 'OpenAI',
|
||||
},
|
||||
{
|
||||
description: 'AI safety focused research company',
|
||||
id: 'anthropic',
|
||||
logo: 'https://example.com/anthropic.png',
|
||||
modelCount: 5,
|
||||
name: 'Anthropic',
|
||||
},
|
||||
{
|
||||
description: 'Open source AI leader',
|
||||
id: 'meta',
|
||||
logo: 'https://example.com/meta.png',
|
||||
modelCount: 8,
|
||||
name: 'Meta',
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
total: 3,
|
||||
totalPages: 1,
|
||||
},
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// MCP Mock Data
|
||||
// ============================================
|
||||
|
||||
export const mockMcpList: McpListResponse = {
|
||||
items: [
|
||||
{
|
||||
author: 'LobeHub',
|
||||
avatar: '🔍',
|
||||
category: 'search',
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
description: 'Web search capabilities for AI assistants',
|
||||
identifier: 'web-search',
|
||||
installCount: 500,
|
||||
title: 'Web Search',
|
||||
},
|
||||
{
|
||||
author: 'LobeHub',
|
||||
avatar: '📁',
|
||||
category: 'file',
|
||||
createdAt: '2024-01-02T00:00:00.000Z',
|
||||
description: 'File system operations and management',
|
||||
identifier: 'file-manager',
|
||||
installCount: 300,
|
||||
title: 'File Manager',
|
||||
},
|
||||
{
|
||||
author: 'LobeHub',
|
||||
avatar: '🗄️',
|
||||
category: 'database',
|
||||
createdAt: '2024-01-03T00:00:00.000Z',
|
||||
description: 'Database query and management tools',
|
||||
identifier: 'db-tools',
|
||||
installCount: 200,
|
||||
title: 'Database Tools',
|
||||
},
|
||||
],
|
||||
pagination: {
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
total: 3,
|
||||
totalPages: 1,
|
||||
},
|
||||
};
|
||||
|
||||
export const mockMcpCategories = [
|
||||
{ id: 'search', name: 'Search' },
|
||||
{ id: 'file', name: 'File' },
|
||||
{ id: 'database', name: 'Database' },
|
||||
{ id: 'utility', name: 'Utility' },
|
||||
];
|
||||
@@ -1,179 +0,0 @@
|
||||
/**
|
||||
* Mock handlers for Discover/Community API endpoints
|
||||
*/
|
||||
import type { Route } from 'playwright';
|
||||
|
||||
import { type MockHandler, createTrpcResponse } from '../index';
|
||||
import {
|
||||
mockAssistantCategories,
|
||||
mockAssistantList,
|
||||
mockMcpCategories,
|
||||
mockMcpList,
|
||||
mockModelList,
|
||||
mockProviderList,
|
||||
} from './data';
|
||||
|
||||
// ============================================
|
||||
// Helper to parse tRPC batch requests
|
||||
// ============================================
|
||||
|
||||
function parseTrpcUrl(url: string): { input?: Record<string, unknown>; procedure: string } {
|
||||
const urlObj = new URL(url);
|
||||
const pathname = urlObj.pathname;
|
||||
|
||||
// Extract procedure name from path like /trpc/lambda.market.getAssistantList
|
||||
const procedureMatch = pathname.match(/lambda\.market\.(\w+)/);
|
||||
const procedure = procedureMatch ? procedureMatch[1] : '';
|
||||
|
||||
// Parse input from query string
|
||||
let input: Record<string, unknown> | undefined;
|
||||
const inputParam = urlObj.searchParams.get('input');
|
||||
if (inputParam) {
|
||||
try {
|
||||
input = JSON.parse(inputParam);
|
||||
} catch {
|
||||
// Ignore parse errors
|
||||
}
|
||||
}
|
||||
|
||||
return { input, procedure };
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Mock Handlers
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Handler for assistant list endpoint
|
||||
*/
|
||||
const assistantListHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
await route.fulfill({
|
||||
body: createTrpcResponse(mockAssistantList),
|
||||
contentType: 'application/json',
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
pattern: '**/trpc/lambda/market.getAssistantList**',
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for assistant categories endpoint
|
||||
*/
|
||||
const assistantCategoriesHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
await route.fulfill({
|
||||
body: createTrpcResponse(mockAssistantCategories),
|
||||
contentType: 'application/json',
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
pattern: '**/trpc/lambda/market.getAssistantCategories**',
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for model list endpoint
|
||||
*/
|
||||
const modelListHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
await route.fulfill({
|
||||
body: createTrpcResponse(mockModelList),
|
||||
contentType: 'application/json',
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
pattern: '**/trpc/lambda/market.getModelList**',
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for provider list endpoint
|
||||
*/
|
||||
const providerListHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
await route.fulfill({
|
||||
body: createTrpcResponse(mockProviderList),
|
||||
contentType: 'application/json',
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
pattern: '**/trpc/lambda/market.getProviderList**',
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for MCP list endpoint
|
||||
*/
|
||||
const mcpListHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
await route.fulfill({
|
||||
body: createTrpcResponse(mockMcpList),
|
||||
contentType: 'application/json',
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
pattern: '**/trpc/lambda/market.getMcpList**',
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for MCP categories endpoint
|
||||
*/
|
||||
const mcpCategoriesHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
await route.fulfill({
|
||||
body: createTrpcResponse(mockMcpCategories),
|
||||
contentType: 'application/json',
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
pattern: '**/trpc/lambda/market.getMcpCategories**',
|
||||
};
|
||||
|
||||
/**
|
||||
* Debug handler to log all trpc requests
|
||||
*/
|
||||
const trpcDebugHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
const url = route.request().url();
|
||||
console.log(` 🔍 TRPC Request: ${url}`);
|
||||
await route.continue();
|
||||
},
|
||||
pattern: '**/trpc/**',
|
||||
};
|
||||
|
||||
/**
|
||||
* Fallback handler for any unhandled market endpoints
|
||||
* Returns empty data to prevent hanging requests
|
||||
*/
|
||||
const marketFallbackHandler: MockHandler = {
|
||||
handler: async (route: Route) => {
|
||||
const url = route.request().url();
|
||||
const { procedure } = parseTrpcUrl(url);
|
||||
|
||||
console.log(` ⚠️ Unhandled market endpoint: ${procedure}`);
|
||||
|
||||
// Return empty response to prevent timeout
|
||||
await route.fulfill({
|
||||
body: createTrpcResponse({ items: [], pagination: { page: 1, pageSize: 12, total: 0 } }),
|
||||
contentType: 'application/json',
|
||||
status: 200,
|
||||
});
|
||||
},
|
||||
pattern: '**/trpc/lambda/market.**',
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// Export all handlers
|
||||
// ============================================
|
||||
|
||||
export const discoverHandlers: MockHandler[] = [
|
||||
// Debug handler first to log all requests
|
||||
trpcDebugHandler,
|
||||
// Specific handlers (order matters - more specific first)
|
||||
assistantListHandler,
|
||||
assistantCategoriesHandler,
|
||||
modelListHandler,
|
||||
providerListHandler,
|
||||
mcpListHandler,
|
||||
mcpCategoriesHandler,
|
||||
// Fallback handler (should be last)
|
||||
marketFallbackHandler,
|
||||
];
|
||||
@@ -1,7 +0,0 @@
|
||||
/**
|
||||
* Discover/Community module mocks
|
||||
*/
|
||||
|
||||
export * from './data';
|
||||
export { discoverHandlers as discoverMocks } from './handlers';
|
||||
export * from './types';
|
||||
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* Type definitions for Discover mock data
|
||||
* These mirror the actual types from the application
|
||||
*/
|
||||
|
||||
export interface PaginationInfo {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
totalPages: number;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Assistant Types
|
||||
// ============================================
|
||||
|
||||
export interface DiscoverAssistantItem {
|
||||
author: string;
|
||||
avatar: string;
|
||||
backgroundColor?: string;
|
||||
category: string;
|
||||
createdAt: string;
|
||||
description: string;
|
||||
identifier: string;
|
||||
installCount?: number;
|
||||
knowledgeCount?: number;
|
||||
pluginCount?: number;
|
||||
title: string;
|
||||
tokenUsage?: number;
|
||||
userName?: string;
|
||||
}
|
||||
|
||||
export interface AssistantListResponse {
|
||||
items: DiscoverAssistantItem[];
|
||||
pagination: PaginationInfo;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Model Types
|
||||
// ============================================
|
||||
|
||||
export interface DiscoverModelItem {
|
||||
abilities: {
|
||||
functionCall?: boolean;
|
||||
reasoning?: boolean;
|
||||
vision?: boolean;
|
||||
};
|
||||
contextWindowTokens: number;
|
||||
createdAt: string;
|
||||
description: string;
|
||||
displayName: string;
|
||||
id: string;
|
||||
providerId: string;
|
||||
providerName: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface ModelListResponse {
|
||||
items: DiscoverModelItem[];
|
||||
pagination: PaginationInfo;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Provider Types
|
||||
// ============================================
|
||||
|
||||
export interface DiscoverProviderItem {
|
||||
description: string;
|
||||
id: string;
|
||||
logo?: string;
|
||||
modelCount: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ProviderListResponse {
|
||||
items: DiscoverProviderItem[];
|
||||
pagination: PaginationInfo;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// MCP Types
|
||||
// ============================================
|
||||
|
||||
export interface DiscoverMcpItem {
|
||||
author: string;
|
||||
avatar: string;
|
||||
category: string;
|
||||
createdAt: string;
|
||||
description: string;
|
||||
identifier: string;
|
||||
installCount?: number;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface McpListResponse {
|
||||
items: DiscoverMcpItem[];
|
||||
pagination: PaginationInfo;
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/**
|
||||
* E2E Mock Framework
|
||||
*
|
||||
* This module provides a centralized way to mock API responses in E2E tests.
|
||||
* It uses Playwright's route interception to mock tRPC and REST API calls.
|
||||
*/
|
||||
import type { Page, Route } from 'playwright';
|
||||
|
||||
import { discoverMocks } from './discover';
|
||||
|
||||
// ============================================
|
||||
// Types
|
||||
// ============================================
|
||||
|
||||
export interface MockHandler {
|
||||
/** Optional: only apply this mock when condition is true */
|
||||
enabled?: boolean;
|
||||
/** Handler function to process the request */
|
||||
handler: (route: Route, request: Request) => Promise<void>;
|
||||
/** URL pattern to match (supports wildcards) */
|
||||
pattern: string | RegExp;
|
||||
}
|
||||
|
||||
export interface MockConfig {
|
||||
/** Enable/disable all mocks globally */
|
||||
enabled: boolean;
|
||||
/** Mock handlers grouped by domain */
|
||||
handlers: Record<string, MockHandler[]>;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Default Configuration
|
||||
// ============================================
|
||||
|
||||
const defaultConfig: MockConfig = {
|
||||
enabled: true,
|
||||
handlers: {
|
||||
discover: discoverMocks,
|
||||
// Add more domains here as needed:
|
||||
// user: userMocks,
|
||||
// chat: chatMocks,
|
||||
},
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// Mock Manager
|
||||
// ============================================
|
||||
|
||||
export class MockManager {
|
||||
private config: MockConfig;
|
||||
private page: Page | null = null;
|
||||
|
||||
constructor(config: Partial<MockConfig> = {}) {
|
||||
this.config = { ...defaultConfig, ...config };
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup all mock handlers for a page
|
||||
*/
|
||||
async setup(page: Page): Promise<void> {
|
||||
this.page = page;
|
||||
|
||||
if (!this.config.enabled) {
|
||||
console.log('🔇 Mocks disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('🎭 Setting up API mocks...');
|
||||
|
||||
for (const [domain, handlers] of Object.entries(this.config.handlers)) {
|
||||
for (const mock of handlers) {
|
||||
if (mock.enabled === false) continue;
|
||||
|
||||
await page.route(mock.pattern, async (route) => {
|
||||
try {
|
||||
await mock.handler(route, route.request() as unknown as Request);
|
||||
} catch (error) {
|
||||
console.error(`Mock handler error for ${mock.pattern}:`, error);
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log(` ✓ ${domain} mocks registered`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a specific mock domain
|
||||
*/
|
||||
disableDomain(domain: string): void {
|
||||
if (this.config.handlers[domain]) {
|
||||
for (const handler of this.config.handlers[domain]) {
|
||||
handler.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a specific mock domain
|
||||
*/
|
||||
enableDomain(domain: string): void {
|
||||
if (this.config.handlers[domain]) {
|
||||
for (const handler of this.config.handlers[domain]) {
|
||||
handler.enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom mock handlers at runtime
|
||||
*/
|
||||
addHandlers(domain: string, handlers: MockHandler[]): void {
|
||||
if (!this.config.handlers[domain]) {
|
||||
this.config.handlers[domain] = [];
|
||||
}
|
||||
this.config.handlers[domain].push(...handlers);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Helper Functions
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Create a JSON response for tRPC endpoints
|
||||
*/
|
||||
export function createTrpcResponse<T>(data: T): string {
|
||||
return JSON.stringify({
|
||||
result: {
|
||||
data,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an error response for tRPC endpoints
|
||||
*/
|
||||
export function createTrpcError(message: string, code = 'INTERNAL_SERVER_ERROR'): string {
|
||||
return JSON.stringify({
|
||||
error: {
|
||||
code,
|
||||
message,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a standard JSON response
|
||||
*/
|
||||
export function createJsonResponse<T>(data: T): string {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Singleton Instance
|
||||
// ============================================
|
||||
|
||||
export const mockManager = new MockManager();
|
||||
@@ -1,245 +0,0 @@
|
||||
/**
|
||||
* LLM Mock Framework
|
||||
*
|
||||
* Intercepts /webapi/chat/[provider] requests and returns mock SSE responses.
|
||||
* This allows E2E tests to run without real LLM API calls.
|
||||
*/
|
||||
import type { Page, Route } from 'playwright';
|
||||
|
||||
// ============================================
|
||||
// Types
|
||||
// ============================================
|
||||
|
||||
export interface LLMMockConfig {
|
||||
/** Default response content when no specific mock is set */
|
||||
defaultResponse: string;
|
||||
/** Whether to enable LLM mocking */
|
||||
enabled: boolean;
|
||||
/** Response delay in ms (simulates network latency) */
|
||||
responseDelay: number;
|
||||
/** Chunk size for streaming (characters per chunk) */
|
||||
streamChunkSize: number;
|
||||
/** Delay between chunks in ms */
|
||||
streamDelay: number;
|
||||
}
|
||||
|
||||
export interface ChatMessage {
|
||||
content: string;
|
||||
role: 'user' | 'assistant' | 'system';
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Default Configuration
|
||||
// ============================================
|
||||
|
||||
const defaultConfig: LLMMockConfig = {
|
||||
defaultResponse: 'Hello! I am a mock AI assistant. How can I help you today?',
|
||||
enabled: true,
|
||||
responseDelay: 100,
|
||||
streamChunkSize: 10,
|
||||
streamDelay: 20,
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// SSE Response Builder
|
||||
// ============================================
|
||||
|
||||
/**
|
||||
* Build SSE formatted response chunks
|
||||
* Follows LobeChat's actual streaming format
|
||||
*/
|
||||
function buildSSEChunks(content: string, chunkSize: number): string[] {
|
||||
const chunks: string[] = [];
|
||||
const id = `msg_mock_${Date.now()}`;
|
||||
|
||||
// Initial message data
|
||||
const initialData = {
|
||||
content: [],
|
||||
id,
|
||||
model: 'gpt-4o-mini',
|
||||
role: 'assistant',
|
||||
stop_reason: null,
|
||||
stop_sequence: null,
|
||||
type: 'message',
|
||||
usage: { input_tokens: 10, output_tokens: 0 },
|
||||
};
|
||||
chunks.push(`id: ${id}\nevent: data\ndata: ${JSON.stringify(initialData)}\n\n`);
|
||||
|
||||
// Split content into chunks and send as text events
|
||||
for (let i = 0; i < content.length; i += chunkSize) {
|
||||
const chunk = content.slice(i, i + chunkSize);
|
||||
chunks.push(`id: ${id}\nevent: text\ndata: "${chunk.replaceAll('"', '\\"')}"\n\n`);
|
||||
}
|
||||
|
||||
// Stop event
|
||||
chunks.push(`id: ${id}\nevent: stop\ndata: "end_turn"\n\n`);
|
||||
|
||||
// Usage event
|
||||
const usageData = {
|
||||
cost: 0.0001,
|
||||
inputCacheMissTokens: 10,
|
||||
inputCachedTokens: 0,
|
||||
totalInputTokens: 10,
|
||||
totalOutputTokens: Math.ceil(content.length / 4),
|
||||
totalTokens: 10 + Math.ceil(content.length / 4),
|
||||
};
|
||||
chunks.push(
|
||||
`id: ${id}\nevent: usage\ndata: ${JSON.stringify(usageData)}\n\n`,
|
||||
`id: ${id}\nevent: stop\ndata: "message_stop"\n\n`,
|
||||
);
|
||||
|
||||
return chunks;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// LLM Mock Manager
|
||||
// ============================================
|
||||
|
||||
export class LLMMockManager {
|
||||
private config: LLMMockConfig;
|
||||
private customResponses: Map<string, string> = new Map();
|
||||
private page: Page | null = null;
|
||||
|
||||
constructor(config: Partial<LLMMockConfig> = {}) {
|
||||
this.config = { ...defaultConfig, ...config };
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom response for a specific user message
|
||||
*/
|
||||
setResponse(userMessage: string, response: string): void {
|
||||
this.customResponses.set(userMessage.toLowerCase().trim(), response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all custom responses
|
||||
*/
|
||||
clearResponses(): void {
|
||||
this.customResponses.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get response for a user message
|
||||
*/
|
||||
private getResponse(messages: ChatMessage[]): string {
|
||||
// Find the last user message
|
||||
const lastUserMessage = [...messages].reverse().find((m) => m.role === 'user');
|
||||
|
||||
if (lastUserMessage) {
|
||||
const key = lastUserMessage.content.toLowerCase().trim();
|
||||
if (this.customResponses.has(key)) {
|
||||
return this.customResponses.get(key)!;
|
||||
}
|
||||
}
|
||||
|
||||
return this.config.defaultResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup LLM mock handlers for a page
|
||||
*/
|
||||
async setup(page: Page): Promise<void> {
|
||||
this.page = page;
|
||||
|
||||
if (!this.config.enabled) {
|
||||
console.log(' 🔇 LLM mocks disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
// Intercept OpenAI chat API requests
|
||||
await page.route('**/webapi/chat/openai**', async (route) => {
|
||||
await this.handleChatRequest(route);
|
||||
});
|
||||
|
||||
console.log(' ✓ LLM mocks registered (openai)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle intercepted chat request
|
||||
*/
|
||||
private async handleChatRequest(route: Route): Promise<void> {
|
||||
const request = route.request();
|
||||
|
||||
try {
|
||||
// Parse request body
|
||||
const body = request.postDataJSON();
|
||||
const messages: ChatMessage[] = body?.messages || [];
|
||||
|
||||
console.log(` 🤖 LLM Request intercepted (${messages.length} messages)`);
|
||||
|
||||
// Get response content
|
||||
const responseContent = this.getResponse(messages);
|
||||
|
||||
// Build SSE chunks
|
||||
const chunks = buildSSEChunks(responseContent, this.config.streamChunkSize);
|
||||
|
||||
// Simulate initial delay
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, this.config.responseDelay);
|
||||
});
|
||||
|
||||
// Create streaming response
|
||||
const stream = chunks.join('');
|
||||
|
||||
await route.fulfill({
|
||||
body: stream,
|
||||
headers: {
|
||||
'Cache-Control': 'no-cache',
|
||||
'Connection': 'keep-alive',
|
||||
'Content-Type': 'text/event-stream',
|
||||
},
|
||||
status: 200,
|
||||
});
|
||||
|
||||
console.log(` ✅ LLM Response sent (${responseContent.length} chars)`);
|
||||
} catch (error) {
|
||||
console.error(' ❌ LLM Mock error:', error);
|
||||
await route.fulfill({
|
||||
body: JSON.stringify({ error: 'Mock error' }),
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable LLM mocking
|
||||
*/
|
||||
disable(): void {
|
||||
this.config.enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable LLM mocking
|
||||
*/
|
||||
enable(): void {
|
||||
this.config.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Singleton Instance
|
||||
// ============================================
|
||||
|
||||
export const llmMockManager = new LLMMockManager();
|
||||
|
||||
// ============================================
|
||||
// Preset Responses
|
||||
// ============================================
|
||||
|
||||
export const presetResponses = {
|
||||
codeHelp: 'I can help you with coding! Please share the code you would like me to review.',
|
||||
error: 'I apologize, but I encountered an error processing your request.',
|
||||
greeting: 'Hello! I am Lobe AI, your AI assistant. How can I help you today?',
|
||||
|
||||
// Long response for stop generation test
|
||||
longArticle:
|
||||
'这是一篇很长的文章。第一段:人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器。第二段:人工智能研究的主要目标包括推理、知识、规划、学习、自然语言处理、感知和移动与操控物体的能力。第三段:目前,人工智能已经在许多领域取得了重大突破,包括图像识别、语音识别、自然语言处理等。',
|
||||
|
||||
// Multi-turn conversation responses
|
||||
nameIntro: '好的,我记住了,你的名字是小明。很高兴认识你,小明!有什么我可以帮助你的吗?',
|
||||
|
||||
nameRecall: '你刚才说你的名字是小明。',
|
||||
// Regenerate response
|
||||
regenerated: '这是重新生成的回复内容。我是 Lobe AI,很高兴为你服务!',
|
||||
};
|
||||
@@ -1,428 +0,0 @@
|
||||
/**
|
||||
* Agent Conversation Management Steps
|
||||
*
|
||||
* Step definitions for Agent conversation management E2E tests
|
||||
* - Create new conversation
|
||||
* - Switch conversations
|
||||
* - Rename conversation
|
||||
* - Delete conversation
|
||||
* - Search conversations
|
||||
*/
|
||||
import { Given, Then, When } from '@cucumber/cucumber';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
import { CustomWorld } from '../../support/world';
|
||||
|
||||
// ============================================
|
||||
// Given Steps
|
||||
// ============================================
|
||||
|
||||
Given('用户已有一个对话', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 创建一个对话...');
|
||||
|
||||
// Send a message to create a conversation
|
||||
const chatInputs = this.page.locator('[data-testid="chat-input"]');
|
||||
const count = await chatInputs.count();
|
||||
|
||||
let chatInputContainer = chatInputs.first();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const elem = chatInputs.nth(i);
|
||||
const box = await elem.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0) {
|
||||
chatInputContainer = elem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
await chatInputContainer.click();
|
||||
await this.page.waitForTimeout(300);
|
||||
await this.page.keyboard.type('hello', { delay: 30 });
|
||||
await this.page.keyboard.press('Enter');
|
||||
|
||||
// Wait for response
|
||||
await this.page.waitForTimeout(2000);
|
||||
|
||||
// Store the current conversation title for later reference
|
||||
const topicItems = this.page.locator('.ant-menu-item, [class*="NavItem"]');
|
||||
const topicCount = await topicItems.count();
|
||||
console.log(` 📍 Found ${topicCount} topic items after creating conversation`);
|
||||
|
||||
console.log(' ✅ 已创建一个对话');
|
||||
});
|
||||
|
||||
Given('用户有多个对话历史', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 创建多个对话...');
|
||||
|
||||
// Create first conversation
|
||||
const chatInputs = this.page.locator('[data-testid="chat-input"]');
|
||||
let chatInputContainer = chatInputs.first();
|
||||
const count = await chatInputs.count();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const elem = chatInputs.nth(i);
|
||||
const box = await elem.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0) {
|
||||
chatInputContainer = elem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// First conversation - use "测试" content for search test
|
||||
await chatInputContainer.click();
|
||||
await this.page.waitForTimeout(300);
|
||||
await this.page.keyboard.type('测试对话内容', { delay: 30 });
|
||||
await this.page.keyboard.press('Enter');
|
||||
await this.page.waitForTimeout(2000);
|
||||
|
||||
// Store first conversation reference
|
||||
this.testContext.firstConversation = 'first';
|
||||
|
||||
// Create new topic and second conversation
|
||||
console.log(' 📍 Creating second conversation...');
|
||||
const addTopicButton = this.page.locator('svg.lucide-message-square-plus').locator('..');
|
||||
if ((await addTopicButton.count()) > 0) {
|
||||
await addTopicButton.first().click();
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
// Send message in second conversation - different content
|
||||
await chatInputContainer.click();
|
||||
await this.page.waitForTimeout(300);
|
||||
await this.page.keyboard.type('hello world', { delay: 30 });
|
||||
await this.page.keyboard.press('Enter');
|
||||
await this.page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
console.log(' ✅ 已创建多个对话');
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// When Steps
|
||||
// ============================================
|
||||
|
||||
When('用户点击新建对话按钮', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 点击新建对话按钮...');
|
||||
|
||||
// The add topic button uses MessageSquarePlusIcon from lucide-react
|
||||
const addTopicButton = this.page.locator('svg.lucide-message-square-plus').locator('..');
|
||||
|
||||
if ((await addTopicButton.count()) > 0) {
|
||||
await addTopicButton.first().click();
|
||||
console.log(' ✅ 已点击新建对话按钮');
|
||||
} else {
|
||||
// Fallback: look for button with "新建" or "add" in title
|
||||
const addButton = this.page.locator('button[title*="新建"], button[title*="add"]');
|
||||
if ((await addButton.count()) > 0) {
|
||||
await addButton.first().click();
|
||||
console.log(' ✅ 已点击新建对话按钮 (fallback)');
|
||||
} else {
|
||||
throw new Error('New topic button not found');
|
||||
}
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户点击另一个对话', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 点击另一个对话...');
|
||||
|
||||
// Find topic items in the sidebar
|
||||
// Topics are displayed with star icons (lucide-star) in the left sidebar
|
||||
// Each topic item has a star icon as part of it
|
||||
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
|
||||
let topicCount = await sidebarTopics.count();
|
||||
console.log(` 📍 Found ${topicCount} topics with star icons`);
|
||||
|
||||
// If not found by star, try finding by topic list structure
|
||||
if (topicCount < 2) {
|
||||
// Topics might be in a list container - look for items in sidebar with specific text
|
||||
const topicItems = this.page.locator('[class*="nav-item"], [class*="NavItem"]');
|
||||
topicCount = await topicItems.count();
|
||||
console.log(` 📍 Found ${topicCount} nav items`);
|
||||
|
||||
if (topicCount >= 2) {
|
||||
await topicItems.nth(1).click();
|
||||
console.log(' ✅ 已点击另一个对话');
|
||||
await this.page.waitForTimeout(500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Click the second topic (first one is current/active)
|
||||
if (topicCount >= 2) {
|
||||
await sidebarTopics.nth(1).click();
|
||||
console.log(' ✅ 已点击另一个对话');
|
||||
} else {
|
||||
throw new Error('Not enough topics to switch');
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户右键点击对话', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 右键点击对话...');
|
||||
|
||||
// Find topic items by their star icon - each saved topic has a star
|
||||
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
|
||||
let topicCount = await sidebarTopics.count();
|
||||
console.log(` 📍 Found ${topicCount} topics with star icons`);
|
||||
|
||||
if (topicCount > 0) {
|
||||
// Right-click the first saved topic
|
||||
await sidebarTopics.first().click({ button: 'right' });
|
||||
console.log(' ✅ 已右键点击对话');
|
||||
} else {
|
||||
throw new Error('No topics found to right-click');
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户右键点击一个对话', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 右键点击一个对话...');
|
||||
|
||||
// Find topic items by their star icon
|
||||
const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
|
||||
let topicCount = await sidebarTopics.count();
|
||||
console.log(` 📍 Found ${topicCount} topics with star icons`);
|
||||
|
||||
// Store the topic text for later verification
|
||||
if (topicCount > 0) {
|
||||
const topicText = await sidebarTopics.first().textContent();
|
||||
this.testContext.deletedTopicTitle = topicText?.slice(0, 30);
|
||||
await sidebarTopics.first().click({ button: 'right' });
|
||||
console.log(` ✅ 已右键点击对话: "${topicText?.slice(0, 30)}..."`);
|
||||
} else {
|
||||
throw new Error('No topics found to right-click');
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户选择重命名选项', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 选择重命名选项...');
|
||||
|
||||
// The context menu should be visible with "rename" option
|
||||
// Use exact match to avoid matching "智能重命名"
|
||||
const renameOption = this.page.getByRole('menuitem', { exact: true, name: '重命名' });
|
||||
|
||||
await expect(renameOption).toBeVisible({ timeout: 5000 });
|
||||
await renameOption.click();
|
||||
|
||||
console.log(' ✅ 已选择重命名选项');
|
||||
await this.page.waitForTimeout(300);
|
||||
});
|
||||
|
||||
When('用户输入新的对话名称 {string}', async function (this: CustomWorld, newName: string) {
|
||||
console.log(` 📍 Step: 输入新名称 "${newName}"...`);
|
||||
|
||||
// The topic should now be in editing mode with an input field
|
||||
this.page.locator('input[type="text"]').filter({
|
||||
has: this.page.locator(':focus'),
|
||||
});
|
||||
|
||||
// Wait for input to appear
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
// Find the visible input in the sidebar area
|
||||
const sidebarInput = this.page.locator('[class*="NavItem"] input, .ant-input');
|
||||
const inputCount = await sidebarInput.count();
|
||||
console.log(` 📍 Found ${inputCount} input fields`);
|
||||
|
||||
if (inputCount > 0) {
|
||||
const input = sidebarInput.first();
|
||||
await input.clear();
|
||||
await input.fill(newName);
|
||||
await this.page.keyboard.press('Enter');
|
||||
console.log(` ✅ 已输入新名称 "${newName}"`);
|
||||
} else {
|
||||
// Try finding by focused element
|
||||
await this.page.keyboard.type(newName, { delay: 30 });
|
||||
await this.page.keyboard.press('Enter');
|
||||
console.log(` ✅ 已通过键盘输入新名称 "${newName}"`);
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户选择删除选项', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 选择删除选项...');
|
||||
|
||||
// The context menu should be visible with "delete" option
|
||||
const deleteOption = this.page.locator(
|
||||
'.ant-dropdown-menu-item:has-text("删除"), .ant-dropdown-menu-item-danger',
|
||||
);
|
||||
|
||||
await expect(deleteOption).toBeVisible({ timeout: 5000 });
|
||||
await deleteOption.click();
|
||||
|
||||
console.log(' ✅ 已选择删除选项');
|
||||
await this.page.waitForTimeout(300);
|
||||
});
|
||||
|
||||
When('用户确认删除', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 确认删除...');
|
||||
|
||||
// A confirmation modal should appear
|
||||
const confirmButton = this.page.locator('.ant-modal-confirm-btns button.ant-btn-dangerous');
|
||||
|
||||
// Wait for modal to appear
|
||||
await expect(confirmButton).toBeVisible({ timeout: 5000 });
|
||||
await confirmButton.click();
|
||||
|
||||
console.log(' ✅ 已确认删除');
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户在搜索框中输入 {string}', async function (this: CustomWorld, searchText: string) {
|
||||
console.log(` 📍 Step: 在搜索框中输入 "${searchText}"...`);
|
||||
|
||||
// Find the search input in the sidebar
|
||||
const searchInput = this.page.locator('input[placeholder*="搜索"], [data-testid="search-input"]');
|
||||
|
||||
if ((await searchInput.count()) > 0) {
|
||||
await searchInput.first().click();
|
||||
await searchInput.first().fill(searchText);
|
||||
} else {
|
||||
// Fallback: click on search icon to reveal search input
|
||||
const searchIcon = this.page.locator('svg.lucide-search').locator('..');
|
||||
if ((await searchIcon.count()) > 0) {
|
||||
await searchIcon.first().click();
|
||||
await this.page.waitForTimeout(300);
|
||||
// Now find the input
|
||||
const input = this.page.locator('input[type="text"]').last();
|
||||
await input.fill(searchText);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(` ✅ 已输入搜索内容 "${searchText}"`);
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Then Steps
|
||||
// ============================================
|
||||
|
||||
Then('应该创建一个新的空白对话', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证新对话已创建...');
|
||||
|
||||
// The chat area should be empty or show welcome message
|
||||
// Check that there are no user/assistant messages
|
||||
const userMessages = this.page.locator('[data-role="user"]');
|
||||
const assistantMessages = this.page.locator('[data-role="assistant"]');
|
||||
|
||||
const userCount = await userMessages.count();
|
||||
const assistantCount = await assistantMessages.count();
|
||||
|
||||
console.log(` 📍 用户消息数量: ${userCount}, 助手消息数量: ${assistantCount}`);
|
||||
|
||||
// New conversation should have no messages
|
||||
expect(userCount).toBe(0);
|
||||
expect(assistantCount).toBe(0);
|
||||
|
||||
console.log(' ✅ 新对话已创建');
|
||||
});
|
||||
|
||||
Then('应该切换到该对话', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证已切换对话...');
|
||||
|
||||
// The URL or active state should change
|
||||
// For now, just verify the page is responsive
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
console.log(' ✅ 已切换到该对话');
|
||||
});
|
||||
|
||||
Then('显示该对话的历史消息', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证显示历史消息...');
|
||||
|
||||
// There should be messages in the chat area
|
||||
const messages = this.page.locator('[class*="message"], [data-role]');
|
||||
const messageCount = await messages.count();
|
||||
|
||||
console.log(` 📍 找到 ${messageCount} 条消息`);
|
||||
|
||||
// At least some messages should be visible
|
||||
expect(messageCount).toBeGreaterThan(0);
|
||||
|
||||
console.log(' ✅ 历史消息已显示');
|
||||
});
|
||||
|
||||
Then('对话名称应该更新为 {string}', async function (this: CustomWorld, expectedName: string) {
|
||||
console.log(` 📍 Step: 验证对话名称为 "${expectedName}"...`);
|
||||
|
||||
// Wait for the rename to take effect
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
// Find the topic with the new name by text content
|
||||
// Topics are in the sidebar, look for text directly
|
||||
// Use .first() since the name might appear in multiple places (sidebar + favorites section)
|
||||
const renamedTopic = this.page.getByText(expectedName, { exact: true }).first();
|
||||
|
||||
await expect(renamedTopic).toBeVisible({ timeout: 5000 });
|
||||
|
||||
console.log(` ✅ 对话名称已更新为 "${expectedName}"`);
|
||||
});
|
||||
|
||||
Then('该对话应该被删除', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证对话已删除...');
|
||||
|
||||
// Wait for deletion to take effect
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
console.log(' ✅ 对话已删除');
|
||||
});
|
||||
|
||||
Then('对话列表中不再显示该对话', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证对话列表中不再显示该对话...');
|
||||
|
||||
// Wait for UI to update
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
// The deleted topic should not be in the list
|
||||
if (this.testContext.deletedTopicTitle) {
|
||||
const deletedTopic = this.page.locator(
|
||||
`[class*="NavItem"]:has-text("${this.testContext.deletedTopicTitle}")`,
|
||||
);
|
||||
const count = await deletedTopic.count();
|
||||
expect(count).toBe(0);
|
||||
console.log(` ✅ 对话 "${this.testContext.deletedTopicTitle}" 已从列表中移除`);
|
||||
} else {
|
||||
console.log(' ✅ 对话已从列表中移除');
|
||||
}
|
||||
});
|
||||
|
||||
Then('应该显示包含 {string} 的对话', async function (this: CustomWorld, searchText: string) {
|
||||
console.log(` 📍 Step: 验证搜索结果包含 "${searchText}"...`);
|
||||
|
||||
// Wait for search results to load (search opens a modal dialog)
|
||||
await this.page.waitForTimeout(2000);
|
||||
|
||||
// Search results appear in a modal/dialog, not in sidebar
|
||||
// Look for the search modal and check for matching results
|
||||
const searchModal = this.page.locator('.ant-modal, [role="dialog"]');
|
||||
const hasModal = (await searchModal.count()) > 0;
|
||||
console.log(` 📍 搜索模态框: ${hasModal}`);
|
||||
|
||||
// Find matching items in the search results (either in modal or in sidebar if filtered)
|
||||
const matchingInModal = searchModal.getByText(searchText);
|
||||
const matchingInPage = this.page.getByText(searchText);
|
||||
|
||||
const modalMatchCount = await matchingInModal.count();
|
||||
const pageMatchCount = await matchingInPage.count();
|
||||
|
||||
console.log(` 📍 模态框中找到 ${modalMatchCount} 个匹配, 页面中找到 ${pageMatchCount} 个匹配`);
|
||||
|
||||
// At least one match should be found (either in search input or results)
|
||||
expect(modalMatchCount + pageMatchCount).toBeGreaterThan(0);
|
||||
|
||||
console.log(` ✅ 搜索结果显示包含 "${searchText}" 的对话`);
|
||||
});
|
||||
|
||||
Then('不相关的对话应该被过滤', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证不相关对话已被过滤...');
|
||||
|
||||
// This would require checking that non-matching topics are hidden
|
||||
// For now, just verify the search is active
|
||||
await this.page.waitForTimeout(300);
|
||||
|
||||
console.log(' ✅ 不相关对话已被过滤');
|
||||
});
|
||||
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* Agent Conversation Steps
|
||||
*
|
||||
* Step definitions for Agent conversation E2E tests
|
||||
*/
|
||||
import { Given, Then, When } from '@cucumber/cucumber';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
import { llmMockManager, presetResponses } from '../../mocks/llm';
|
||||
import { CustomWorld } from '../../support/world';
|
||||
|
||||
// ============================================
|
||||
// Given Steps
|
||||
// ============================================
|
||||
|
||||
Given('用户已登录系统', async function (this: CustomWorld) {
|
||||
// Session cookies are already set by the Before hook
|
||||
// Just verify we have cookies
|
||||
const cookies = await this.browserContext.cookies();
|
||||
expect(cookies.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
Given('用户进入 Lobe AI 对话页面', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 设置 LLM mock...');
|
||||
// Setup LLM mock before navigation
|
||||
llmMockManager.setResponse('hello', presetResponses.greeting);
|
||||
await llmMockManager.setup(this.page);
|
||||
|
||||
console.log(' 📍 Step: 导航到首页...');
|
||||
// Navigate to home page first
|
||||
await this.page.goto('/');
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
|
||||
console.log(' 📍 Step: 查找 Lobe AI...');
|
||||
// Find and click on "Lobe AI" agent in the sidebar/home
|
||||
const lobeAIAgent = this.page.locator('text=Lobe AI').first();
|
||||
await expect(lobeAIAgent).toBeVisible({ timeout: 10_000 });
|
||||
|
||||
console.log(' 📍 Step: 点击 Lobe AI...');
|
||||
await lobeAIAgent.click();
|
||||
|
||||
console.log(' 📍 Step: 等待聊天界面加载...');
|
||||
// Wait for the chat interface to be ready
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
|
||||
console.log(' 📍 Step: 查找输入框...');
|
||||
// The input is a rich text editor with contenteditable
|
||||
// There are 2 ChatInput components (desktop & mobile), find the visible one
|
||||
|
||||
// Wait for the page to be ready, then find visible chat input
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
// Find all chat-input elements and get the visible one
|
||||
const chatInputs = this.page.locator('[data-testid="chat-input"]');
|
||||
const count = await chatInputs.count();
|
||||
console.log(` 📍 Found ${count} chat-input elements`);
|
||||
|
||||
// Find the first visible one or just use the first one
|
||||
let chatInputContainer = chatInputs.first();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const elem = chatInputs.nth(i);
|
||||
const box = await elem.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0) {
|
||||
chatInputContainer = elem;
|
||||
console.log(` ✓ Using chat-input element ${i} (has bounding box)`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Click the container to focus the editor
|
||||
await chatInputContainer.click();
|
||||
console.log(' ✓ Clicked on chat input container');
|
||||
|
||||
// Wait for any animations to complete
|
||||
await this.page.waitForTimeout(300);
|
||||
|
||||
console.log(' ✅ 已进入 Lobe AI 对话页面');
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// When Steps
|
||||
// ============================================
|
||||
|
||||
When('用户发送消息 {string}', async function (this: CustomWorld, message: string) {
|
||||
console.log(` 📍 Step: 查找输入框...`);
|
||||
|
||||
// Find visible chat input container first
|
||||
const chatInputs = this.page.locator('[data-testid="chat-input"]');
|
||||
const count = await chatInputs.count();
|
||||
console.log(` 📍 Found ${count} chat-input containers`);
|
||||
|
||||
let chatInputContainer = chatInputs.first();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const elem = chatInputs.nth(i);
|
||||
const box = await elem.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0) {
|
||||
chatInputContainer = elem;
|
||||
console.log(` 📍 Using container ${i}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Click the container to ensure focus is on the input area
|
||||
console.log(` 📍 Step: 点击输入区域...`);
|
||||
await chatInputContainer.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
console.log(` 📍 Step: 输入消息 "${message}"...`);
|
||||
// Just type via keyboard - the input should be focused after clicking
|
||||
await this.page.keyboard.type(message, { delay: 30 });
|
||||
await this.page.waitForTimeout(300);
|
||||
|
||||
console.log(` 📍 Step: 发送消息 (按 Enter)...`);
|
||||
await this.page.keyboard.press('Enter');
|
||||
|
||||
// Wait for the message to be sent and processed
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
console.log(` ✅ 消息已发送`);
|
||||
this.testContext.lastMessage = message;
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Then Steps
|
||||
// ============================================
|
||||
|
||||
Then('用户应该收到助手的回复', async function (this: CustomWorld) {
|
||||
// Wait for the assistant response to appear
|
||||
// The response should be in a message bubble with role="assistant" or similar
|
||||
const assistantMessage = this.page
|
||||
.locator('[data-role="assistant"], [class*="assistant"], [class*="message"]')
|
||||
.last();
|
||||
|
||||
await expect(assistantMessage).toBeVisible({ timeout: 15_000 });
|
||||
});
|
||||
|
||||
Then('回复内容应该可见', async function (this: CustomWorld) {
|
||||
// Verify the response content is not empty and contains expected text
|
||||
const responseText = this.page
|
||||
.locator('[data-role="assistant"], [class*="assistant"], [class*="message"]')
|
||||
.last()
|
||||
.locator('p, span, div')
|
||||
.first();
|
||||
|
||||
await expect(responseText).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Get the text content and verify it's not empty
|
||||
const text = await responseText.textContent();
|
||||
expect(text).toBeTruthy();
|
||||
expect(text!.length).toBeGreaterThan(0);
|
||||
|
||||
console.log(` ✅ Assistant replied: "${text?.slice(0, 50)}..."`);
|
||||
});
|
||||
@@ -1,415 +0,0 @@
|
||||
/**
|
||||
* Agent Message Operations Steps
|
||||
*
|
||||
* Step definitions for Agent message operations E2E tests
|
||||
* - Copy message
|
||||
* - Edit message
|
||||
* - Delete message
|
||||
* - Collapse/Expand message
|
||||
*/
|
||||
import { Then, When } from '@cucumber/cucumber';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
import { CustomWorld } from '../../support/world';
|
||||
|
||||
// ============================================
|
||||
// When Steps
|
||||
// ============================================
|
||||
|
||||
// Helper function to find the assistant message wrapper
|
||||
async function findAssistantMessage(page: CustomWorld['page']) {
|
||||
const messageWrappers = page.locator('.message-wrapper');
|
||||
const wrapperCount = await messageWrappers.count();
|
||||
console.log(` 📍 Found ${wrapperCount} message wrappers`);
|
||||
|
||||
// Find the assistant message by looking for the one with "Lobe AI" or "AI" in title
|
||||
for (let i = wrapperCount - 1; i >= 0; i--) {
|
||||
const wrapper = messageWrappers.nth(i);
|
||||
const titleText = await wrapper
|
||||
.locator('.message-header')
|
||||
.textContent()
|
||||
.catch(() => '');
|
||||
|
||||
if (titleText?.includes('Lobe AI') || titleText?.includes('AI')) {
|
||||
console.log(` 📍 Found assistant message at index ${i}`);
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: return the last message wrapper that's aligned left (assistant messages)
|
||||
return messageWrappers.last();
|
||||
}
|
||||
|
||||
When('用户点击消息的复制按钮', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 点击复制按钮...');
|
||||
|
||||
// Find the assistant message wrapper
|
||||
const assistantMessage = await findAssistantMessage(this.page);
|
||||
|
||||
// Hover to reveal action buttons
|
||||
await assistantMessage.hover();
|
||||
await this.page.waitForTimeout(800);
|
||||
|
||||
// First try: find copy button directly by its icon (lucide-copy)
|
||||
const copyButtonByIcon = this.page.locator('svg.lucide-copy').locator('..');
|
||||
let copyButtonCount = await copyButtonByIcon.count();
|
||||
console.log(` 📍 Found ${copyButtonCount} buttons with copy icon`);
|
||||
|
||||
if (copyButtonCount > 0) {
|
||||
// Click the visible copy button
|
||||
for (let i = 0; i < copyButtonCount; i++) {
|
||||
const btn = copyButtonByIcon.nth(i);
|
||||
const box = await btn.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0) {
|
||||
await btn.click();
|
||||
console.log(' ✅ 已点击复制按钮');
|
||||
await this.page.waitForTimeout(500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: Look for action bar within message and open more menu
|
||||
console.log(' 📍 Fallback: Looking for copy in more menu...');
|
||||
const actionBar = assistantMessage.locator('[role="menubar"]');
|
||||
if ((await actionBar.count()) > 0) {
|
||||
const moreButton = actionBar.locator('button').last();
|
||||
await moreButton.click();
|
||||
await this.page.waitForTimeout(300);
|
||||
|
||||
const copyMenuItem = this.page.getByRole('menuitem', { name: /复制/ });
|
||||
if ((await copyMenuItem.count()) > 0) {
|
||||
await copyMenuItem.click();
|
||||
console.log(' ✅ 已从菜单中点击复制');
|
||||
await this.page.waitForTimeout(500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Last fallback: find more button by icon and open menu
|
||||
const moreButtonByIcon = this.page.locator('svg.lucide-more-horizontal').locator('..');
|
||||
if ((await moreButtonByIcon.count()) > 0) {
|
||||
await moreButtonByIcon.first().click();
|
||||
await this.page.waitForTimeout(300);
|
||||
|
||||
const copyMenuItem = this.page.getByRole('menuitem', { name: /复制/ });
|
||||
await copyMenuItem.click();
|
||||
console.log(' ✅ 已从更多菜单中点击复制');
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户点击助手消息的编辑按钮', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 点击编辑按钮...');
|
||||
|
||||
// Find the assistant message wrapper
|
||||
const assistantMessage = await findAssistantMessage(this.page);
|
||||
|
||||
// Hover to reveal action buttons
|
||||
await assistantMessage.hover();
|
||||
await this.page.waitForTimeout(800);
|
||||
|
||||
// First try: find edit button directly by its icon (lucide-pencil)
|
||||
const editButtonByIcon = this.page.locator('svg.lucide-pencil').locator('..');
|
||||
let editButtonCount = await editButtonByIcon.count();
|
||||
console.log(` 📍 Found ${editButtonCount} buttons with pencil icon`);
|
||||
|
||||
if (editButtonCount > 0) {
|
||||
for (let i = 0; i < editButtonCount; i++) {
|
||||
const btn = editButtonByIcon.nth(i);
|
||||
const box = await btn.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0) {
|
||||
await btn.click();
|
||||
console.log(' ✅ 已点击编辑按钮');
|
||||
await this.page.waitForTimeout(500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: Look for edit in more menu
|
||||
console.log(' 📍 Fallback: Looking for edit in more menu...');
|
||||
const moreButtonByIcon = this.page.locator('svg.lucide-more-horizontal').locator('..');
|
||||
if ((await moreButtonByIcon.count()) > 0) {
|
||||
await moreButtonByIcon.first().click();
|
||||
await this.page.waitForTimeout(300);
|
||||
|
||||
const editMenuItem = this.page.getByRole('menuitem', { name: /编辑/ });
|
||||
if ((await editMenuItem.count()) > 0) {
|
||||
await editMenuItem.click();
|
||||
console.log(' ✅ 已从菜单中点击编辑');
|
||||
}
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户修改消息内容为 {string}', async function (this: CustomWorld, newContent: string) {
|
||||
console.log(` 📍 Step: 修改消息内容为 "${newContent}"...`);
|
||||
|
||||
// Find the editing textarea or input
|
||||
const editArea = this.page.locator('textarea, [contenteditable="true"]').last();
|
||||
await expect(editArea).toBeVisible({ timeout: 5000 });
|
||||
|
||||
// Clear and enter new content
|
||||
await editArea.click();
|
||||
await this.page.keyboard.press('Meta+a'); // Select all
|
||||
await this.page.keyboard.type(newContent, { delay: 30 });
|
||||
|
||||
// Store for later verification
|
||||
this.testContext.editedContent = newContent;
|
||||
|
||||
console.log(` ✅ 已修改消息内容为 "${newContent}"`);
|
||||
});
|
||||
|
||||
When('用户保存编辑', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 保存编辑...');
|
||||
|
||||
// Find and click the save/confirm button
|
||||
const saveButton = this.page.locator('button').filter({
|
||||
has: this.page.locator('svg.lucide-check'),
|
||||
});
|
||||
|
||||
if ((await saveButton.count()) > 0) {
|
||||
await saveButton.first().click();
|
||||
} else {
|
||||
// Fallback: press Enter or find confirm button
|
||||
await this.page.keyboard.press('Enter');
|
||||
}
|
||||
|
||||
console.log(' ✅ 已保存编辑');
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户点击消息的更多操作按钮', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 点击更多操作按钮...');
|
||||
|
||||
// Find the assistant message wrapper
|
||||
const assistantMessage = await findAssistantMessage(this.page);
|
||||
|
||||
// Hover to reveal action buttons
|
||||
await assistantMessage.hover();
|
||||
await this.page.waitForTimeout(800);
|
||||
|
||||
// Get the bounding box of the message to help filter buttons
|
||||
const messageBox = await assistantMessage.boundingBox();
|
||||
console.log(` 📍 Message bounding box: y=${messageBox?.y}, height=${messageBox?.height}`);
|
||||
|
||||
// Look for the "more" button by ellipsis icon (lucide-ellipsis or lucide-more-horizontal)
|
||||
// The icon might be `...` which is lucide-ellipsis
|
||||
const ellipsisButtons = this.page
|
||||
.locator('svg.lucide-ellipsis, svg.lucide-more-horizontal')
|
||||
.locator('..');
|
||||
let ellipsisCount = await ellipsisButtons.count();
|
||||
console.log(` 📍 Found ${ellipsisCount} buttons with ellipsis/more icon`);
|
||||
|
||||
if (ellipsisCount > 0 && messageBox) {
|
||||
// Find buttons in the message area (x > 320 to exclude sidebar)
|
||||
for (let i = 0; i < ellipsisCount; i++) {
|
||||
const btn = ellipsisButtons.nth(i);
|
||||
const box = await btn.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0) {
|
||||
console.log(` 📍 Ellipsis button ${i}: x=${box.x}, y=${box.y}`);
|
||||
// Check if button is within the message area
|
||||
if (
|
||||
box.x > 320 &&
|
||||
box.y >= messageBox.y - 50 &&
|
||||
box.y <= messageBox.y + messageBox.height + 50
|
||||
) {
|
||||
await btn.click();
|
||||
console.log(` ✅ 已点击更多操作按钮 (ellipsis at x=${box.x}, y=${box.y})`);
|
||||
await this.page.waitForTimeout(300);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second approach: Find the action bar and click its last button
|
||||
const actionBar = assistantMessage.locator('[role="menubar"]');
|
||||
const actionBarCount = await actionBar.count();
|
||||
console.log(` 📍 Found ${actionBarCount} action bars in message`);
|
||||
|
||||
if (actionBarCount > 0) {
|
||||
// Find all clickable elements (button, span with onClick, etc.)
|
||||
const clickables = actionBar.locator('button, span[role="button"], [class*="action"]');
|
||||
const clickableCount = await clickables.count();
|
||||
console.log(` 📍 Found ${clickableCount} clickable elements in action bar`);
|
||||
|
||||
if (clickableCount > 0) {
|
||||
// Click the last one (usually "more")
|
||||
await clickables.last().click();
|
||||
console.log(' ✅ 已点击更多操作按钮 (last clickable)');
|
||||
await this.page.waitForTimeout(300);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Third approach: Find buttons by looking for all SVG icons in the message area
|
||||
const allSvgButtons = this.page.locator('.message-wrapper svg').locator('..');
|
||||
const svgButtonCount = await allSvgButtons.count();
|
||||
console.log(` 📍 Found ${svgButtonCount} SVG button parents in message wrappers`);
|
||||
|
||||
if (svgButtonCount > 0 && messageBox) {
|
||||
// Find the rightmost button in the action area (more button is usually last)
|
||||
let rightmostBtn = null;
|
||||
let maxX = 0;
|
||||
|
||||
for (let i = 0; i < svgButtonCount; i++) {
|
||||
const btn = allSvgButtons.nth(i);
|
||||
const box = await btn.boundingBox();
|
||||
if (box && box.width > 0 && box.height > 0 && box.width < 50 && // Only consider small buttons (action icons are small)
|
||||
|
||||
box.x > 320 &&
|
||||
box.y >= messageBox.y &&
|
||||
box.y <= messageBox.y + messageBox.height + 50
|
||||
&& box.x > maxX) {
|
||||
maxX = box.x;
|
||||
rightmostBtn = btn;
|
||||
}
|
||||
}
|
||||
|
||||
if (rightmostBtn) {
|
||||
await rightmostBtn.click();
|
||||
console.log(` ✅ 已点击更多操作按钮 (rightmost at x=${maxX})`);
|
||||
await this.page.waitForTimeout(300);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Could not find more button in message action bar');
|
||||
});
|
||||
|
||||
When('用户选择删除消息选项', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 选择删除消息选项...');
|
||||
|
||||
// Find and click delete option (exact match to avoid "删除并重新生成")
|
||||
const deleteOption = this.page.getByRole('menuitem', { exact: true, name: '删除' });
|
||||
await expect(deleteOption).toBeVisible({ timeout: 5000 });
|
||||
await deleteOption.click();
|
||||
|
||||
console.log(' ✅ 已选择删除消息选项');
|
||||
await this.page.waitForTimeout(300);
|
||||
});
|
||||
|
||||
When('用户确认删除消息', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 确认删除消息...');
|
||||
|
||||
// A confirmation popconfirm might appear
|
||||
const confirmButton = this.page.locator('.ant-popconfirm-buttons button.ant-btn-dangerous');
|
||||
|
||||
if ((await confirmButton.count()) > 0) {
|
||||
await confirmButton.click();
|
||||
console.log(' ✅ 已确认删除消息');
|
||||
} else {
|
||||
// If no popconfirm, deletion might be immediate
|
||||
console.log(' ✅ 删除操作已执行(无需确认)');
|
||||
}
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户选择折叠消息选项', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 选择折叠消息选项...');
|
||||
|
||||
// The collapse option is "收起消息" in the menu
|
||||
const collapseOption = this.page.getByRole('menuitem', { name: /收起消息/ });
|
||||
await expect(collapseOption).toBeVisible({ timeout: 5000 });
|
||||
await collapseOption.click();
|
||||
|
||||
console.log(' ✅ 已选择折叠消息选项');
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('用户选择展开消息选项', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 选择展开消息选项...');
|
||||
|
||||
// The expand option is "展开消息" in the menu
|
||||
const expandOption = this.page.getByRole('menuitem', { name: /展开消息/ });
|
||||
await expect(expandOption).toBeVisible({ timeout: 5000 });
|
||||
await expandOption.click();
|
||||
|
||||
console.log(' ✅ 已选择展开消息选项');
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Then Steps
|
||||
// ============================================
|
||||
|
||||
Then('消息内容应该被复制到剪贴板', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证消息已复制到剪贴板...');
|
||||
|
||||
// Check for success message/toast
|
||||
const successMessage = this.page.locator('.ant-message-success, [class*="toast"]');
|
||||
|
||||
// Wait briefly for any success notification
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
// Verify by checking if clipboard has content (or success message appeared)
|
||||
const successCount = await successMessage.count();
|
||||
if (successCount > 0) {
|
||||
console.log(' ✅ 显示复制成功提示');
|
||||
} else {
|
||||
// Just verify the action completed without error
|
||||
console.log(' ✅ 复制操作已完成');
|
||||
}
|
||||
});
|
||||
|
||||
Then('消息内容应该更新为 {string}', async function (this: CustomWorld, expectedContent: string) {
|
||||
console.log(` 📍 Step: 验证消息内容为 "${expectedContent}"...`);
|
||||
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
// Find the updated message content
|
||||
const messageContent = this.page.getByText(expectedContent);
|
||||
await expect(messageContent).toBeVisible({ timeout: 5000 });
|
||||
|
||||
console.log(` ✅ 消息内容已更新为 "${expectedContent}"`);
|
||||
});
|
||||
|
||||
Then('该消息应该从对话中移除', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证消息已移除...');
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
// The assistant message count should be reduced
|
||||
// Or verify the specific message content is gone
|
||||
const assistantMessages = this.page.locator('[data-role="assistant"]');
|
||||
const count = await assistantMessages.count();
|
||||
|
||||
console.log(` 📍 剩余助手消息数量: ${count}`);
|
||||
console.log(' ✅ 消息已移除');
|
||||
});
|
||||
|
||||
Then('消息内容应该被折叠', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证消息已折叠...');
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
// Look for collapsed indicator or truncated content
|
||||
const collapsedIndicator = this.page.locator(
|
||||
'[class*="collapsed"], [class*="truncate"], svg.lucide-chevron-down',
|
||||
);
|
||||
const hasCollapsed = (await collapsedIndicator.count()) > 0;
|
||||
|
||||
if (hasCollapsed) {
|
||||
console.log(' ✅ 消息已折叠');
|
||||
} else {
|
||||
// Alternative verification: content height should be reduced
|
||||
console.log(' ✅ 消息折叠操作已执行');
|
||||
}
|
||||
});
|
||||
|
||||
Then('消息内容应该完整显示', async function (this: CustomWorld) {
|
||||
console.log(' 📍 Step: 验证消息完整显示...');
|
||||
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
// The message content should be fully visible
|
||||
const assistantMessage = await findAssistantMessage(this.page);
|
||||
await expect(assistantMessage).toBeVisible();
|
||||
|
||||
console.log(' ✅ 消息内容完整显示');
|
||||
});
|
||||
@@ -1,100 +0,0 @@
|
||||
import { Given, When } from '@cucumber/cucumber';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
import { TEST_USER, createTestSession } from '../../support/seedTestUser';
|
||||
import { CustomWorld } from '../../support/world';
|
||||
|
||||
/**
|
||||
* Login via UI - fills in the login form and submits
|
||||
*/
|
||||
Given('I am logged in as the test user', async function (this: CustomWorld) {
|
||||
// Navigate to signin page
|
||||
await this.page.goto('/signin');
|
||||
|
||||
// Wait for the login form to be visible
|
||||
await this.page.waitForSelector('input[type="email"], input[name="email"]', { timeout: 30_000 });
|
||||
|
||||
// Fill in email
|
||||
await this.page.fill('input[type="email"], input[name="email"]', TEST_USER.email);
|
||||
|
||||
// Fill in password
|
||||
await this.page.fill('input[type="password"], input[name="password"]', TEST_USER.password);
|
||||
|
||||
// Click submit button
|
||||
await this.page.click('button[type="submit"]');
|
||||
|
||||
// Wait for navigation away from signin page
|
||||
await this.page.waitForURL((url) => !url.pathname.includes('/signin'), { timeout: 30_000 });
|
||||
|
||||
console.log('✅ Logged in as test user via UI');
|
||||
});
|
||||
|
||||
/**
|
||||
* Login via session injection - faster, bypasses UI
|
||||
* Creates a session directly in the database and sets the cookie
|
||||
*/
|
||||
Given('I am logged in with a session', async function (this: CustomWorld) {
|
||||
const sessionToken = await createTestSession();
|
||||
|
||||
if (!sessionToken) {
|
||||
throw new Error('Failed to create test session');
|
||||
}
|
||||
|
||||
// Set the session cookie (Better Auth uses 'better-auth.session_token' by default)
|
||||
await this.browserContext.addCookies([
|
||||
{
|
||||
domain: 'localhost',
|
||||
httpOnly: true,
|
||||
name: 'better-auth.session_token',
|
||||
path: '/',
|
||||
sameSite: 'Lax',
|
||||
secure: false,
|
||||
value: sessionToken,
|
||||
},
|
||||
]);
|
||||
|
||||
console.log('✅ Session cookie set for test user');
|
||||
});
|
||||
|
||||
/**
|
||||
* Navigate to signin page
|
||||
*/
|
||||
When('I navigate to the signin page', async function (this: CustomWorld) {
|
||||
await this.page.goto('/signin');
|
||||
await this.page.waitForLoadState('networkidle');
|
||||
});
|
||||
|
||||
/**
|
||||
* Fill in login credentials
|
||||
*/
|
||||
When('I enter the test user credentials', async function (this: CustomWorld) {
|
||||
await this.page.fill('input[type="email"], input[name="email"]', TEST_USER.email);
|
||||
await this.page.fill('input[type="password"], input[name="password"]', TEST_USER.password);
|
||||
});
|
||||
|
||||
/**
|
||||
* Submit the login form
|
||||
*/
|
||||
When('I submit the login form', async function (this: CustomWorld) {
|
||||
await this.page.click('button[type="submit"]');
|
||||
});
|
||||
|
||||
/**
|
||||
* Verify login was successful
|
||||
*/
|
||||
Given('I should be logged in', async function (this: CustomWorld) {
|
||||
// Check we're not on signin page anymore
|
||||
await expect(this.page).not.toHaveURL(/\/signin/);
|
||||
|
||||
// Optionally check for user menu or other logged-in indicators
|
||||
console.log('✅ User is logged in');
|
||||
});
|
||||
|
||||
/**
|
||||
* Logout the current user
|
||||
*/
|
||||
When('I logout', async function (this: CustomWorld) {
|
||||
// Clear cookies to logout
|
||||
await this.browserContext.clearCookies();
|
||||
console.log('✅ User logged out (cookies cleared)');
|
||||
});
|
||||
@@ -8,7 +8,7 @@ import { CustomWorld } from '../../support/world';
|
||||
// ============================================
|
||||
|
||||
Given('I wait for the page to fully load', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
await this.page.waitForTimeout(1000);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ Given('I wait for the page to fully load', async function (this: CustomWorld) {
|
||||
// ============================================
|
||||
|
||||
When('I click the back button', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Try to find a back button
|
||||
const backButton = this.page
|
||||
@@ -34,7 +34,7 @@ When('I click the back button', async function (this: CustomWorld) {
|
||||
await this.page.goBack();
|
||||
}
|
||||
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
});
|
||||
|
||||
// ============================================
|
||||
@@ -43,7 +43,7 @@ When('I click the back button', async function (this: CustomWorld) {
|
||||
|
||||
// Assistant Detail Page Assertions
|
||||
Then('I should be on an assistant detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL matches assistant detail page pattern
|
||||
@@ -55,13 +55,13 @@ Then('I should be on an assistant detail page', async function (this: CustomWorl
|
||||
});
|
||||
|
||||
Then('I should see the assistant title', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for title element (h1, h2, or prominent text)
|
||||
const title = this.page
|
||||
.locator('h1, h2, [data-testid="detail-title"], [data-testid="assistant-title"]')
|
||||
.first();
|
||||
await expect(title).toBeVisible({ timeout: 30_000 });
|
||||
await expect(title).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Verify title has content
|
||||
const titleText = await title.textContent();
|
||||
@@ -69,7 +69,7 @@ Then('I should see the assistant title', async function (this: CustomWorld) {
|
||||
});
|
||||
|
||||
Then('I should see the assistant description', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for description element
|
||||
const description = this.page
|
||||
@@ -77,11 +77,11 @@ Then('I should see the assistant description', async function (this: CustomWorld
|
||||
'p, [data-testid="detail-description"], [data-testid="assistant-description"], .description',
|
||||
)
|
||||
.first();
|
||||
await expect(description).toBeVisible({ timeout: 30_000 });
|
||||
await expect(description).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see the assistant author information', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for author information
|
||||
const author = this.page
|
||||
@@ -95,7 +95,7 @@ Then('I should see the assistant author information', async function (this: Cust
|
||||
});
|
||||
|
||||
Then('I should see the add to workspace button', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for add button (might be "Add", "Install", "Add to Workspace", etc.)
|
||||
const addButton = this.page
|
||||
@@ -110,19 +110,18 @@ Then('I should see the add to workspace button', async function (this: CustomWor
|
||||
});
|
||||
|
||||
Then('I should be on the assistant list page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL is assistant list (not detail page)
|
||||
const isListPage =
|
||||
currentUrl.includes('/community/assistant') &&
|
||||
!/\/discover\/assistant\/[^#?]+/.test(currentUrl);
|
||||
currentUrl.includes('/discover/assistant') && !/\/discover\/assistant\/[^#?]+/.test(currentUrl);
|
||||
expect(isListPage, `Expected URL to be assistant list page, but got: ${currentUrl}`).toBeTruthy();
|
||||
});
|
||||
|
||||
// Model Detail Page Assertions
|
||||
Then('I should be on a model detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL matches model detail page pattern
|
||||
@@ -134,30 +133,30 @@ Then('I should be on a model detail page', async function (this: CustomWorld) {
|
||||
});
|
||||
|
||||
Then('I should see the model title', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const title = this.page
|
||||
.locator('h1, h2, [data-testid="detail-title"], [data-testid="model-title"]')
|
||||
.first();
|
||||
await expect(title).toBeVisible({ timeout: 30_000 });
|
||||
await expect(title).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
const titleText = await title.textContent();
|
||||
expect(titleText?.trim().length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
Then('I should see the model description', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const description = this.page
|
||||
.locator(
|
||||
'p, [data-testid="detail-description"], [data-testid="model-description"], .description',
|
||||
)
|
||||
.first();
|
||||
await expect(description).toBeVisible({ timeout: 30_000 });
|
||||
await expect(description).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see the model parameters information', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for parameters or specs section
|
||||
const params = this.page
|
||||
@@ -170,18 +169,18 @@ Then('I should see the model parameters information', async function (this: Cust
|
||||
});
|
||||
|
||||
Then('I should be on the model list page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL is model list (not detail page)
|
||||
const isListPage =
|
||||
currentUrl.includes('/community/model') && !/\/discover\/model\/[^#?]+/.test(currentUrl);
|
||||
currentUrl.includes('/discover/model') && !/\/discover\/model\/[^#?]+/.test(currentUrl);
|
||||
expect(isListPage, `Expected URL to be model list page, but got: ${currentUrl}`).toBeTruthy();
|
||||
});
|
||||
|
||||
// Provider Detail Page Assertions
|
||||
Then('I should be on a provider detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL matches provider detail page pattern
|
||||
@@ -193,30 +192,30 @@ Then('I should be on a provider detail page', async function (this: CustomWorld)
|
||||
});
|
||||
|
||||
Then('I should see the provider title', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const title = this.page
|
||||
.locator('h1, h2, [data-testid="detail-title"], [data-testid="provider-title"]')
|
||||
.first();
|
||||
await expect(title).toBeVisible({ timeout: 30_000 });
|
||||
await expect(title).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
const titleText = await title.textContent();
|
||||
expect(titleText?.trim().length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
Then('I should see the provider description', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const description = this.page
|
||||
.locator(
|
||||
'p, [data-testid="detail-description"], [data-testid="provider-description"], .description',
|
||||
)
|
||||
.first();
|
||||
await expect(description).toBeVisible({ timeout: 30_000 });
|
||||
await expect(description).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see the provider website link', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for website link
|
||||
const websiteLink = this.page
|
||||
@@ -229,18 +228,18 @@ Then('I should see the provider website link', async function (this: CustomWorld
|
||||
});
|
||||
|
||||
Then('I should be on the provider list page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL is provider list (not detail page)
|
||||
const isListPage =
|
||||
currentUrl.includes('/community/provider') && !/\/discover\/provider\/[^#?]+/.test(currentUrl);
|
||||
currentUrl.includes('/discover/provider') && !/\/discover\/provider\/[^#?]+/.test(currentUrl);
|
||||
expect(isListPage, `Expected URL to be provider list page, but got: ${currentUrl}`).toBeTruthy();
|
||||
});
|
||||
|
||||
// MCP Detail Page Assertions
|
||||
Then('I should be on an MCP detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL matches MCP detail page pattern
|
||||
@@ -252,28 +251,28 @@ Then('I should be on an MCP detail page', async function (this: CustomWorld) {
|
||||
});
|
||||
|
||||
Then('I should see the MCP title', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const title = this.page
|
||||
.locator('h1, h2, [data-testid="detail-title"], [data-testid="mcp-title"]')
|
||||
.first();
|
||||
await expect(title).toBeVisible({ timeout: 30_000 });
|
||||
await expect(title).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
const titleText = await title.textContent();
|
||||
expect(titleText?.trim().length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
Then('I should see the MCP description', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const description = this.page
|
||||
.locator('p, [data-testid="detail-description"], [data-testid="mcp-description"], .description')
|
||||
.first();
|
||||
await expect(description).toBeVisible({ timeout: 30_000 });
|
||||
await expect(description).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see the install button', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for install button
|
||||
const installButton = this.page
|
||||
@@ -286,11 +285,11 @@ Then('I should see the install button', async function (this: CustomWorld) {
|
||||
});
|
||||
|
||||
Then('I should be on the MCP list page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Check if URL is MCP list (not detail page)
|
||||
const isListPage =
|
||||
currentUrl.includes('/community/mcp') && !/\/discover\/mcp\/[^#?]+/.test(currentUrl);
|
||||
currentUrl.includes('/discover/mcp') && !/\/discover\/mcp\/[^#?]+/.test(currentUrl);
|
||||
expect(isListPage, `Expected URL to be MCP list page, but got: ${currentUrl}`).toBeTruthy();
|
||||
});
|
||||
|
||||
@@ -8,10 +8,10 @@ import { CustomWorld } from '../../support/world';
|
||||
// ============================================
|
||||
|
||||
When('I type {string} in the search bar', async function (this: CustomWorld, searchText: string) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const searchBar = this.page.locator('input[type="text"]').first();
|
||||
await searchBar.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await searchBar.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
await searchBar.fill(searchText);
|
||||
|
||||
// Store the search text for later assertions
|
||||
@@ -20,13 +20,13 @@ When('I type {string} in the search bar', async function (this: CustomWorld, sea
|
||||
|
||||
When('I wait for the search results to load', async function (this: CustomWorld) {
|
||||
// Wait for network to be idle after typing
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
// Add a small delay to ensure UI updates
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('I click on a category in the category menu', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Find the category menu and click the first non-active category
|
||||
const categoryItems = this.page.locator(
|
||||
@@ -34,7 +34,7 @@ When('I click on a category in the category menu', async function (this: CustomW
|
||||
);
|
||||
|
||||
// Wait for categories to be visible
|
||||
await categoryItems.first().waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await categoryItems.first().waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Click the second category (skip "All" which is usually first)
|
||||
const secondCategory = categoryItems.nth(1);
|
||||
@@ -46,7 +46,7 @@ When('I click on a category in the category menu', async function (this: CustomW
|
||||
});
|
||||
|
||||
When('I click on a category in the category filter', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Find the category filter and click a category
|
||||
const categoryItems = this.page.locator(
|
||||
@@ -54,7 +54,7 @@ When('I click on a category in the category filter', async function (this: Custo
|
||||
);
|
||||
|
||||
// Wait for categories to be visible
|
||||
await categoryItems.first().waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await categoryItems.first().waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Click the second category (skip "All" which is usually first)
|
||||
const secondCategory = categoryItems.nth(1);
|
||||
@@ -67,35 +67,35 @@ When('I click on a category in the category filter', async function (this: Custo
|
||||
|
||||
When('I wait for the filtered results to load', async function (this: CustomWorld) {
|
||||
// Wait for network to be idle after filtering
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
// Add a small delay to ensure UI updates
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('I click the next page button', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Find and click the next page button
|
||||
const nextButton = this.page.locator(
|
||||
'button:has-text("Next"), button[aria-label*="next" i], .pagination button:last-child',
|
||||
);
|
||||
|
||||
await nextButton.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await nextButton.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
await nextButton.click();
|
||||
});
|
||||
|
||||
When('I wait for the next page to load', async function (this: CustomWorld) {
|
||||
// Wait for network to be idle after page change
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
// Add a small delay to ensure UI updates
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
|
||||
When('I click on the first assistant card', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const firstCard = this.page.locator('[data-testid="assistant-item"]').first();
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Store the current URL before clicking
|
||||
this.testContext.previousUrl = this.page.url();
|
||||
@@ -106,15 +106,15 @@ When('I click on the first assistant card', async function (this: CustomWorld) {
|
||||
await this.page.waitForFunction(
|
||||
(previousUrl) => window.location.href !== previousUrl,
|
||||
this.testContext.previousUrl,
|
||||
{ timeout: 30_000 },
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
});
|
||||
|
||||
When('I click on the first model card', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const firstCard = this.page.locator('[data-testid="model-item"]').first();
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Store the current URL before clicking
|
||||
this.testContext.previousUrl = this.page.url();
|
||||
@@ -125,15 +125,15 @@ When('I click on the first model card', async function (this: CustomWorld) {
|
||||
await this.page.waitForFunction(
|
||||
(previousUrl) => window.location.href !== previousUrl,
|
||||
this.testContext.previousUrl,
|
||||
{ timeout: 30_000 },
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
});
|
||||
|
||||
When('I click on the first provider card', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const firstCard = this.page.locator('[data-testid="provider-item"]').first();
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Store the current URL before clicking
|
||||
this.testContext.previousUrl = this.page.url();
|
||||
@@ -144,15 +144,15 @@ When('I click on the first provider card', async function (this: CustomWorld) {
|
||||
await this.page.waitForFunction(
|
||||
(previousUrl) => window.location.href !== previousUrl,
|
||||
this.testContext.previousUrl,
|
||||
{ timeout: 30_000 },
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
});
|
||||
|
||||
When('I click on the first MCP card', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const firstCard = this.page.locator('[data-testid="mcp-item"]').first();
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Store the current URL before clicking
|
||||
this.testContext.previousUrl = this.page.url();
|
||||
@@ -163,12 +163,12 @@ When('I click on the first MCP card', async function (this: CustomWorld) {
|
||||
await this.page.waitForFunction(
|
||||
(previousUrl) => window.location.href !== previousUrl,
|
||||
this.testContext.previousUrl,
|
||||
{ timeout: 30_000 },
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
});
|
||||
|
||||
When('I click on the sort dropdown', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const sortDropdown = this.page
|
||||
.locator(
|
||||
@@ -176,7 +176,7 @@ When('I click on the sort dropdown', async function (this: CustomWorld) {
|
||||
)
|
||||
.first();
|
||||
|
||||
await sortDropdown.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await sortDropdown.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
await sortDropdown.click();
|
||||
});
|
||||
|
||||
@@ -187,7 +187,7 @@ When('I select a sort option', async function (this: CustomWorld) {
|
||||
const sortOptions = this.page.locator('[role="option"], [role="menuitem"]');
|
||||
|
||||
// Wait for options to appear
|
||||
await sortOptions.first().waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await sortOptions.first().waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Click the second option (skip the default/first one)
|
||||
const secondOption = sortOptions.nth(1);
|
||||
@@ -200,7 +200,7 @@ When('I select a sort option', async function (this: CustomWorld) {
|
||||
|
||||
When('I wait for the sorted results to load', async function (this: CustomWorld) {
|
||||
// Wait for network to be idle after sorting
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
// Add a small delay to ensure UI updates
|
||||
await this.page.waitForTimeout(500);
|
||||
});
|
||||
@@ -208,14 +208,14 @@ When('I wait for the sorted results to load', async function (this: CustomWorld)
|
||||
When(
|
||||
'I click on the {string} link in the featured assistants section',
|
||||
async function (this: CustomWorld, linkText: string) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Find the featured assistants section and the "more" link
|
||||
const moreLink = this.page
|
||||
.locator(`a:has-text("${linkText}"), button:has-text("${linkText}")`)
|
||||
.first();
|
||||
|
||||
await moreLink.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await moreLink.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
await moreLink.click();
|
||||
},
|
||||
);
|
||||
@@ -223,7 +223,7 @@ When(
|
||||
When(
|
||||
'I click on the {string} link in the featured MCP tools section',
|
||||
async function (this: CustomWorld, linkText: string) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Find the MCP section and the "more" link
|
||||
// Since there might be multiple "more" links, we'll click the second one (MCP is after assistants)
|
||||
@@ -232,7 +232,7 @@ When(
|
||||
);
|
||||
|
||||
// Wait for links to be visible
|
||||
await moreLinks.first().waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await moreLinks.first().waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Click the second "more" link (for MCP section)
|
||||
await moreLinks.nth(1).click();
|
||||
@@ -240,10 +240,10 @@ When(
|
||||
);
|
||||
|
||||
When('I click on the first featured assistant card', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const firstCard = this.page.locator('[data-testid="assistant-item"]').first();
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await firstCard.waitFor({ state: 'visible', timeout: 120_000 });
|
||||
|
||||
// Store the current URL before clicking
|
||||
this.testContext.previousUrl = this.page.url();
|
||||
@@ -254,7 +254,7 @@ When('I click on the first featured assistant card', async function (this: Custo
|
||||
await this.page.waitForFunction(
|
||||
(previousUrl) => window.location.href !== previousUrl,
|
||||
this.testContext.previousUrl,
|
||||
{ timeout: 30_000 },
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
});
|
||||
|
||||
@@ -263,12 +263,12 @@ When('I click on the first featured assistant card', async function (this: Custo
|
||||
// ============================================
|
||||
|
||||
Then('I should see filtered assistant cards', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 30_000 });
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Verify that at least one item exists
|
||||
const count = await assistantItems.count();
|
||||
@@ -278,12 +278,12 @@ Then('I should see filtered assistant cards', async function (this: CustomWorld)
|
||||
Then(
|
||||
'I should see assistant cards filtered by the selected category',
|
||||
async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 30_000 });
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Verify that at least one item exists
|
||||
const count = await assistantItems.count();
|
||||
@@ -301,12 +301,12 @@ Then('the URL should contain the category parameter', async function (this: Cust
|
||||
});
|
||||
|
||||
Then('I should see different assistant cards', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 30_000 });
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Verify that at least one item exists
|
||||
const count = await assistantItems.count();
|
||||
@@ -323,7 +323,7 @@ Then('the URL should contain the page parameter', async function (this: CustomWo
|
||||
});
|
||||
|
||||
Then('I should be navigated to the assistant detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Verify that URL changed and contains /assistant/ followed by an identifier
|
||||
@@ -337,20 +337,20 @@ Then('I should be navigated to the assistant detail page', async function (this:
|
||||
});
|
||||
|
||||
Then('I should see the assistant detail content', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for detail page elements (e.g., title, description, etc.)
|
||||
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
|
||||
await expect(detailContent).toBeVisible({ timeout: 30_000 });
|
||||
await expect(detailContent).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see model cards in the sorted order', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const modelItems = this.page.locator('[data-testid="model-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(modelItems.first()).toBeVisible({ timeout: 30_000 });
|
||||
await expect(modelItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Verify that at least one item exists
|
||||
const count = await modelItems.count();
|
||||
@@ -358,7 +358,7 @@ Then('I should see model cards in the sorted order', async function (this: Custo
|
||||
});
|
||||
|
||||
Then('I should be navigated to the model detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Verify that URL changed and contains /model/ followed by an identifier
|
||||
@@ -372,15 +372,15 @@ Then('I should be navigated to the model detail page', async function (this: Cus
|
||||
});
|
||||
|
||||
Then('I should see the model detail content', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for detail page elements
|
||||
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
|
||||
await expect(detailContent).toBeVisible({ timeout: 30_000 });
|
||||
await expect(detailContent).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should be navigated to the provider detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Verify that URL changed and contains /provider/ followed by an identifier
|
||||
@@ -394,22 +394,22 @@ Then('I should be navigated to the provider detail page', async function (this:
|
||||
});
|
||||
|
||||
Then('I should see the provider detail content', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for detail page elements
|
||||
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
|
||||
await expect(detailContent).toBeVisible({ timeout: 30_000 });
|
||||
await expect(detailContent).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then(
|
||||
'I should see MCP cards filtered by the selected category',
|
||||
async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const mcpItems = this.page.locator('[data-testid="mcp-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(mcpItems.first()).toBeVisible({ timeout: 30_000 });
|
||||
await expect(mcpItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Verify that at least one item exists
|
||||
const count = await mcpItems.count();
|
||||
@@ -418,7 +418,7 @@ Then(
|
||||
);
|
||||
|
||||
Then('I should be navigated to the MCP detail page', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Verify that URL changed and contains /mcp/ followed by an identifier
|
||||
@@ -432,15 +432,15 @@ Then('I should be navigated to the MCP detail page', async function (this: Custo
|
||||
});
|
||||
|
||||
Then('I should see the MCP detail content', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for detail page elements
|
||||
const detailContent = this.page.locator('[data-testid="detail-content"], main, article').first();
|
||||
await expect(detailContent).toBeVisible({ timeout: 30_000 });
|
||||
await expect(detailContent).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should be navigated to {string}', async function (this: CustomWorld, expectedPath: string) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
const currentUrl = this.page.url();
|
||||
// Verify that URL contains the expected path
|
||||
|
||||
@@ -9,50 +9,55 @@ import { CustomWorld } from '../../support/world';
|
||||
|
||||
// Home Page Steps
|
||||
Then('I should see the featured assistants section', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for "Featured Agents" heading text (i18n key: home.featuredAssistants)
|
||||
// Supports: en-US "Featured Agents", zh-CN "推荐助理"
|
||||
// Look for featured assistants section by data-testid or heading
|
||||
const featuredSection = this.page
|
||||
.getByRole('heading', { name: /featured agents|推荐助理/i })
|
||||
.locator(
|
||||
'[data-testid="featured-assistants"], h2:has-text("Featured"), h3:has-text("Featured")',
|
||||
)
|
||||
.first();
|
||||
await expect(featuredSection).toBeVisible({ timeout: 10_000 });
|
||||
await expect(featuredSection).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see the featured MCP tools section', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for "Featured Skills" heading text (i18n key: home.featuredTools)
|
||||
// Supports: en-US "Featured Skills", zh-CN "推荐技能"
|
||||
const mcpSection = this.page.getByRole('heading', { name: /featured skills|推荐技能/i }).first();
|
||||
await expect(mcpSection).toBeVisible({ timeout: 10_000 });
|
||||
// Look for featured MCP section by data-testid or heading
|
||||
const mcpSection = this.page
|
||||
.locator('[data-testid="featured-mcp"], h2:has-text("MCP"), h3:has-text("MCP")')
|
||||
.first();
|
||||
await expect(mcpSection).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
// Assistant List Page Steps
|
||||
Then('I should see the search bar', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// SearchBar component has data-testid="search-bar"
|
||||
const searchBar = this.page.locator('[data-testid="search-bar"]').first();
|
||||
await expect(searchBar).toBeVisible({ timeout: 10_000 });
|
||||
// The SearchBar component from @lobehub/ui may not pass through data-testid
|
||||
// Try to find the input element within the search component
|
||||
const searchBar = this.page.locator('input[type="text"]').first();
|
||||
await expect(searchBar).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see the category menu', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// CategoryMenu component has data-testid="category-menu"
|
||||
const categoryMenu = this.page.locator('[data-testid="category-menu"]').first();
|
||||
await expect(categoryMenu).toBeVisible({ timeout: 10_000 });
|
||||
// Look for category menu/filter by data-testid or role
|
||||
const categoryMenu = this.page
|
||||
.locator('[data-testid="category-menu"], [role="menu"], nav[aria-label*="categor" i]')
|
||||
.first();
|
||||
await expect(categoryMenu).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
Then('I should see assistant cards', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for assistant items by data-testid
|
||||
const assistantItems = this.page.locator('[data-testid="assistant-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 10_000 });
|
||||
await expect(assistantItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Check we have multiple items
|
||||
const count = await assistantItems.count();
|
||||
@@ -60,22 +65,26 @@ Then('I should see assistant cards', async function (this: CustomWorld) {
|
||||
});
|
||||
|
||||
Then('I should see pagination controls', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Pagination component has data-testid="pagination"
|
||||
const pagination = this.page.locator('[data-testid="pagination"]').first();
|
||||
await expect(pagination).toBeVisible({ timeout: 10_000 });
|
||||
// Look for pagination controls by data-testid, role, or common pagination elements
|
||||
const pagination = this.page
|
||||
.locator(
|
||||
'[data-testid="pagination"], nav[aria-label*="pagination" i], .pagination, button:has-text("Next"), button:has-text("Previous")',
|
||||
)
|
||||
.first();
|
||||
await expect(pagination).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
// Model List Page Steps
|
||||
Then('I should see model cards', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Model items have data-testid="model-item"
|
||||
// Look for model items by data-testid
|
||||
const modelItems = this.page.locator('[data-testid="model-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(modelItems.first()).toBeVisible({ timeout: 10_000 });
|
||||
await expect(modelItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Check we have multiple items
|
||||
const count = await modelItems.count();
|
||||
@@ -83,22 +92,26 @@ Then('I should see model cards', async function (this: CustomWorld) {
|
||||
});
|
||||
|
||||
Then('I should see the sort dropdown', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// SortButton has data-testid="sort-dropdown"
|
||||
const sortDropdown = this.page.locator('[data-testid="sort-dropdown"]').first();
|
||||
await expect(sortDropdown).toBeVisible({ timeout: 10_000 });
|
||||
// Look for sort dropdown by data-testid, role, or select element
|
||||
const sortDropdown = this.page
|
||||
.locator(
|
||||
'[data-testid="sort-dropdown"], select, button[aria-label*="sort" i], [role="combobox"]',
|
||||
)
|
||||
.first();
|
||||
await expect(sortDropdown).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
// Provider List Page Steps
|
||||
Then('I should see provider cards', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for provider items by data-testid
|
||||
const providerItems = this.page.locator('[data-testid="provider-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(providerItems.first()).toBeVisible({ timeout: 10_000 });
|
||||
await expect(providerItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Check we have multiple items
|
||||
const count = await providerItems.count();
|
||||
@@ -107,13 +120,13 @@ Then('I should see provider cards', async function (this: CustomWorld) {
|
||||
|
||||
// MCP List Page Steps
|
||||
Then('I should see MCP cards', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// Look for MCP items by data-testid
|
||||
const mcpItems = this.page.locator('[data-testid="mcp-item"]');
|
||||
|
||||
// Wait for at least one item to be visible
|
||||
await expect(mcpItems.first()).toBeVisible({ timeout: 10_000 });
|
||||
await expect(mcpItems.first()).toBeVisible({ timeout: 120_000 });
|
||||
|
||||
// Check we have multiple items
|
||||
const count = await mcpItems.count();
|
||||
@@ -121,9 +134,13 @@ Then('I should see MCP cards', async function (this: CustomWorld) {
|
||||
});
|
||||
|
||||
Then('I should see the category filter', async function (this: CustomWorld) {
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 10_000 });
|
||||
await this.page.waitForLoadState('networkidle', { timeout: 120_000 });
|
||||
|
||||
// CategoryMenu component has data-testid="category-menu" (shared across list pages)
|
||||
const categoryFilter = this.page.locator('[data-testid="category-menu"]').first();
|
||||
await expect(categoryFilter).toBeVisible({ timeout: 10_000 });
|
||||
// Look for category filter by data-testid or similar to category menu
|
||||
const categoryFilter = this.page
|
||||
.locator(
|
||||
'[data-testid="category-filter"], [data-testid="category-menu"], [role="menu"], nav[aria-label*="categor" i]',
|
||||
)
|
||||
.first();
|
||||
await expect(categoryFilter).toBeVisible({ timeout: 120_000 });
|
||||
});
|
||||
|
||||
+7
-68
@@ -1,80 +1,28 @@
|
||||
import { After, AfterAll, Before, BeforeAll, Status, setDefaultTimeout } from '@cucumber/cucumber';
|
||||
import { type Cookie, chromium } from 'playwright';
|
||||
|
||||
import { TEST_USER, seedTestUser } from '../support/seedTestUser';
|
||||
import { startWebServer, stopWebServer } from '../support/webServer';
|
||||
import { CustomWorld } from '../support/world';
|
||||
|
||||
process.env['E2E'] = '1';
|
||||
// Set default timeout for all steps to 10 seconds
|
||||
setDefaultTimeout(10_000);
|
||||
// Set default timeout for all steps to 120 seconds
|
||||
setDefaultTimeout(120_000);
|
||||
|
||||
// Store base URL and cached session cookies
|
||||
let baseUrl: string;
|
||||
let sessionCookies: Cookie[] = [];
|
||||
|
||||
BeforeAll({ timeout: 600_000 }, async function () {
|
||||
BeforeAll({ timeout: 120_000 }, async function () {
|
||||
console.log('🚀 Starting E2E test suite...');
|
||||
|
||||
const PORT = process.env.PORT ? Number(process.env.PORT) : 3006;
|
||||
baseUrl = process.env.BASE_URL || `http://localhost:${PORT}`;
|
||||
const PORT = process.env.PORT ? Number(process.env.PORT) : 3010;
|
||||
const BASE_URL = process.env.BASE_URL || `http://localhost:${PORT}`;
|
||||
|
||||
console.log(`Base URL: ${baseUrl}`);
|
||||
|
||||
// Seed test user before starting web server
|
||||
await seedTestUser();
|
||||
console.log(`Base URL: ${BASE_URL}`);
|
||||
|
||||
// Start web server if not using external BASE_URL
|
||||
if (!process.env.BASE_URL) {
|
||||
await startWebServer({
|
||||
command: `bunx next start -p ${PORT}`,
|
||||
command: 'npm run dev',
|
||||
port: PORT,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
timeout: 60_000,
|
||||
});
|
||||
}
|
||||
|
||||
// Login once and cache the session cookies
|
||||
console.log('🔐 Performing one-time login to cache session...');
|
||||
|
||||
const browser = await chromium.launch({ headless: process.env.HEADLESS !== 'false' });
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
|
||||
try {
|
||||
// Navigate to signin page
|
||||
await page.goto(`${baseUrl}/signin`, { waitUntil: 'networkidle' });
|
||||
|
||||
// Step 1: Enter email
|
||||
console.log(' Step 1: Entering email...');
|
||||
const emailInput = page.locator('input[id="email"]').first();
|
||||
await emailInput.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await emailInput.fill(TEST_USER.email);
|
||||
|
||||
// Click the next button
|
||||
const nextButton = page.locator('form button').first();
|
||||
await nextButton.click();
|
||||
|
||||
// Step 2: Wait for password step and enter password
|
||||
console.log(' Step 2: Entering password...');
|
||||
const passwordInput = page.locator('input[id="password"]').first();
|
||||
await passwordInput.waitFor({ state: 'visible', timeout: 30_000 });
|
||||
await passwordInput.fill(TEST_USER.password);
|
||||
|
||||
// Click submit button
|
||||
const submitButton = page.locator('form button').first();
|
||||
await submitButton.click();
|
||||
|
||||
// Wait for navigation away from signin page
|
||||
await page.waitForURL((url) => !url.pathname.includes('/signin'), { timeout: 30_000 });
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// Cache the session cookies
|
||||
sessionCookies = await context.cookies();
|
||||
console.log(`✅ Login successful, cached ${sessionCookies.length} cookies`);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
});
|
||||
|
||||
Before(async function (this: CustomWorld, { pickle }) {
|
||||
@@ -82,15 +30,6 @@ Before(async function (this: CustomWorld, { pickle }) {
|
||||
|
||||
const testId = pickle.tags.find((tag) => tag.name.startsWith('@DISCOVER-'));
|
||||
console.log(`\n📝 Running: ${pickle.name}${testId ? ` (${testId.name.replace('@', '')})` : ''}`);
|
||||
|
||||
// Setup API mocks before any page navigation
|
||||
// await mockManager.setup(this.page);
|
||||
|
||||
// Set cached session cookies to skip login
|
||||
if (sessionCookies.length > 0) {
|
||||
await this.browserContext.addCookies(sessionCookies);
|
||||
console.log('🍪 Session cookies restored');
|
||||
}
|
||||
});
|
||||
|
||||
After(async function (this: CustomWorld, { pickle, result }) {
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
// Test user credentials - these are used for e2e testing only
|
||||
export const TEST_USER = {
|
||||
email: 'e2e-test@lobehub.com',
|
||||
fullName: 'E2E Test User',
|
||||
id: 'user_e2e_test_user_001',
|
||||
password: 'TestPassword123!',
|
||||
username: 'e2e_test_user',
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a bcrypt password hash
|
||||
* Better Auth supports bcrypt for passwords migrated from Clerk
|
||||
*/
|
||||
async function hashPassword(password: string): Promise<string> {
|
||||
return bcrypt.hash(password, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seed test user into the database for e2e testing
|
||||
* This function connects directly to PostgreSQL and creates the necessary records
|
||||
*/
|
||||
export async function seedTestUser(): Promise<void> {
|
||||
const databaseUrl = process.env.DATABASE_URL;
|
||||
|
||||
if (!databaseUrl) {
|
||||
console.log('⚠️ DATABASE_URL not set, skipping test user seeding');
|
||||
return;
|
||||
}
|
||||
|
||||
// Dynamic import pg to avoid bundling issues
|
||||
const { default: pg } = await import('pg');
|
||||
const client = new pg.Client({ connectionString: databaseUrl });
|
||||
|
||||
try {
|
||||
await client.connect();
|
||||
console.log('🔌 Connected to database for test user seeding');
|
||||
|
||||
const now = new Date().toISOString();
|
||||
// Use fixed account ID to avoid conflicts when multiple workers run concurrently
|
||||
const accountId = 'e2e_test_account_001';
|
||||
|
||||
// Use upsert to handle concurrent worker execution
|
||||
// Insert user or do nothing if already exists (handles all unique constraints)
|
||||
const passwordHash = await hashPassword(TEST_USER.password);
|
||||
|
||||
// Use ON CONFLICT DO NOTHING to handle all unique constraint conflicts
|
||||
// This is safe because we're using fixed test user credentials
|
||||
// Set onboarding as completed to skip onboarding flow in tests
|
||||
const onboarding = JSON.stringify({ finishedAt: now, version: 1 });
|
||||
|
||||
await client.query(
|
||||
`INSERT INTO users (id, email, normalized_email, username, full_name, email_verified, onboarding, created_at, updated_at, last_active_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $8, $8)
|
||||
ON CONFLICT (id) DO UPDATE SET onboarding = $7, updated_at = $8`,
|
||||
[
|
||||
TEST_USER.id,
|
||||
TEST_USER.email,
|
||||
TEST_USER.email.toLowerCase(),
|
||||
TEST_USER.username,
|
||||
TEST_USER.fullName,
|
||||
true, // email_verified
|
||||
onboarding,
|
||||
now,
|
||||
],
|
||||
);
|
||||
|
||||
// Create account record with password (for credential login)
|
||||
await client.query(
|
||||
`INSERT INTO accounts (id, user_id, account_id, provider_id, password, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $6)
|
||||
ON CONFLICT DO NOTHING`,
|
||||
[
|
||||
accountId,
|
||||
TEST_USER.id,
|
||||
TEST_USER.email, // account_id is email for credential provider
|
||||
'credential', // provider_id
|
||||
passwordHash,
|
||||
now,
|
||||
],
|
||||
);
|
||||
|
||||
console.log('✅ Test user seeded successfully');
|
||||
console.log(` Email: ${TEST_USER.email}`);
|
||||
console.log(` Password: ${TEST_USER.password}`);
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to seed test user:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
await client.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up test user data after tests
|
||||
*/
|
||||
export async function cleanupTestUser(): Promise<void> {
|
||||
const databaseUrl = process.env.DATABASE_URL;
|
||||
|
||||
if (!databaseUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { default: pg } = await import('pg');
|
||||
const client = new pg.Client({ connectionString: databaseUrl });
|
||||
|
||||
try {
|
||||
await client.connect();
|
||||
|
||||
// Delete sessions first (foreign key)
|
||||
await client.query('DELETE FROM auth_sessions WHERE user_id = $1', [TEST_USER.id]);
|
||||
|
||||
// Delete accounts (foreign key)
|
||||
await client.query('DELETE FROM accounts WHERE user_id = $1', [TEST_USER.id]);
|
||||
|
||||
// Delete user
|
||||
await client.query('DELETE FROM users WHERE id = $1', [TEST_USER.id]);
|
||||
|
||||
console.log('🧹 Test user cleaned up');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to cleanup test user:', error);
|
||||
} finally {
|
||||
await client.end();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
import { type ChildProcess, exec } from 'node:child_process';
|
||||
import { existsSync, unlinkSync, writeFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
let serverProcess: ChildProcess | null = null;
|
||||
let serverStartPromise: Promise<void> | null = null;
|
||||
|
||||
// File-based lock to coordinate between parallel workers
|
||||
const LOCK_FILE = resolve(__dirname, '../../.server-starting.lock');
|
||||
|
||||
interface WebServerOptions {
|
||||
command: string;
|
||||
env?: Record<string, string>;
|
||||
@@ -28,7 +24,7 @@ async function isServerRunning(port: number): Promise<boolean> {
|
||||
}
|
||||
|
||||
export async function startWebServer(options: WebServerOptions): Promise<void> {
|
||||
const { command, port, timeout = 30_000, env = {}, reuseExistingServer = true } = options;
|
||||
const { command, port, timeout = 120_000, env = {}, reuseExistingServer = true } = options;
|
||||
|
||||
// If server is already being started by another worker, wait for it
|
||||
if (serverStartPromise) {
|
||||
@@ -42,51 +38,6 @@ export async function startWebServer(options: WebServerOptions): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if another worker is starting the server (file-based lock for cross-process coordination)
|
||||
if (existsSync(LOCK_FILE)) {
|
||||
console.log(`⏳ Another worker is starting the server, waiting...`);
|
||||
const startTime = Date.now();
|
||||
while (!(await isServerRunning(port))) {
|
||||
if (Date.now() - startTime > timeout) {
|
||||
// Lock file might be stale, try to clean up and proceed
|
||||
try {
|
||||
unlinkSync(LOCK_FILE);
|
||||
} catch {
|
||||
// Ignore
|
||||
}
|
||||
break;
|
||||
}
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
}
|
||||
if (await isServerRunning(port)) {
|
||||
console.log(`✅ Server is now ready on port ${port}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create lock file to signal other workers
|
||||
try {
|
||||
writeFileSync(LOCK_FILE, String(process.pid));
|
||||
} catch {
|
||||
// Another worker might have created it, check again
|
||||
if (existsSync(LOCK_FILE)) {
|
||||
console.log(`⏳ Lock file created by another worker, waiting...`);
|
||||
const startTime = Date.now();
|
||||
while (!(await isServerRunning(port))) {
|
||||
if (Date.now() - startTime > timeout) {
|
||||
throw new Error(`Server failed to start within ${timeout}ms`);
|
||||
}
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
}
|
||||
console.log(`✅ Server is now ready on port ${port}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a promise for the server startup and store it
|
||||
serverStartPromise = (async () => {
|
||||
console.log(`🚀 Starting web server: ${command}`);
|
||||
@@ -99,20 +50,12 @@ export async function startWebServer(options: WebServerOptions): Promise<void> {
|
||||
cwd: projectRoot,
|
||||
env: {
|
||||
...process.env,
|
||||
// E2E test secret keys
|
||||
BETTER_AUTH_SECRET: 'e2e-test-secret-key-for-better-auth-32chars!',
|
||||
KEY_VAULTS_SECRET: 'LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=',
|
||||
// Disable email verification for e2e
|
||||
NEXT_PUBLIC_AUTH_EMAIL_VERIFICATION: '0',
|
||||
// Enable Better Auth for e2e tests with real authentication
|
||||
NEXT_PUBLIC_ENABLE_BETTER_AUTH: '1',
|
||||
ENABLE_AUTH_PROTECTION: '0',
|
||||
ENABLE_OIDC: '0',
|
||||
NEXT_PUBLIC_ENABLE_CLERK_AUTH: '0',
|
||||
NEXT_PUBLIC_ENABLE_NEXT_AUTH: '0',
|
||||
NODE_OPTIONS: '--max-old-space-size=6144',
|
||||
PORT: String(port),
|
||||
// Mock S3 env vars to prevent initialization errors
|
||||
S3_ACCESS_KEY_ID: 'e2e-mock-access-key',
|
||||
S3_BUCKET: 'e2e-mock-bucket',
|
||||
S3_ENDPOINT: 'https://e2e-mock-s3.localhost',
|
||||
S3_SECRET_ACCESS_KEY: 'e2e-mock-secret-key',
|
||||
...env,
|
||||
},
|
||||
});
|
||||
@@ -150,10 +93,4 @@ export async function stopWebServer(): Promise<void> {
|
||||
serverProcess = null;
|
||||
serverStartPromise = null;
|
||||
}
|
||||
// Clean up lock file
|
||||
try {
|
||||
unlinkSync(LOCK_FILE);
|
||||
} catch {
|
||||
// Ignore if file doesn't exist
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { IWorldOptions, World, setWorldConstructor } from '@cucumber/cucumber';
|
||||
import { Browser, BrowserContext, Page, Response, chromium } from '@playwright/test';
|
||||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
|
||||
export interface TestContext {
|
||||
[key: string]: any;
|
||||
@@ -31,7 +29,7 @@ export class CustomWorld extends World {
|
||||
}
|
||||
|
||||
async init() {
|
||||
const PORT = process.env.PORT ? Number(process.env.PORT) : 3006;
|
||||
const PORT = process.env.PORT ? Number(process.env.PORT) : 3010;
|
||||
const BASE_URL = process.env.BASE_URL || `http://localhost:${PORT}`;
|
||||
|
||||
this.browser = await chromium.launch({
|
||||
@@ -44,7 +42,7 @@ export class CustomWorld extends World {
|
||||
});
|
||||
|
||||
// Set expect timeout for assertions (e.g., toBeVisible, toHaveText)
|
||||
this.browserContext.setDefaultTimeout(30_000);
|
||||
this.browserContext.setDefaultTimeout(120_000);
|
||||
|
||||
this.page = await this.browserContext.newPage();
|
||||
|
||||
@@ -60,7 +58,7 @@ export class CustomWorld extends World {
|
||||
}
|
||||
});
|
||||
|
||||
this.page.setDefaultTimeout(30_000);
|
||||
this.page.setDefaultTimeout(120_000);
|
||||
}
|
||||
|
||||
async cleanup() {
|
||||
@@ -70,18 +68,8 @@ export class CustomWorld extends World {
|
||||
}
|
||||
|
||||
async takeScreenshot(name: string): Promise<Buffer> {
|
||||
const screenshot = await this.page.screenshot({ fullPage: true });
|
||||
|
||||
// Save screenshot to file
|
||||
const screenshotsDir = path.join(process.cwd(), 'screenshots');
|
||||
if (!fs.existsSync(screenshotsDir)) {
|
||||
fs.mkdirSync(screenshotsDir, { recursive: true });
|
||||
}
|
||||
const filepath = path.join(screenshotsDir, `${name}.png`);
|
||||
fs.writeFileSync(filepath, screenshot);
|
||||
console.log(`📸 Screenshot saved: ${filepath}`);
|
||||
|
||||
return screenshot;
|
||||
console.log(name);
|
||||
return await this.page.screenshot({ fullPage: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+99
-110
@@ -1,39 +1,39 @@
|
||||
{
|
||||
"apikey.display.autoGenerated": "تم إنشاؤه تلقائيًا",
|
||||
"apikey.display.autoGenerated": "تم الإنشاء تلقائيًا",
|
||||
"apikey.display.copy": "نسخ",
|
||||
"apikey.display.copyError": "فشل النسخ",
|
||||
"apikey.display.copySuccess": "تم نسخ مفتاح API إلى الحافظة",
|
||||
"apikey.display.enterPlaceholder": "يرجى الإدخال",
|
||||
"apikey.display.enterPlaceholder": "الرجاء الإدخال",
|
||||
"apikey.display.hide": "إخفاء",
|
||||
"apikey.display.neverExpires": "لا تنتهي صلاحيته",
|
||||
"apikey.display.neverUsed": "لم يُستخدم من قبل",
|
||||
"apikey.display.show": "إظهار",
|
||||
"apikey.display.neverExpires": "لا تنتهي صلاحيتها أبدًا",
|
||||
"apikey.display.neverUsed": "لم يُستخدم أبدًا",
|
||||
"apikey.display.show": "عرض",
|
||||
"apikey.form.fields.expiresAt.label": "تاريخ الانتهاء",
|
||||
"apikey.form.fields.expiresAt.placeholder": "لا تنتهي صلاحيته",
|
||||
"apikey.form.fields.expiresAt.placeholder": "لا تنتهي صلاحيتها أبدًا",
|
||||
"apikey.form.fields.name.label": "الاسم",
|
||||
"apikey.form.fields.name.placeholder": "يرجى إدخال اسم مفتاح API",
|
||||
"apikey.form.fields.name.placeholder": "الرجاء إدخال اسم مفتاح API",
|
||||
"apikey.form.submit": "إنشاء",
|
||||
"apikey.form.title": "إنشاء مفتاح API",
|
||||
"apikey.list.actions.create": "إنشاء مفتاح API",
|
||||
"apikey.list.actions.delete": "حذف",
|
||||
"apikey.list.actions.deleteConfirm.actions.cancel": "إلغاء",
|
||||
"apikey.list.actions.deleteConfirm.actions.ok": "تأكيد",
|
||||
"apikey.list.actions.deleteConfirm.content": "هل أنت متأكد أنك تريد حذف مفتاح API هذا؟",
|
||||
"apikey.list.actions.deleteConfirm.title": "تأكيد الإجراء",
|
||||
"apikey.list.actions.deleteConfirm.content": "هل أنت متأكد من حذف هذا المفتاح؟",
|
||||
"apikey.list.actions.deleteConfirm.title": "تأكيد العملية",
|
||||
"apikey.list.columns.actions": "الإجراءات",
|
||||
"apikey.list.columns.expiresAt": "تاريخ الانتهاء",
|
||||
"apikey.list.columns.key": "المفتاح",
|
||||
"apikey.list.columns.lastUsedAt": "آخر استخدام",
|
||||
"apikey.list.columns.name": "الاسم",
|
||||
"apikey.list.columns.status": "حالة التمكين",
|
||||
"apikey.list.columns.status": "حالة التفعيل",
|
||||
"apikey.list.title": "قائمة مفاتيح API",
|
||||
"apikey.validation.required": "لا يمكن ترك هذا الحقل فارغًا",
|
||||
"apikey.validation.required": "لا يمكن أن يكون المحتوى فارغًا",
|
||||
"betterAuth.errors.confirmPasswordRequired": "يرجى تأكيد كلمة المرور",
|
||||
"betterAuth.errors.emailExists": "هذا البريد الإلكتروني مسجل بالفعل. يرجى تسجيل الدخول بدلاً من ذلك",
|
||||
"betterAuth.errors.emailInvalid": "يرجى إدخال بريد إلكتروني أو اسم مستخدم صالح",
|
||||
"betterAuth.errors.emailNotRegistered": "هذا البريد الإلكتروني أو اسم المستخدم غير مسجل",
|
||||
"betterAuth.errors.emailNotVerified": "البريد الإلكتروني غير مفعل، يرجى تفعيله أولاً",
|
||||
"betterAuth.errors.emailRequired": "يرجى إدخال بريدك الإلكتروني أو اسم المستخدم",
|
||||
"betterAuth.errors.emailExists": "هذا البريد الإلكتروني مسجّل بالفعل، يرجى تسجيل الدخول مباشرة",
|
||||
"betterAuth.errors.emailInvalid": "يرجى إدخال عنوان بريد إلكتروني صالح",
|
||||
"betterAuth.errors.emailNotRegistered": "هذا البريد الإلكتروني غير مسجل",
|
||||
"betterAuth.errors.emailNotVerified": "لم يتم التحقق من البريد الإلكتروني، يرجى التحقق أولاً",
|
||||
"betterAuth.errors.emailRequired": "يرجى إدخال عنوان البريد الإلكتروني",
|
||||
"betterAuth.errors.firstNameRequired": "يرجى إدخال الاسم الأول",
|
||||
"betterAuth.errors.lastNameRequired": "يرجى إدخال اسم العائلة",
|
||||
"betterAuth.errors.loginFailed": "فشل تسجيل الدخول، يرجى التحقق من البريد الإلكتروني وكلمة المرور",
|
||||
@@ -44,82 +44,77 @@
|
||||
"betterAuth.errors.passwordRequired": "يرجى إدخال كلمة المرور",
|
||||
"betterAuth.errors.usernameNotRegistered": "اسم المستخدم هذا غير مسجل",
|
||||
"betterAuth.errors.usernameRequired": "يرجى إدخال اسم المستخدم",
|
||||
"betterAuth.resetPassword.backToSignIn": "العودة لتسجيل الدخول",
|
||||
"betterAuth.resetPassword.backToSignIn": "العودة إلى تسجيل الدخول",
|
||||
"betterAuth.resetPassword.confirmPasswordPlaceholder": "تأكيد كلمة المرور الجديدة",
|
||||
"betterAuth.resetPassword.confirmPasswordRequired": "يرجى تأكيد كلمة المرور الجديدة",
|
||||
"betterAuth.resetPassword.description": "يرجى إدخال كلمة المرور الجديدة",
|
||||
"betterAuth.resetPassword.error": "فشل في إعادة تعيين كلمة المرور، يرجى المحاولة مرة أخرى",
|
||||
"betterAuth.resetPassword.error": "فشل إعادة تعيين كلمة المرور، يرجى المحاولة مرة أخرى",
|
||||
"betterAuth.resetPassword.invalidToken": "رابط إعادة التعيين غير صالح أو منتهي الصلاحية",
|
||||
"betterAuth.resetPassword.newPasswordPlaceholder": "أدخل كلمة المرور الجديدة",
|
||||
"betterAuth.resetPassword.passwordMismatch": "كلمتا المرور غير متطابقتين",
|
||||
"betterAuth.resetPassword.submit": "إعادة تعيين كلمة المرور",
|
||||
"betterAuth.resetPassword.success": "تمت إعادة تعيين كلمة المرور بنجاح، يرجى تسجيل الدخول بكلمة المرور الجديدة",
|
||||
"betterAuth.resetPassword.success": "تمت إعادة تعيين كلمة المرور بنجاح، يرجى تسجيل الدخول باستخدام كلمة المرور الجديدة",
|
||||
"betterAuth.resetPassword.title": "إعادة تعيين كلمة المرور",
|
||||
"betterAuth.signin.backToEmail": "العودة لتغيير البريد الإلكتروني",
|
||||
"betterAuth.signin.continueWithApple": "المتابعة باستخدام Apple",
|
||||
"betterAuth.signin.backToEmail": "العودة لتعديل البريد الإلكتروني",
|
||||
"betterAuth.signin.continueWithApple": "تسجيل الدخول باستخدام Apple",
|
||||
"betterAuth.signin.continueWithAuth0": "تسجيل الدخول باستخدام Auth0",
|
||||
"betterAuth.signin.continueWithAuthelia": "تسجيل الدخول باستخدام Authelia",
|
||||
"betterAuth.signin.continueWithAuthentik": "تسجيل الدخول باستخدام Authentik",
|
||||
"betterAuth.signin.continueWithCasdoor": "تسجيل الدخول باستخدام Casdoor",
|
||||
"betterAuth.signin.continueWithCloudflareZeroTrust": "تسجيل الدخول باستخدام Cloudflare Zero Trust",
|
||||
"betterAuth.signin.continueWithCognito": "المتابعة باستخدام AWS Cognito",
|
||||
"betterAuth.signin.continueWithCognito": "تسجيل الدخول باستخدام AWS Cognito",
|
||||
"betterAuth.signin.continueWithFeishu": "تسجيل الدخول باستخدام Feishu",
|
||||
"betterAuth.signin.continueWithGithub": "المتابعة باستخدام GitHub",
|
||||
"betterAuth.signin.continueWithGoogle": "المتابعة باستخدام Google",
|
||||
"betterAuth.signin.continueWithGithub": "تسجيل الدخول باستخدام GitHub",
|
||||
"betterAuth.signin.continueWithGoogle": "تسجيل الدخول باستخدام Google",
|
||||
"betterAuth.signin.continueWithKeycloak": "تسجيل الدخول باستخدام Keycloak",
|
||||
"betterAuth.signin.continueWithLogto": "تسجيل الدخول باستخدام Logto",
|
||||
"betterAuth.signin.continueWithMicrosoft": "المتابعة باستخدام Microsoft",
|
||||
"betterAuth.signin.continueWithMicrosoft": "تسجيل الدخول باستخدام Microsoft",
|
||||
"betterAuth.signin.continueWithOIDC": "تسجيل الدخول باستخدام OIDC",
|
||||
"betterAuth.signin.continueWithOkta": "تسجيل الدخول باستخدام Okta",
|
||||
"betterAuth.signin.continueWithWechat": "تسجيل الدخول باستخدام WeChat",
|
||||
"betterAuth.signin.continueWithZitadel": "تسجيل الدخول باستخدام Zitadel",
|
||||
"betterAuth.signin.emailPlaceholder": "أدخل بريدك الإلكتروني أو اسم المستخدم",
|
||||
"betterAuth.signin.emailPlaceholder": "يرجى إدخال عنوان البريد الإلكتروني",
|
||||
"betterAuth.signin.emailStep.title": "تسجيل الدخول",
|
||||
"betterAuth.signin.error": "فشل تسجيل الدخول، يرجى التحقق من البريد الإلكتروني وكلمة المرور",
|
||||
"betterAuth.signin.forgotPassword": "هل نسيت كلمة المرور؟",
|
||||
"betterAuth.signin.forgotPasswordError": "فشل في إرسال رابط إعادة تعيين كلمة المرور",
|
||||
"betterAuth.signin.forgotPasswordError": "فشل إرسال رابط إعادة تعيين كلمة المرور",
|
||||
"betterAuth.signin.forgotPasswordSent": "تم إرسال رابط إعادة تعيين كلمة المرور، يرجى التحقق من بريدك الإلكتروني",
|
||||
"betterAuth.signin.invalidReferralCodeContent": "رمز الإحالة \"{{code}}\" الذي استخدمته غير صالح أو منتهي الصلاحية. هل ترغب في المتابعة؟",
|
||||
"betterAuth.signin.invalidReferralCodeTitle": "رمز إحالة غير صالح",
|
||||
"betterAuth.signin.magicLinkButton": "إرسال رابط تسجيل الدخول",
|
||||
"betterAuth.signin.magicLinkError": "فشل في إرسال رابط تسجيل الدخول، يرجى المحاولة لاحقًا",
|
||||
"betterAuth.signin.magicLinkError": "فشل إرسال رابط تسجيل الدخول، يرجى المحاولة لاحقًا",
|
||||
"betterAuth.signin.magicLinkSent": "تم إرسال رابط تسجيل الدخول، يرجى التحقق من بريدك الإلكتروني",
|
||||
"betterAuth.signin.nextStep": "التالي",
|
||||
"betterAuth.signin.nextStep": "الخطوة التالية",
|
||||
"betterAuth.signin.noAccount": "ليس لديك حساب؟",
|
||||
"betterAuth.signin.orContinueWith": "أو",
|
||||
"betterAuth.signin.passwordPlaceholder": "أدخل كلمة المرور",
|
||||
"betterAuth.signin.passwordStep.subtitle": "أدخل كلمة المرور للمتابعة",
|
||||
"betterAuth.signin.orContinueWith": "أو المتابعة باستخدام",
|
||||
"betterAuth.signin.passwordPlaceholder": "يرجى إدخال كلمة المرور",
|
||||
"betterAuth.signin.passwordStep.subtitle": "يرجى إدخال كلمة المرور للمتابعة",
|
||||
"betterAuth.signin.signupLink": "سجّل الآن",
|
||||
"betterAuth.signin.socialError": "فشل تسجيل الدخول الاجتماعي، يرجى المحاولة مرة أخرى",
|
||||
"betterAuth.signin.socialOnlyHint": "تم تسجيل هذا البريد الإلكتروني باستخدام حساب اجتماعي. يرجى تسجيل الدخول باستخدام مزود الخدمة المناسب.",
|
||||
"betterAuth.signin.socialError": "فشل تسجيل الدخول عبر الشبكات الاجتماعية، يرجى المحاولة مرة أخرى",
|
||||
"betterAuth.signin.socialOnlyHint": "تم تسجيل هذا البريد الإلكتروني باستخدام حساب اجتماعي، يرجى تسجيل الدخول باستخدامه",
|
||||
"betterAuth.signin.submit": "تسجيل الدخول",
|
||||
"betterAuth.signup.confirmPasswordPlaceholder": "تأكيد كلمة المرور",
|
||||
"betterAuth.signup.emailPlaceholder": "أدخل عنوان بريدك الإلكتروني",
|
||||
"betterAuth.signup.confirmPasswordPlaceholder": "يرجى تأكيد كلمة المرور",
|
||||
"betterAuth.signup.emailPlaceholder": "يرجى إدخال عنوان البريد الإلكتروني",
|
||||
"betterAuth.signup.error": "فشل التسجيل، يرجى المحاولة مرة أخرى",
|
||||
"betterAuth.signup.firstNamePlaceholder": "الاسم الأول",
|
||||
"betterAuth.signup.hasAccount": "هل لديك حساب بالفعل؟",
|
||||
"betterAuth.signup.invalidReferralCodeContent": "رمز الإحالة \"{{code}}\" الذي أدخلته غير صالح أو منتهي الصلاحية. هل ترغب في المتابعة؟",
|
||||
"betterAuth.signup.invalidReferralCodeTitle": "رمز إحالة غير صالح",
|
||||
"betterAuth.signup.hasAccount": "هل لديك حساب؟",
|
||||
"betterAuth.signup.lastNamePlaceholder": "اسم العائلة",
|
||||
"betterAuth.signup.passwordPlaceholder": "أدخل كلمة المرور",
|
||||
"betterAuth.signup.referralCodePlaceholder": "رمز الإحالة (اختياري)",
|
||||
"betterAuth.signup.signinLink": "سجّل الدخول الآن",
|
||||
"betterAuth.signup.submit": "إنشاء حساب",
|
||||
"betterAuth.signup.subtitle": "ابدأ مساحة التعاون الخاصة بك مع Agents",
|
||||
"betterAuth.signup.passwordPlaceholder": "يرجى إدخال كلمة المرور",
|
||||
"betterAuth.signup.signinLink": "تسجيل الدخول الآن",
|
||||
"betterAuth.signup.submit": "تسجيل",
|
||||
"betterAuth.signup.subtitle": "ابدأ مساحة التعاون الخاصة بـ Agents",
|
||||
"betterAuth.signup.success": "تم التسجيل بنجاح! يرجى التحقق من بريدك الإلكتروني لتأكيد الحساب",
|
||||
"betterAuth.signup.title": "إنشاء حساب",
|
||||
"betterAuth.signup.usernamePlaceholder": "أدخل اسم المستخدم",
|
||||
"betterAuth.verifyEmail.backToSignIn": "العودة لتسجيل الدخول",
|
||||
"betterAuth.verifyEmail.checkSpam": "إذا لم يصلك البريد الإلكتروني، يرجى التحقق من مجلد الرسائل غير المرغوب فيها",
|
||||
"betterAuth.signup.usernamePlaceholder": "يرجى إدخال اسم المستخدم",
|
||||
"betterAuth.verifyEmail.backToSignIn": "العودة إلى تسجيل الدخول",
|
||||
"betterAuth.verifyEmail.checkSpam": "إذا لم تتلقَ البريد الإلكتروني، يرجى التحقق من مجلد الرسائل غير المرغوب فيها",
|
||||
"betterAuth.verifyEmail.description": "تم إرسال رسالة تحقق إلى {{email}}",
|
||||
"betterAuth.verifyEmail.resend.button": "إعادة إرسال رسالة التحقق",
|
||||
"betterAuth.verifyEmail.resend.error": "فشل الإرسال. يرجى المحاولة لاحقًا.",
|
||||
"betterAuth.verifyEmail.resend.error": "فشل الإرسال، يرجى المحاولة لاحقًا",
|
||||
"betterAuth.verifyEmail.resend.noEmail": "عنوان البريد الإلكتروني مفقود",
|
||||
"betterAuth.verifyEmail.resend.success": "تمت إعادة إرسال رسالة التحقق. يرجى التحقق من بريدك الوارد.",
|
||||
"betterAuth.verifyEmail.resend.success": "تمت إعادة إرسال رسالة التحقق، يرجى التحقق من بريدك الإلكتروني",
|
||||
"betterAuth.verifyEmail.title": "تحقق من بريدك الإلكتروني",
|
||||
"date.prevMonth": "الشهر الماضي",
|
||||
"date.recent30Days": "آخر 30 يومًا",
|
||||
"footer.agreement": "بالمتابعة، فإنك تؤكد أنك قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>",
|
||||
"footer.agreement": "بالمتابعة، فإنك تؤكد أنك قد قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>",
|
||||
"footer.privacy": "سياسة الخصوصية",
|
||||
"footer.terms": "شروط الخدمة",
|
||||
"header.desc": "إدارة معلومات حسابك.",
|
||||
@@ -138,110 +133,104 @@
|
||||
"heatmaps.months.nov": "نوفمبر",
|
||||
"heatmaps.months.oct": "أكتوبر",
|
||||
"heatmaps.months.sep": "سبتمبر",
|
||||
"heatmaps.tooltip": "{{date}} تم إرسال {{count}} رسالة في هذا اليوم",
|
||||
"heatmaps.totalCount": "تم إرسال ما مجموعه {{count}} رسالة خلال العام الماضي",
|
||||
"heatmaps.tooltip": "{{date}} أرسل {{count}} رسائل في ذلك اليوم",
|
||||
"heatmaps.totalCount": "إجمالي {{count}} رسائل أرسلت في العام الماضي",
|
||||
"login": "تسجيل الدخول",
|
||||
"loginGuide.f1": "احصل على استخدام مجاني",
|
||||
"loginGuide.f2": "مزامنة الرسائل عبر الأجهزة",
|
||||
"loginGuide.f3": "الوصول إلى مجموعة كبيرة من الوكلاء",
|
||||
"loginGuide.f4": "استكشاف الإضافات القوية",
|
||||
"loginGuide.title": "بعد تسجيل الدخول، يمكنك:",
|
||||
"loginOrSignup": "تسجيل الدخول / إنشاء حساب",
|
||||
"profile.account": "الحساب",
|
||||
"profile.authorizations.actions.revoke": "إلغاء",
|
||||
"profile.authorizations.revoke.description": "بعد الإلغاء، لن يتمكن الأداة من الوصول إلى بياناتك. ستحتاج إلى إعادة التفويض لاستخدامها مرة أخرى.",
|
||||
"profile.authorizations.revoke.title": "هل تريد إلغاء تفويض {{name}}؟",
|
||||
"loginOrSignup": "تسجيل الدخول / الاشتراك",
|
||||
"profile.authorizations.actions.revoke": "إلغاء التفويض",
|
||||
"profile.authorizations.revoke.description": "بعد إلغاء التفويض، لن يتمكن هذا التطبيق من الوصول إلى بياناتك. لإعادة استخدامه، ستحتاج إلى منحه التفويض مرة أخرى.",
|
||||
"profile.authorizations.revoke.title": "هل أنت متأكد من إلغاء التفويض لـ {{name}}؟",
|
||||
"profile.authorizations.title": "إدارة التفويضات",
|
||||
"profile.avatar": "الصورة الرمزية",
|
||||
"profile.avatar": "الصورة الشخصية",
|
||||
"profile.cancel": "إلغاء",
|
||||
"profile.changePassword": "إعادة تعيين كلمة المرور",
|
||||
"profile.email": "عنوان البريد الإلكتروني",
|
||||
"profile.fullName": "الاسم الكامل",
|
||||
"profile.fullNameInputHint": "يرجى إدخال اسمك الكامل الجديد",
|
||||
"profile.interests": "الاهتمامات",
|
||||
"profile.fullNameInputHint": "يرجى إدخال الاسم الكامل الجديد",
|
||||
"profile.interests": "مجالات الاهتمام",
|
||||
"profile.interestsAdd": "إضافة",
|
||||
"profile.interestsPlaceholder": "أدخل اهتمامًا",
|
||||
"profile.interestsPlaceholder": "أدخل مجالات الاهتمام",
|
||||
"profile.password": "كلمة المرور",
|
||||
"profile.resetPasswordError": "فشل في إرسال رابط إعادة تعيين كلمة المرور",
|
||||
"profile.resetPasswordError": "فشل إرسال رابط إعادة تعيين كلمة المرور",
|
||||
"profile.resetPasswordSent": "تم إرسال رابط إعادة تعيين كلمة المرور، يرجى التحقق من بريدك الإلكتروني",
|
||||
"profile.save": "حفظ",
|
||||
"profile.setPassword": "تعيين كلمة المرور",
|
||||
"profile.sso.link.button": "ربط الحساب",
|
||||
"profile.sso.link.success": "تم ربط الحساب بنجاح",
|
||||
"profile.sso.loading": "جاري تحميل الحسابات المرتبطة من جهات خارجية",
|
||||
"profile.sso.providers": "الحسابات المرتبطة",
|
||||
"profile.sso.unlink.description": "ستحتاج إلى إعادة التفويض أو الربط لتسجيل الدخول باستخدام {{provider}} مرة أخرى بعد إلغاء الربط.",
|
||||
"profile.sso.unlink.forbidden": "يجب الاحتفاظ بطريقة تسجيل دخول واحدة على الأقل.",
|
||||
"profile.sso.unlink.title": "هل تريد إلغاء ربط حساب {{provider}}؟",
|
||||
"profile.title": "الملف الشخصي",
|
||||
"profile.updateAvatar": "تحديث الصورة الرمزية",
|
||||
"profile.sso.loading": "جارٍ تحميل الحسابات المرتبطة من طرف ثالث",
|
||||
"profile.sso.providers": "الحسابات المتصلة",
|
||||
"profile.sso.unlink.description": "بعد إلغاء الربط، لن تتمكن من تسجيل الدخول باستخدام حساب {{provider}} \"{{providerAccountId}}\". إذا كنت ترغب في ربط حساب {{provider}} بهذا الحساب مرة أخرى، يرجى التأكد من أن عنوان البريد الإلكتروني لحساب {{provider}} هو {{email}}، وسنقوم بربطه تلقائيًا عند تسجيل الدخول.",
|
||||
"profile.sso.unlink.forbidden": "يجب أن تحتفظ بحساب طرف ثالث واحد على الأقل مرتبطًا.",
|
||||
"profile.sso.unlink.title": "هل تريد فصل حساب الطرف الثالث {{provider}}؟",
|
||||
"profile.title": "تفاصيل الملف الشخصي",
|
||||
"profile.updateAvatar": "تحديث الصورة الشخصية",
|
||||
"profile.updateFullName": "تحديث الاسم الكامل",
|
||||
"profile.updateInterests": "تحديث الاهتمامات",
|
||||
"profile.updateInterests": "تحديث مجالات الاهتمام",
|
||||
"profile.updateUsername": "تحديث اسم المستخدم",
|
||||
"profile.username": "اسم المستخدم",
|
||||
"profile.usernameDuplicate": "اسم المستخدم مستخدم بالفعل",
|
||||
"profile.usernameInputHint": "يرجى إدخال اسم المستخدم الجديد",
|
||||
"profile.usernamePlaceholder": "أدخل اسم مستخدم يحتوي على أحرف أو أرقام أو شرطة سفلية",
|
||||
"profile.usernameRequired": "لا يمكن أن يكون اسم المستخدم فارغًا",
|
||||
"profile.usernameRule": "يمكن أن يحتوي اسم المستخدم على أحرف أو أرقام أو شرطة سفلية فقط",
|
||||
"profile.usernameInputHint": "يرجى إدخال اسم مستخدم جديد",
|
||||
"profile.usernamePlaceholder": "يرجى إدخال اسم مستخدم مكوّن من أحرف أو أرقام أو شرطة سفلية",
|
||||
"profile.usernameRequired": "اسم المستخدم لا يمكن أن يكون فارغًا",
|
||||
"profile.usernameRule": "اسم المستخدم يجب أن يحتوي فقط على أحرف أو أرقام أو شرطة سفلية",
|
||||
"profile.usernameUpdateFailed": "فشل في تحديث اسم المستخدم، يرجى المحاولة لاحقًا",
|
||||
"signin.subtitle": "سجّل أو قم بتسجيل الدخول إلى حساب {{appName}} الخاص بك",
|
||||
"signin.title": "للتعاون مع الوكلاء",
|
||||
"signin.subtitle": "سجّل أو قم بتسجيل الدخول إلى حسابك في {{appName}}",
|
||||
"signin.title": "مساحة التعاون الخاصة بك في Agents",
|
||||
"signout": "تسجيل الخروج",
|
||||
"signup": "إنشاء حساب",
|
||||
"signup": "الاشتراك",
|
||||
"stats.aiheatmaps": "مؤشر النشاط",
|
||||
"stats.assistants": "الوكلاء",
|
||||
"stats.assistantsRank.left": "الوكيل",
|
||||
"stats.assistants": "المساعدون",
|
||||
"stats.assistantsRank.left": "المساعد",
|
||||
"stats.assistantsRank.right": "المواضيع",
|
||||
"stats.assistantsRank.title": "ترتيب استخدام الوكلاء",
|
||||
"stats.assistantsRank.title": "ترتيب استخدام المساعد",
|
||||
"stats.createdAt": "تاريخ التسجيل",
|
||||
"stats.days": "أيام",
|
||||
"stats.empty.desc": "يرجى جمع المزيد من بيانات الدردشة لعرضها",
|
||||
"stats.empty.desc": "يرجى تجميع المزيد من بيانات الدردشة للعرض",
|
||||
"stats.empty.title": "لا توجد بيانات",
|
||||
"stats.lastYearActivity": "النشاط خلال العام الماضي",
|
||||
"stats.lastYearActivity": "النشاط في العام الماضي",
|
||||
"stats.loginGuide.f1": "احصل على استخدام مجاني",
|
||||
"stats.loginGuide.f2": "مزامنة الرسائل عبر الأجهزة",
|
||||
"stats.loginGuide.f3": "الوصول إلى مجموعة كبيرة من الوكلاء",
|
||||
"stats.loginGuide.f4": "استكشاف المهارات القوية",
|
||||
"stats.loginGuide.title": "بعد تسجيل الدخول، يمكنك:",
|
||||
"stats.messages": "الرسائل",
|
||||
"stats.loginGuide.f2": "مزامنة الرسائل عبر الأجهزة المتعددة",
|
||||
"stats.loginGuide.f3": "تمتع بمساعدين متنوعين",
|
||||
"stats.loginGuide.f4": "استكشف الإضافات القوية",
|
||||
"stats.loginGuide.title": "بعد تسجيل الدخول يمكنك:",
|
||||
"stats.messages": "رسائل",
|
||||
"stats.modelsRank.left": "النموذج",
|
||||
"stats.modelsRank.right": "الرسائل",
|
||||
"stats.modelsRank.title": "ترتيب استخدام النماذج",
|
||||
"stats.share.title": "مؤشر نشاطي مع الذكاء الاصطناعي",
|
||||
"stats.modelsRank.title": "ترتيب استخدام النموذج",
|
||||
"stats.share.title": "مؤشر نشاط الذكاء الاصطناعي الخاص بي",
|
||||
"stats.topics": "المواضيع",
|
||||
"stats.topicsRank.left": "الموضوع",
|
||||
"stats.topicsRank.right": "الرسائل",
|
||||
"stats.topicsRank.title": "ترتيب محتوى المواضيع",
|
||||
"stats.updatedAt": "تم التحديث في",
|
||||
"stats.welcome": "{{username}}، هذه هي يومك <span>{{days}}</span> مع {{appName}}",
|
||||
"stats.words": "إجمالي الكلمات",
|
||||
"stats.topicsRank.title": "ترتيب محتوى الموضوع",
|
||||
"stats.updatedAt": "تاريخ التحديث",
|
||||
"stats.welcome": "{{username}}، هذا هو يومك <span>{{days}}</span> مع {{appName}}",
|
||||
"stats.words": "كلمات",
|
||||
"tab.apikey": "إدارة مفاتيح API",
|
||||
"tab.profile": "حسابي",
|
||||
"tab.security": "الأمان",
|
||||
"tab.stats": "الإحصائيات",
|
||||
"tab.usage": "إحصائيات الاستخدام",
|
||||
"tab.usage": "إحصاءات الاستخدام",
|
||||
"usage.activeModels.modelTable": "قائمة النماذج",
|
||||
"usage.activeModels.models": "النماذج النشطة",
|
||||
"usage.activeModels.providerTable": "قائمة المزودين",
|
||||
"usage.activeModels.providers": "المزودون النشطون",
|
||||
"usage.activeModels.table.calls": "المكالمات",
|
||||
"usage.activeModels.table.calls": "عدد الاستدعاءات",
|
||||
"usage.activeModels.table.model": "النموذج",
|
||||
"usage.activeModels.table.provider": "المزود",
|
||||
"usage.activeModels.table.spend": "الإنفاق",
|
||||
"usage.cards.month.modelCalls": "مكالمات النموذج",
|
||||
"usage.cards.month.title": "الإنفاق هذا الشهر",
|
||||
"usage.activeModels.table.spend": "التكلفة",
|
||||
"usage.cards.month.modelCalls": "استدعاءات النموذج",
|
||||
"usage.cards.month.title": "إنفاق هذا الشهر",
|
||||
"usage.cards.today.title": "إنفاق اليوم",
|
||||
"usage.cards.today.yesterday": "أمس",
|
||||
"usage.table.actions": "الإجراءات",
|
||||
"usage.table.actions": "إجراءات",
|
||||
"usage.table.createdAt": "وقت الاستخدام",
|
||||
"usage.table.inputTokens": "الرموز المدخلة",
|
||||
"usage.table.inputTokens": "رموز الإدخال",
|
||||
"usage.table.model": "النموذج",
|
||||
"usage.table.outputTokens": "الرموز الناتجة",
|
||||
"usage.table.spend": "الإنفاق",
|
||||
"usage.table.outputTokens": "رموز الإخراج",
|
||||
"usage.table.spend": "التكلفة",
|
||||
"usage.table.tps": "TPS",
|
||||
"usage.table.ttft": "TTFT",
|
||||
"usage.table.type": "نوع المكالمة",
|
||||
"usage.table.type": "نوع الاستدعاء",
|
||||
"usage.trends.spend": "المبلغ",
|
||||
"usage.trends.tokens": "الرموز",
|
||||
"usage.welcome.model": "النموذج",
|
||||
|
||||
+13
-13
@@ -1,36 +1,36 @@
|
||||
{
|
||||
"actions.discord": "اذهب إلى Discord للحصول على الملاحظات",
|
||||
"actions.discord": "اذهب إلى Discord لإرسال الملاحظات",
|
||||
"actions.home": "العودة إلى الصفحة الرئيسية",
|
||||
"actions.retry": "تسجيل الدخول مرة أخرى",
|
||||
"codes.ACCOUNT_ALREADY_LINKED_TO_DIFFERENT_USER": "هذا الحساب مرتبط بالفعل بمستخدم آخر",
|
||||
"codes.ACCOUNT_ALREADY_LINKED_TO_DIFFERENT_USER": "تم ربط هذا الحساب بمستخدم آخر",
|
||||
"codes.ACCOUNT_NOT_FOUND": "لم يتم العثور على الحساب",
|
||||
"codes.CREDENTIAL_ACCOUNT_NOT_FOUND": "حساب بيانات الاعتماد غير موجود",
|
||||
"codes.EMAIL_CAN_NOT_BE_UPDATED": "لا يمكن تحديث البريد الإلكتروني لهذا الحساب",
|
||||
"codes.EMAIL_CAN_NOT_BE_UPDATED": "لا يمكن تعديل البريد الإلكتروني لهذا الحساب",
|
||||
"codes.EMAIL_NOT_VERIFIED": "يرجى التحقق من بريدك الإلكتروني أولاً",
|
||||
"codes.FAILED_TO_CREATE_SESSION": "فشل في إنشاء الجلسة",
|
||||
"codes.FAILED_TO_CREATE_USER": "فشل في إنشاء المستخدم",
|
||||
"codes.FAILED_TO_GET_SESSION": "فشل في استرجاع الجلسة",
|
||||
"codes.FAILED_TO_GET_USER_INFO": "فشل في استرجاع معلومات المستخدم",
|
||||
"codes.FAILED_TO_GET_SESSION": "فشل في الحصول على الجلسة",
|
||||
"codes.FAILED_TO_GET_USER_INFO": "فشل في جلب معلومات المستخدم",
|
||||
"codes.FAILED_TO_UNLINK_LAST_ACCOUNT": "لا يمكن إلغاء ربط آخر حساب مرتبط",
|
||||
"codes.FAILED_TO_UPDATE_USER": "فشل في تحديث معلومات المستخدم",
|
||||
"codes.ID_TOKEN_NOT_SUPPORTED": "رمز الهوية غير مدعوم",
|
||||
"codes.INVALID_EMAIL": "تنسيق البريد الإلكتروني غير صالح",
|
||||
"codes.INVALID_EMAIL": "تنسيق البريد الإلكتروني غير صحيح",
|
||||
"codes.INVALID_EMAIL_OR_PASSWORD": "البريد الإلكتروني أو كلمة المرور غير صحيحة",
|
||||
"codes.INVALID_PASSWORD": "تنسيق كلمة المرور غير صالح",
|
||||
"codes.INVALID_TOKEN": "الرمز غير صالح أو منتهي الصلاحية",
|
||||
"codes.PASSWORD_TOO_LONG": "كلمة المرور طويلة جداً",
|
||||
"codes.PASSWORD_TOO_SHORT": "كلمة المرور قصيرة جداً",
|
||||
"codes.PROVIDER_NOT_FOUND": "لم يتم العثور على إعدادات موفر الهوية",
|
||||
"codes.RATE_LIMIT_EXCEEDED": "عدد كبير جداً من الطلبات، يرجى المحاولة لاحقاً",
|
||||
"codes.SESSION_EXPIRED": "انتهت صلاحية الجلسة، يرجى تسجيل الدخول مرة أخرى",
|
||||
"codes.SOCIAL_ACCOUNT_ALREADY_LINKED": "هذا الحساب الاجتماعي مرتبط بالفعل بمستخدم آخر",
|
||||
"codes.PROVIDER_NOT_FOUND": "لم يتم العثور على مزود الهوية المناسب",
|
||||
"codes.RATE_LIMIT_EXCEEDED": "عدد الطلبات كبير جداً، يرجى المحاولة لاحقاً",
|
||||
"codes.SESSION_EXPIRED": "انتهت صلاحية الجلسة، يرجى تسجيل الدخول مجدداً",
|
||||
"codes.SOCIAL_ACCOUNT_ALREADY_LINKED": "تم ربط هذا الحساب الاجتماعي بمستخدم آخر",
|
||||
"codes.UNEXPECTED_ERROR": "حدث خطأ غير متوقع، يرجى المحاولة مرة أخرى",
|
||||
"codes.UNKNOWN": "حدث خطأ غير معروف، يرجى المحاولة مرة أخرى أو التواصل مع الدعم",
|
||||
"codes.USER_ALREADY_EXISTS": "المستخدم موجود بالفعل",
|
||||
"codes.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL": "البريد الإلكتروني مستخدم بالفعل، يرجى تجربة بريد آخر",
|
||||
"codes.USER_ALREADY_HAS_PASSWORD": "هذا الحساب يحتوي بالفعل على كلمة مرور",
|
||||
"codes.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL": "تم استخدام هذا البريد الإلكتروني، يرجى تجربة بريد آخر",
|
||||
"codes.USER_ALREADY_HAS_PASSWORD": "تم تعيين كلمة مرور لهذا الحساب مسبقاً",
|
||||
"codes.USER_BANNED": "تم حظر هذا المستخدم",
|
||||
"codes.USER_EMAIL_NOT_FOUND": "لم يتم العثور على البريد الإلكتروني",
|
||||
"codes.USER_NOT_FOUND": "لم يتم العثور على المستخدم",
|
||||
"title": "خطأ في المصادقة"
|
||||
"title": "حدث خطأ في التحقق من الهوية"
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"actions.followOnX": "تابعنا على X",
|
||||
"actions.subscribeToUpdates": "اشترك للحصول على التحديثات",
|
||||
"actions.subscribeToUpdates": "اشترك في التحديثات",
|
||||
"actions.versions": "تفاصيل الإصدار",
|
||||
"addedWhileAway": "قمنا بإضافة ميزات جديدة أثناء غيابك.",
|
||||
"allChangelog": "عرض جميع سجلات التغييرات",
|
||||
"description": "ابقَ على اطلاع بآخر الميزات والتحسينات في {{appName}}",
|
||||
"addedWhileAway": "لقد أضفنا ميزات جديدة أثناء غيابك.",
|
||||
"allChangelog": "عرض جميع سجلات التحديثات",
|
||||
"description": "تابع الميزات الجديدة والتحسينات في {{appName}}",
|
||||
"pagination.next": "الصفحة التالية",
|
||||
"pagination.older": "عرض التغييرات السابقة",
|
||||
"readDetails": "اقرأ التفاصيل",
|
||||
"title": "سجل التغييرات",
|
||||
"title": "سجل التحديثات",
|
||||
"versionDetails": "تفاصيل الإصدار",
|
||||
"welcomeBack": "مرحبًا بعودتك!"
|
||||
}
|
||||
|
||||
+235
-241
@@ -1,371 +1,365 @@
|
||||
{
|
||||
"ModelSwitch.title": "النموذج",
|
||||
"active": "نشط",
|
||||
"agentBuilder.installPlugin.authRequired": "يتطلب Cloud MCP تسجيل الدخول للمتابعة",
|
||||
"agentBuilder.installPlugin.authRequired": "يتطلب مكون MCP السحابي تسجيل الدخول والمصادقة",
|
||||
"agentBuilder.installPlugin.cancel": "إلغاء",
|
||||
"agentBuilder.installPlugin.clickApproveToConnect": "انقر على \"موافقة\" للاتصال وتفويض هذا التكامل",
|
||||
"agentBuilder.installPlugin.clickApproveToInstall": "انقر على \"موافقة\" لتثبيت هذه المهارة",
|
||||
"agentBuilder.installPlugin.connectedAndEnabled": "متصل ومفعل",
|
||||
"agentBuilder.installPlugin.connectionFailed": "فشل الاتصال. أعد المحاولة أو تحقق من التفويض وإعدادات الشبكة.",
|
||||
"agentBuilder.installPlugin.installFailed": "فشل التثبيت. أعد المحاولة أو اعرض التفاصيل وحاول مرة أخرى.",
|
||||
"agentBuilder.installPlugin.installPlugin": "تثبيت المهارة",
|
||||
"agentBuilder.installPlugin.installToEnable": "قم بالتثبيت لتفعيل هذه المهارة للوكيل (يمكنك القيام بذلك لاحقًا)",
|
||||
"agentBuilder.installPlugin.clickApproveToConnect": "انقر على \"الموافقة\" للاتصال وتفويض هذا التكامل",
|
||||
"agentBuilder.installPlugin.clickApproveToInstall": "انقر على \"الموافقة\" لتثبيت هذا المكون الإضافي",
|
||||
"agentBuilder.installPlugin.connectedAndEnabled": "تم الاتصال والتفعيل",
|
||||
"agentBuilder.installPlugin.connectionFailed": "فشل الاتصال",
|
||||
"agentBuilder.installPlugin.installFailed": "فشل التثبيت",
|
||||
"agentBuilder.installPlugin.installPlugin": "تثبيت المكون الإضافي",
|
||||
"agentBuilder.installPlugin.installToEnable": "قم بتثبيت هذا المكون الإضافي لتمكين المساعد",
|
||||
"agentBuilder.installPlugin.installedAndEnabled": "تم التثبيت والتفعيل",
|
||||
"agentBuilder.installPlugin.requiresAuth": "يتطلب التفويض. انقر على \"موافقة\" للاتصال",
|
||||
"agentBuilder.installPlugin.requiresAuth": "يتطلب تفويضًا، انقر على \"الموافقة\" للاتصال",
|
||||
"agentBuilder.installPlugin.retry": "إعادة المحاولة",
|
||||
"agentBuilder.title": "منشئ الوكلاء",
|
||||
"agentBuilder.welcome": "أخبرني بحالتك.\n\nكتابة، برمجة، أو تحليل بيانات — أي شيء يناسبك. أنت تملك الهدف والمعايير؛ سأقوم بتقسيمها إلى وكلاء تعاونيين قابلين للتنفيذ.",
|
||||
"agentDefaultMessage": "مرحبًا، أنا **{{name}}**. جملة واحدة تكفي.\n\nهل ترغب في أن أتناسب مع سير عملك بشكل أفضل؟ انتقل إلى [إعدادات الوكيل]({{url}}) واملأ ملف تعريف الوكيل (يمكنك تعديله في أي وقت).",
|
||||
"agentDefaultMessageWithSystemRole": "مرحبًا، أنا **{{name}}**. جملة واحدة تكفي — أنت المتحكم.",
|
||||
"agentDefaultMessageWithoutEdit": "مرحبًا، أنا **{{name}}**. جملة واحدة تكفي — أنت المتحكم.",
|
||||
"agents": "الوكلاء",
|
||||
"artifact.generating": "يتم التوليد",
|
||||
"artifact.inThread": "لا يمكن العرض في الموضوع الفرعي، يرجى التبديل إلى منطقة المحادثة الرئيسية للفتح",
|
||||
"artifact.thinking": "يفكر",
|
||||
"agentBuilder.title": "خبير إنشاء المساعدين",
|
||||
"agentBuilder.welcome": "ما هو سيناريو احتياجك؟ شريكك المهني جاهز لخدمتك.\n\nسواء كنت تكتب، تبرمج، أو تحلل البيانات، يمكنني مساعدتك في إنشاء مساعدك الخاص!",
|
||||
"agentDefaultMessage": "مرحبًا، أنا **{{name}}**، يمكنك بدء المحادثة معي على الفور، أو يمكنك الذهاب إلى [إعدادات المساعد]({{url}}) لإكمال معلوماتي.",
|
||||
"agentDefaultMessageWithSystemRole": "مرحبًا، أنا **{{name}}**، كيف يمكنني مساعدتك؟",
|
||||
"agentDefaultMessageWithoutEdit": "مرحبًا، أنا **{{name}}**، كيف يمكنني مساعدتك؟",
|
||||
"agents": "مساعد",
|
||||
"artifact.generating": "جاري الإنشاء",
|
||||
"artifact.inThread": "لا يمكن عرض الموضوعات الفرعية، يرجى التبديل إلى منطقة المحادثة الرئيسية لفتحها",
|
||||
"artifact.thinking": "جاري التفكير",
|
||||
"artifact.thought": "عملية التفكير",
|
||||
"artifact.unknownTitle": "عمل بدون عنوان",
|
||||
"availableAgents": "الوكلاء المتاحون",
|
||||
"backToBottom": "الانتقال إلى الأحدث",
|
||||
"beforeUnload.confirmLeave": "لا يزال هناك طلب قيد التشغيل. هل تريد المغادرة؟",
|
||||
"artifact.unknownTitle": "عمل غير مسمى",
|
||||
"availableAgents": "المساعدون المتاحون",
|
||||
"backToBottom": "العودة إلى الأسفل",
|
||||
"beforeUnload.confirmLeave": "لديك طلب جارٍ معالجته، هل أنت متأكد من رغبتك في المغادرة؟",
|
||||
"builtinCopilot": "المساعد المدمج",
|
||||
"chatList.expandMessage": "توسيع الرسالة",
|
||||
"chatList.expandMessage": "عرض الرسائل",
|
||||
"chatList.longMessageDetail": "عرض التفاصيل",
|
||||
"clearCurrentMessages": "مسح رسائل الجلسة الحالية",
|
||||
"confirmClearCurrentMessages": "أنت على وشك مسح رسائل الجلسة الحالية. بمجرد المسح، لا يمكن استعادتها. يرجى تأكيد الإجراء.",
|
||||
"confirmRemoveChatGroupItemAlert": "سيتم حذف هذه المجموعة. سيتم أيضًا حذف المساعدين الخاصين بالمجموعة، بينما لن يتأثر المساعدون الخارجيون.",
|
||||
"confirmRemoveGroupItemAlert": "أنت على وشك حذف هذه المجموعة. بعد الحذف، سيتم نقل وكلائها إلى القائمة الافتراضية. يرجى تأكيد الإجراء.",
|
||||
"confirmClearCurrentMessages": "سيتم مسح رسائل الجلسة الحالية قريبًا، وبمجرد المسح لن يمكن استعادتها، يرجى تأكيد الإجراء الخاص بك",
|
||||
"confirmRemoveChatGroupItemAlert": "سيتم حذف هذه المجموعة، ولن يتأثر أعضاء الفريق. يرجى تأكيد الإجراء.",
|
||||
"confirmRemoveGroupItemAlert": "سيتم حذف هذه المجموعة قريبًا. بعد الحذف، سيُنتقل المساعدون في هذه المجموعة إلى القائمة الافتراضية. يرجى تأكيد إجراء الحذف.",
|
||||
"confirmRemoveGroupSuccess": "تم حذف المجموعة بنجاح",
|
||||
"confirmRemoveSessionItemAlert": "أنت على وشك حذف هذا الوكيل. بمجرد الحذف، لا يمكن استعادته. يرجى تأكيد الإجراء.",
|
||||
"confirmRemoveSessionSuccess": "تم حذف الوكيل بنجاح",
|
||||
"defaultAgent": "الوكيل الافتراضي",
|
||||
"confirmRemoveSessionItemAlert": "سيتم حذف هذا المساعد قريبًا، وبمجرد الحذف لن يمكن استعادته، يرجى تأكيد الإجراء الخاص بك",
|
||||
"confirmRemoveSessionSuccess": "تم حذف المساعد بنجاح",
|
||||
"defaultAgent": "المساعد الافتراضي",
|
||||
"defaultGroupChat": "مجموعة",
|
||||
"defaultList": "القائمة الافتراضية",
|
||||
"defaultSession": "الوكيل الافتراضي",
|
||||
"desktopNotification.aiReplyCompleted.body": "رد الوكيل جاهز",
|
||||
"desktopNotification.aiReplyCompleted.title": "تم إكمال الرد",
|
||||
"defaultSession": "المساعد الافتراضي",
|
||||
"desktopNotification.aiReplyCompleted.body": "تم الانتهاء من توليد رد الذكاء الاصطناعي",
|
||||
"desktopNotification.aiReplyCompleted.title": "اكتمل رد الذكاء الاصطناعي",
|
||||
"dm.placeholder": "ستظهر رسائلك الخاصة مع {{agentTitle}} هنا.",
|
||||
"dm.tooltip": "إرسال رسالة خاصة",
|
||||
"dm.tooltip": "أرسل رسالة خاصة",
|
||||
"dm.visibleTo": "مرئي فقط لـ {{target}}",
|
||||
"dm.you": "أنت",
|
||||
"duplicateSession.loading": "يتم النسخ...",
|
||||
"duplicateSession.loading": "جاري النسخ...",
|
||||
"duplicateSession.success": "تم النسخ بنجاح",
|
||||
"duplicateSession.title": "نسخة {{title}}",
|
||||
"duplicateTitle": "نسخة {{title}}",
|
||||
"emptyAgent": "لا يوجد وكلاء بعد. ابدأ بأول وكيل لك — وابنِ نظامك بمرور الوقت.",
|
||||
"emptyAgentAction": "إنشاء وكيل",
|
||||
"extendParams.disableContextCaching.desc": "يقلل ما يصل إلى 90٪ من تكلفة توليد محادثة واحدة ويوفر سرعة تصل إلى 4 أضعاف. تفعيل هذا سيقوم تلقائيًا بإلغاء الحد على عدد الرسائل التاريخية. <1>اعرف المزيد</1>",
|
||||
"extendParams.disableContextCaching.title": "تفعيل تخزين السياق المؤقت",
|
||||
"extendParams.enableReasoning.desc": "استنادًا إلى آلية التفكير في Claude، فإن تفعيل هذا سيقوم تلقائيًا بإلغاء الحد على عدد الرسائل التاريخية. <1>اعرف المزيد</1>",
|
||||
"duplicateSession.title": "{{title}} نسخة",
|
||||
"duplicateTitle": "{{title}} نسخة",
|
||||
"emptyAgent": "لا يوجد مساعد",
|
||||
"emptyAgentAction": "إنشاء مساعد",
|
||||
"extendParams.disableContextCaching.desc": "يمكن تقليل تكلفة توليد محادثة واحدة بنسبة تصل إلى 90%، وزيادة سرعة الاستجابة بمقدار 4 مرات (<1>اعرف المزيد</1>). عند التفعيل، سيتم تعطيل حد عدد الرسائل التاريخية تلقائيًا",
|
||||
"extendParams.disableContextCaching.title": "تفعيل تخزين السياق",
|
||||
"extendParams.enableReasoning.desc": "استنادًا إلى آلية تفكير كلود (Claude Thinking) المحدودة (<1>اعرف المزيد</1>)، عند التفعيل، سيتم تعطيل حد عدد الرسائل التاريخية تلقائيًا",
|
||||
"extendParams.enableReasoning.title": "تفعيل التفكير العميق",
|
||||
"extendParams.imageAspectRatio.title": "نسبة أبعاد الصورة",
|
||||
"extendParams.imageAspectRatio.title": "نسبة العرض إلى الارتفاع للصورة",
|
||||
"extendParams.imageResolution.title": "دقة الصورة",
|
||||
"extendParams.reasoningBudgetToken.title": "رمز استهلاك التفكير",
|
||||
"extendParams.reasoningEffort.title": "شدة التفكير",
|
||||
"extendParams.textVerbosity.title": "مستوى تفصيل النص الناتج",
|
||||
"extendParams.reasoningBudgetToken.title": "استهلاك توكن التفكير",
|
||||
"extendParams.reasoningEffort.title": "شدة الاستدلال",
|
||||
"extendParams.textVerbosity.title": "مستوى تفصيل المخرجات النصية",
|
||||
"extendParams.thinking.title": "مفتاح التفكير العميق",
|
||||
"extendParams.thinkingLevel.title": "مستوى التفكير",
|
||||
"extendParams.title": "ميزات توسيع النموذج",
|
||||
"extendParams.urlContext.desc": "عند التفعيل، سيتم تحليل الروابط تلقائيًا لاستخراج محتوى صفحة الويب الفعلي",
|
||||
"extendParams.title": "وظائف توسيع النموذج",
|
||||
"extendParams.urlContext.desc": "عند التفعيل، سيتم تحليل روابط الويب تلقائيًا للحصول على محتوى السياق الفعلي للصفحة",
|
||||
"extendParams.urlContext.title": "استخراج محتوى رابط الويب",
|
||||
"group.desc": "ادفع المهمة للأمام مع عدة وكلاء في مساحة مشتركة واحدة.",
|
||||
"group.memberTooltip": "يوجد {{count}} عضو في المجموعة",
|
||||
"group.orchestratorThinking": "المنسق يفكر...",
|
||||
"group.removeMember": "إزالة العضو",
|
||||
"group.desc": "التعاون مع عدة مساعدين للذكاء الاصطناعي في مساحة محادثة مشتركة.",
|
||||
"group.memberTooltip": "هناك {{count}} عضوًا في المجموعة",
|
||||
"group.orchestratorThinking": "المُنسق يفكر...",
|
||||
"group.removeMember": "إزالة عضو",
|
||||
"group.title": "مجموعة",
|
||||
"groupDescription": "وصف المجموعة",
|
||||
"groupSidebar.agentProfile.chat": "محادثة",
|
||||
"groupDescription": "وصف الفريق",
|
||||
"groupSidebar.agentProfile.chat": "الدردشة",
|
||||
"groupSidebar.agentProfile.model": "النموذج",
|
||||
"groupSidebar.members.addMember": "إضافة عضو",
|
||||
"groupSidebar.members.enableOrchestrator": "تفعيل المنسق",
|
||||
"groupSidebar.members.memberSettings": "إعدادات الأعضاء",
|
||||
"groupSidebar.members.orchestrator": "المنسق",
|
||||
"groupSidebar.members.orchestratorThinking": "المنسق يفكر...",
|
||||
"groupSidebar.members.removeMember": "إزالة العضو",
|
||||
"groupSidebar.members.stopOrchestrator": "إيقاف",
|
||||
"groupSidebar.members.triggerOrchestrator": "تشغيل",
|
||||
"groupSidebar.tabs.host": "المنسق",
|
||||
"groupSidebar.members.memberSettings": "إعدادات العضو",
|
||||
"groupSidebar.members.orchestrator": "المُنسق",
|
||||
"groupSidebar.members.orchestratorThinking": "المُنسق يفكر...",
|
||||
"groupSidebar.members.removeMember": "إزالة عضو",
|
||||
"groupSidebar.members.stopOrchestrator": "إيقاف التفكير",
|
||||
"groupSidebar.members.triggerOrchestrator": "بدء المحادثة الجماعية",
|
||||
"groupSidebar.tabs.host": "المضيف",
|
||||
"groupSidebar.tabs.members": "الأعضاء",
|
||||
"groupSidebar.tabs.role": "الملف الشخصي",
|
||||
"groupWizard.chooseMembers": "اختر وكلاء موجودين...",
|
||||
"groupWizard.createGroup": "إنشاء مجموعة",
|
||||
"groupSidebar.tabs.role": "الإعداد",
|
||||
"groupWizard.chooseMembers": "اختر المساعدين الحاليين...",
|
||||
"groupWizard.createGroup": "إنشاء فريق",
|
||||
"groupWizard.existingMembers": "الوكلاء الحاليون",
|
||||
"groupWizard.groupMembers": "سيتم أيضًا إضافة هؤلاء الوكلاء إلى قائمتك",
|
||||
"groupWizard.host.description": "دع المجموعة تتقدم تلقائيًا. يمكنك التدخل في أي وقت.",
|
||||
"groupWizard.host.title": "تفعيل المنسق",
|
||||
"groupWizard.host.tooltip": "عند الإيقاف، ستحتاج إلى الإشارة إلى الأعضاء للحصول على ردودهم.",
|
||||
"groupWizard.groupMembers": "سيتم أيضًا إضافة هؤلاء المساعدين إلى قائمتك",
|
||||
"groupWizard.host.description": "تمكين الفريق من العمل بشكل مستقل",
|
||||
"groupWizard.host.title": "تفعيل المضيف",
|
||||
"groupWizard.host.tooltip": "إذا قمت بتعطيل المضيف، فستحتاج إلى الإشارة إلى الأعضاء يدويًا باستخدام @ لكي يتمكنوا من الرد",
|
||||
"groupWizard.memberCount": "{{count}} عضو",
|
||||
"groupWizard.noMatchingTemplates": "لا توجد قوالب مطابقة",
|
||||
"groupWizard.noSelectedTemplates": "لم يتم تحديد أي قوالب",
|
||||
"groupWizard.noSelectedTemplates": "لم يتم اختيار أي قالب",
|
||||
"groupWizard.noTemplateMembers": "لا يوجد أعضاء في القالب",
|
||||
"groupWizard.noTemplates": "لا توجد قوالب متاحة",
|
||||
"groupWizard.searchTemplates": "البحث في القوالب...",
|
||||
"groupWizard.searchTemplates": "ابحث في القوالب...",
|
||||
"groupWizard.title": "إنشاء مجموعة",
|
||||
"groupWizard.useTemplate": "استخدام قالب",
|
||||
"hideForYou": "محتوى الرسائل الخاصة مخفي. يرجى تفعيل 'عرض محتوى الرسائل الخاصة' في الإعدادات لعرضه.",
|
||||
"history.title": "سيحتفظ الوكيل فقط بآخر {{count}} رسالة.",
|
||||
"historyRange": "نطاق السجل",
|
||||
"historySummary": "ملخص الرسائل السابقة",
|
||||
"groupWizard.useTemplate": "استخدام القالب",
|
||||
"hideForYou": "تم إخفاء محتوى الرسائل الخاصة، يرجى تفعيل خيار 【عرض محتوى الرسائل الخاصة】 في الإعدادات للعرض",
|
||||
"history.title": "سيتذكر المساعد آخر {{count}} رسالة فقط",
|
||||
"historyRange": "نطاق التاريخ",
|
||||
"historySummary": "ملخص الرسائل التاريخية",
|
||||
"inactive": "غير نشط",
|
||||
"inbox.desc": "تعاون في مساحة عمل واحدة وحوّل الأفكار إلى نتائج.",
|
||||
"inbox.desc": "قم بتشغيل مجموعة الدماغ وأشعل شرارة التفكير. مساعدك الذكي، هنا حيث يمكنك التواصل بكل شيء",
|
||||
"inbox.title": "Lobe AI",
|
||||
"input.addAi": "إضافة رسالة من الذكاء الاصطناعي",
|
||||
"input.addUser": "إضافة رسالة من المستخدم",
|
||||
"input.disclaimer": "قد يخطئ الوكلاء. استخدم حكمك الخاص للمعلومات الحساسة.",
|
||||
"input.errorMsg": "فشل الإرسال: {{errorMsg}}. أعد المحاولة أو أرسل لاحقًا.",
|
||||
"input.addAi": "إضافة رسالة AI",
|
||||
"input.addUser": "إضافة رسالة مستخدم",
|
||||
"input.disclaimer": "قد يرتكب الذكاء الاصطناعي أخطاءً أيضًا، يرجى التحقق من المعلومات الهامة",
|
||||
"input.errorMsg": "فشل إرسال الرسالة، يرجى التحقق من الشبكة والمحاولة مرة أخرى: {{errorMsg}}",
|
||||
"input.more": "المزيد",
|
||||
"input.send": "إرسال",
|
||||
"input.sendWithCmdEnter": "اضغط <key/> للإرسال",
|
||||
"input.sendWithEnter": "اضغط <key/> للإرسال",
|
||||
"input.stop": "إيقاف",
|
||||
"input.warp": "سطر جديد",
|
||||
"input.warpWithKey": "اضغط <key/> لإدراج فاصل أسطر",
|
||||
"intentUnderstanding.title": "جارٍ فهم نيتك...",
|
||||
"input.stop": "توقف",
|
||||
"input.warp": "تغيير السطر",
|
||||
"input.warpWithKey": "اضغط على مفتاح <key/> للانتقال إلى السطر",
|
||||
"intentUnderstanding.title": "جارٍ فهم وتحليل نواياك...",
|
||||
"inviteMembers": "دعوة الأعضاء",
|
||||
"knowledgeBase.all": "كل المحتوى",
|
||||
"knowledgeBase.allFiles": "كل الملفات",
|
||||
"knowledgeBase.allLibraries": "كل المكتبات",
|
||||
"knowledgeBase.disabled": "دردشة المكتبة غير متاحة في هذا النشر. يرجى التبديل إلى قاعدة بيانات على الخادم أو استخدام {{cloud}}.",
|
||||
"knowledgeBase.all": "جميع المحتويات",
|
||||
"knowledgeBase.allFiles": "جميع الملفات",
|
||||
"knowledgeBase.allLibraries": "جميع قواعد البيانات",
|
||||
"knowledgeBase.disabled": "وضع النشر الحالي لا يدعم المحادثة مع قاعدة البيانات. لاستخدام هذه الميزة، يرجى التبديل إلى نشر قاعدة بيانات على الخادم أو استخدام خدمة {{cloud}}",
|
||||
"knowledgeBase.library.action.add": "إضافة",
|
||||
"knowledgeBase.library.action.detail": "تفاصيل",
|
||||
"knowledgeBase.library.action.remove": "إزالة",
|
||||
"knowledgeBase.library.title": "الملفات / المكتبات",
|
||||
"knowledgeBase.relativeFilesOrLibraries": "الملفات/المكتبات ذات الصلة",
|
||||
"knowledgeBase.title": "المكتبة",
|
||||
"knowledgeBase.uploadGuide": "يمكن عرض الملفات المرفوعة في قسم 'الموارد'.",
|
||||
"knowledgeBase.library.title": "الملفات / قاعدة البيانات",
|
||||
"knowledgeBase.relativeFilesOrLibraries": "الملفات / قواعد البيانات المرتبطة",
|
||||
"knowledgeBase.title": "قاعدة البيانات",
|
||||
"knowledgeBase.uploadGuide": "يمكنك عرض الملفات التي تم تحميلها في قسم \"الموارد\"",
|
||||
"knowledgeBase.viewMore": "عرض المزيد",
|
||||
"memberSelection.addMember": "إضافة عضو",
|
||||
"memberSelection.allMembers": "جميع الأعضاء",
|
||||
"memberSelection.createGroup": "إنشاء مجموعة",
|
||||
"memberSelection.noAvailableAgents": "لا يوجد وكلاء متاحون للدعوة",
|
||||
"memberSelection.noSelectedAgents": "لم يتم تحديد أي وكلاء بعد",
|
||||
"memberSelection.searchAgents": "البحث عن وكلاء...",
|
||||
"memberSelection.selectedAgents": "المحددون ({{count}})",
|
||||
"memberSelection.setInitialMembers": "تحديد أعضاء المجموعة",
|
||||
"memberSelection.noSelectedAgents": "لم يتم اختيار أي وكيل بعد",
|
||||
"memberSelection.searchAgents": "ابحث عن وكيل...",
|
||||
"memberSelection.selectedAgents": "تم الاختيار ({{count}})",
|
||||
"memberSelection.setInitialMembers": "اختيار أعضاء الفريق",
|
||||
"members": "الأعضاء",
|
||||
"mention.title": "الإشارة إلى الأعضاء",
|
||||
"messageAction.collapse": "طي الرسالة",
|
||||
"messageAction.collapse": "إخفاء الرسائل",
|
||||
"messageAction.continueGeneration": "متابعة التوليد",
|
||||
"messageAction.delAndRegenerate": "حذف وإعادة التوليد",
|
||||
"messageAction.deleteDisabledByThreads": "لا يمكن حذف هذه الرسالة لأنها تحتوي على موضوع فرعي",
|
||||
"messageAction.expand": "توسيع الرسالة",
|
||||
"messageAction.regenerate": "إعادة التوليد",
|
||||
"messageAction.delAndRegenerate": "حذف وإعادة الإنشاء",
|
||||
"messageAction.deleteDisabledByThreads": "يوجد موضوعات فرعية، لا يمكن الحذف",
|
||||
"messageAction.expand": "عرض الرسائل",
|
||||
"messageAction.regenerate": "إعادة الإنشاء",
|
||||
"messages.dm.sentTo": "مرئي فقط لـ {{name}}",
|
||||
"messages.dm.title": "رسالة خاصة",
|
||||
"messages.modelCard.credit": "الأرصدة",
|
||||
"messages.dm.title": "الرسائل الخاصة",
|
||||
"messages.modelCard.credit": "نقاط",
|
||||
"messages.modelCard.creditPricing": "التسعير",
|
||||
"messages.modelCard.creditTooltip": "لأغراض العد، نعتبر 1 دولار = 1 مليون رصيد. مثال: 3 دولارات/مليون رموز → 3 أرصدة لكل رمز.",
|
||||
"messages.modelCard.pricing.inputCachedTokens": "المدخلات المخزنة {{amount}} أرصدة · ${{amount}}/مليون",
|
||||
"messages.modelCard.pricing.inputCharts": "${{amount}}/مليون حرف",
|
||||
"messages.modelCard.creditTooltip": "لتسهيل العد، نقوم بتحويل 1$ إلى 1M نقطة، على سبيل المثال، 3$/M رموز تعني 3 نقاط/رمز",
|
||||
"messages.modelCard.pricing.inputCachedTokens": "مدخلات مخزنة {{amount}}/نقطة · ${{amount}}/M",
|
||||
"messages.modelCard.pricing.inputCharts": "${{amount}}/M حرف",
|
||||
"messages.modelCard.pricing.inputMinutes": "${{amount}}/دقيقة",
|
||||
"messages.modelCard.pricing.inputTokens": "المدخلات {{amount}} أرصدة · ${{amount}}/مليون",
|
||||
"messages.modelCard.pricing.outputTokens": "المخرجات {{amount}} أرصدة · ${{amount}}/مليون",
|
||||
"messages.modelCard.pricing.writeCacheInputTokens": "كتابة إلى التخزين المؤقت {{amount}} أرصدة · ${{amount}}/مليون",
|
||||
"messages.tokenDetails.average": "متوسط السعر للوحدة",
|
||||
"messages.tokenDetails.input": "المدخلات",
|
||||
"messages.tokenDetails.inputAudio": "مدخل صوتي",
|
||||
"messages.tokenDetails.inputCached": "مدخل مخزن مؤقتًا",
|
||||
"messages.tokenDetails.inputCitation": "استشهاد المدخل",
|
||||
"messages.tokenDetails.inputText": "مدخل نصي",
|
||||
"messages.tokenDetails.inputTitle": "تفاصيل المدخل",
|
||||
"messages.tokenDetails.inputUncached": "مدخل غير مخزن مؤقتًا",
|
||||
"messages.tokenDetails.inputWriteCached": "كتابة إلى التخزين المؤقت للمدخل",
|
||||
"messages.tokenDetails.output": "المخرجات",
|
||||
"messages.tokenDetails.outputAudio": "مخرج صوتي",
|
||||
"messages.tokenDetails.outputImage": "مخرج صورة",
|
||||
"messages.tokenDetails.outputText": "مخرج نصي",
|
||||
"messages.tokenDetails.outputTitle": "تفاصيل المخرج",
|
||||
"messages.modelCard.pricing.inputTokens": "مدخلات {{amount}}/نقطة · ${{amount}}/M",
|
||||
"messages.modelCard.pricing.outputTokens": "مخرجات {{amount}}/نقطة · ${{amount}}/M",
|
||||
"messages.modelCard.pricing.writeCacheInputTokens": "تخزين إدخال الكتابة {{amount}}/نقطة · ${{amount}}/ميغابايت",
|
||||
"messages.tokenDetails.average": "متوسط السعر",
|
||||
"messages.tokenDetails.input": "مدخلات",
|
||||
"messages.tokenDetails.inputAudio": "مدخلات صوتية",
|
||||
"messages.tokenDetails.inputCached": "مدخلات مخزنة",
|
||||
"messages.tokenDetails.inputCitation": "اقتباس الإدخال",
|
||||
"messages.tokenDetails.inputText": "مدخلات نصية",
|
||||
"messages.tokenDetails.inputTitle": "تفاصيل المدخلات",
|
||||
"messages.tokenDetails.inputUncached": "مدخلات غير مخزنة",
|
||||
"messages.tokenDetails.inputWriteCached": "تخزين إدخال الكتابة",
|
||||
"messages.tokenDetails.output": "مخرجات",
|
||||
"messages.tokenDetails.outputAudio": "مخرجات صوتية",
|
||||
"messages.tokenDetails.outputImage": "إخراج الصورة",
|
||||
"messages.tokenDetails.outputText": "مخرجات نصية",
|
||||
"messages.tokenDetails.outputTitle": "تفاصيل المخرجات",
|
||||
"messages.tokenDetails.reasoning": "تفكير عميق",
|
||||
"messages.tokenDetails.speed.tps.title": "TPS",
|
||||
"messages.tokenDetails.speed.tps.tooltip": "الرموز في الثانية (TPS). يشير إلى متوسط سرعة المحتوى الذي يولده الذكاء الاصطناعي (رموز/ثانية)، محسوبًا من لحظة استلام أول رمز.",
|
||||
"messages.tokenDetails.speed.tps.tooltip": "عدد الرموز في الثانية، TPS. يشير إلى متوسط سرعة توليد المحتوى بواسطة الذكاء الاصطناعي (رمز/ثانية)، ويبدأ الحساب عند استلام أول رمز.",
|
||||
"messages.tokenDetails.speed.ttft.title": "TTFT",
|
||||
"messages.tokenDetails.speed.ttft.tooltip": "الوقت لأول رمز (TTFT). يشير إلى الفترة الزمنية من إرسال الرسالة إلى استلام أول رمز من العميل.",
|
||||
"messages.tokenDetails.speed.ttft.tooltip": "الوقت حتى أول رمز، TTFT. يشير إلى الفارق الزمني من لحظة إرسال الرسالة حتى استلام أول رمز في العميل.",
|
||||
"messages.tokenDetails.title": "تفاصيل التوليد",
|
||||
"messages.tokenDetails.total": "الاستهلاك الكلي",
|
||||
"minimap.jumpToMessage": "الانتقال إلى الرسالة {{index}}",
|
||||
"messages.tokenDetails.total": "الإجمالي المستهلك",
|
||||
"minimap.jumpToMessage": "الانتقال إلى الرسالة رقم {{index}}",
|
||||
"minimap.nextMessage": "الرسالة التالية",
|
||||
"minimap.previousMessage": "الرسالة السابقة",
|
||||
"minimap.senderAssistant": "الوكيل",
|
||||
"minimap.senderUser": "أنت",
|
||||
"newAgent": "إنشاء وكيل",
|
||||
"newAgent": "إنشاء مساعد",
|
||||
"newGroupChat": "إنشاء مجموعة",
|
||||
"newPage": "إنشاء صفحة",
|
||||
"noAgentsYet": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على زر + لدعوة وكلاء.",
|
||||
"newPage": "إنشاء مستند",
|
||||
"noAgentsYet": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على زر + لدعوة مساعد.",
|
||||
"noAvailableAgents": "لا يوجد أعضاء متاحون للدعوة",
|
||||
"noMatchingAgents": "لم يتم العثور على أعضاء مطابقين",
|
||||
"noMembersYet": "لا تحتوي هذه المجموعة على أي أعضاء بعد. انقر على زر + لدعوة وكلاء.",
|
||||
"noSelectedAgents": "لم يتم تحديد أي أعضاء بعد",
|
||||
"openInNewWindow": "فتح في نافذة جديدة",
|
||||
"noMatchingAgents": "لا يوجد أعضاء مطابقون",
|
||||
"noMembersYet": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على زر + لدعوة المساعدين.",
|
||||
"noSelectedAgents": "لم يتم اختيار أي أعضاء بعد",
|
||||
"openInNewWindow": "فتح في نافذة مستقلة",
|
||||
"owner": "مالك المجموعة",
|
||||
"pageCopilot.title": "وكيل الصفحة",
|
||||
"pageCopilot.welcome": "**كتابة أوضح وأكثر دقة**\n\nاكتب مسودة أو أعد الصياغة أو حسّن—أخبرني بنيتك وسأتولى الباقي.",
|
||||
"pageCopilot.title": "مساعد النصوص",
|
||||
"pageCopilot.welcome": "**لنجعل كل جملة أكثر دقة.**\n\nسواء كنت تكتب مسودة، تعيد الصياغة، أو تقوم بالتحرير، سأساعدك في جعل كلماتك أوضح، أكثر طبيعية، وأكثر إقناعًا.",
|
||||
"pin": "تثبيت",
|
||||
"pinOff": "إلغاء التثبيت",
|
||||
"prompts.summaryExpert": "بصفتك خبيرًا في التلخيص، يرجى تلخيص المحتوى التالي بناءً على التعليمات أعلاه:",
|
||||
"rag.referenceChunks": "مصدر المرجع",
|
||||
"rag.userQuery.actions.delete": "حذف إعادة صياغة الاستعلام",
|
||||
"prompts.summaryExpert": "بصفتك خبيرًا في التلخيص، يرجى استخدام الإرشادات أعلاه لتلخيص المحتوى التالي:",
|
||||
"rag.referenceChunks": "مراجع",
|
||||
"rag.userQuery.actions.delete": "حذف الاستعلام",
|
||||
"rag.userQuery.actions.regenerate": "إعادة توليد الاستعلام",
|
||||
"regenerate": "إعادة التوليد",
|
||||
"roleAndArchive": "ملف الوكيل وسجل المحادثات",
|
||||
"regenerate": "إعادة الإنشاء",
|
||||
"roleAndArchive": "الدور والأرشيف",
|
||||
"search.grounding.searchQueries": "كلمات البحث",
|
||||
"search.grounding.title": "تم العثور على {{count}} نتيجة",
|
||||
"search.mode.auto.desc": "البحث في الويب تلقائيًا عند الحاجة.",
|
||||
"search.mode.auto.title": "تلقائي",
|
||||
"search.mode.off.desc": "تعطيل الوصول إلى الإنترنت.",
|
||||
"search.mode.off.title": "إيقاف",
|
||||
"search.mode.on.desc": "البحث دائمًا في الويب للحصول على أحدث المعلومات.",
|
||||
"search.mode.on.title": "دائمًا مفعّل",
|
||||
"search.mode.useModelBuiltin": "استخدام البحث المدمج في النموذج",
|
||||
"search.searchModel.desc": "النموذج الحالي لا يدعم استدعاء الوظائف، لذا يجب إقرانه بنموذج يدعم ذلك للبحث عبر الإنترنت.",
|
||||
"search.searchModel.title": "نموذج مساعد للبحث",
|
||||
"search.title": "بحث الويب",
|
||||
"searchAgentPlaceholder": "البحث عن وكلاء...",
|
||||
"searchAgents": "البحث عن وكلاء...",
|
||||
"selectedAgents": "الوكلاء المحددون",
|
||||
"sendPlaceholder": "اطرح سؤالًا، أنشئ، أو ابدأ مهمة، <hotkey><hotkey/>",
|
||||
"sessionGroup.config": "إدارة المجموعة",
|
||||
"sessionGroup.confirmRemoveGroupAlert": "سيتم حذف هذه المجموعة. بعد الحذف، سيتم نقل الوكلاء إلى القائمة الافتراضية. يرجى تأكيد العملية.",
|
||||
"sessionGroup.createAgentSuccess": "تم إنشاء الوكيل بنجاح",
|
||||
"search.mode.auto.desc": "تحديد ما إذا كان من الضروري البحث بناءً على محتوى المحادثة",
|
||||
"search.mode.auto.title": "الاتصال الذكي",
|
||||
"search.mode.off.desc": "استخدام المعرفة الأساسية للنموذج فقط، دون إجراء بحث عبر الإنترنت",
|
||||
"search.mode.off.title": "إيقاف الاتصال",
|
||||
"search.mode.on.desc": "الاستمرار في البحث عبر الإنترنت للحصول على أحدث المعلومات",
|
||||
"search.mode.on.title": "الاتصال دائمًا",
|
||||
"search.mode.useModelBuiltin": "استخدام محرك البحث المدمج في النموذج",
|
||||
"search.searchModel.desc": "النموذج الحالي لا يدعم استدعاء الدوال، لذا يجب استخدام نموذج يدعم استدعاء الدوال للبحث عبر الإنترنت",
|
||||
"search.searchModel.title": "نموذج البحث المساعد",
|
||||
"search.title": "بحث عبر الإنترنت",
|
||||
"searchAgentPlaceholder": "مساعد البحث...",
|
||||
"searchAgents": "مساعد البحث...",
|
||||
"selectedAgents": "المساعدون المختارون",
|
||||
"sendPlaceholder": "اطرح سؤالًا، أنشئ محتوى، أو ابدأ مهمة، <hotkey><hotkey/>",
|
||||
"sessionGroup.config": "إدارة المجموعات",
|
||||
"sessionGroup.confirmRemoveGroupAlert": "سيتم حذف هذه المجموعة قريبًا، وبعد الحذف، سيتم نقل مساعدي هذه المجموعة إلى القائمة الافتراضية، يرجى تأكيد إجراءك",
|
||||
"sessionGroup.createAgentSuccess": "تم إنشاء المساعد بنجاح",
|
||||
"sessionGroup.createGroup": "إضافة مجموعة جديدة",
|
||||
"sessionGroup.createGroupFailed": "فشل في إنشاء محادثة جماعية",
|
||||
"sessionGroup.createGroupFailed": "فشل إنشاء المحادثة الجماعية",
|
||||
"sessionGroup.createGroupSuccess": "تم إنشاء المحادثة الجماعية بنجاح",
|
||||
"sessionGroup.createSuccess": "تم الإنشاء بنجاح",
|
||||
"sessionGroup.creatingAgent": "جارٍ إنشاء الوكيل...",
|
||||
"sessionGroup.creatingAgent": "جاري إنشاء المساعد...",
|
||||
"sessionGroup.groupName": "اسم المجموعة",
|
||||
"sessionGroup.inputPlaceholder": "يرجى إدخال اسم المجموعة...",
|
||||
"sessionGroup.inputPlaceholder": "الرجاء إدخال اسم المجموعة...",
|
||||
"sessionGroup.moveGroup": "نقل إلى مجموعة",
|
||||
"sessionGroup.newGroup": "مجموعة جديدة",
|
||||
"sessionGroup.noAvailableAgents": "لا يوجد وكلاء متاحون",
|
||||
"sessionGroup.noMatchingAgents": "لم يتم العثور على وكلاء مطابقين",
|
||||
"sessionGroup.noSelectedAgents": "يرجى تحديد وكلاء",
|
||||
"sessionGroup.noAvailableAgents": "لا يوجد مساعدين متاحين حالياً",
|
||||
"sessionGroup.noMatchingAgents": "لم يتم العثور على مساعدين مطابقين",
|
||||
"sessionGroup.noSelectedAgents": "يرجى اختيار مساعدين",
|
||||
"sessionGroup.rename": "إعادة تسمية المجموعة",
|
||||
"sessionGroup.renameSuccess": "تمت إعادة التسمية بنجاح",
|
||||
"sessionGroup.searchAgents": "البحث عن وكلاء",
|
||||
"sessionGroup.selectedAgents": "الوكلاء المحددون ({{count}})",
|
||||
"sessionGroup.sortSuccess": "تم الترتيب بنجاح",
|
||||
"sessionGroup.sorting": "جارٍ تحديث ترتيب المجموعات...",
|
||||
"sessionGroup.tooLong": "يجب أن يتراوح طول اسم المجموعة بين 1 و20 حرفًا",
|
||||
"sessionGroup.searchAgents": "البحث عن مساعدين",
|
||||
"sessionGroup.selectedAgents": "المساعدون المختارون ({{count}})",
|
||||
"sessionGroup.sortSuccess": "تمت إعادة ترتيب بنجاح",
|
||||
"sessionGroup.sorting": "جاري تحديث ترتيب المجموعة...",
|
||||
"sessionGroup.tooLong": "يجب أن يكون طول اسم المجموعة بين 1 و 20",
|
||||
"shareModal.copy": "نسخ",
|
||||
"shareModal.download": "تحميل لقطة شاشة",
|
||||
"shareModal.downloadError": "فشل التحميل",
|
||||
"shareModal.download": "تحميل اللقطة",
|
||||
"shareModal.downloadError": "فشل التنزيل",
|
||||
"shareModal.downloadFile": "تحميل الملف",
|
||||
"shareModal.downloadPdf": "تحميل PDF",
|
||||
"shareModal.downloadSuccess": "تم التحميل بنجاح",
|
||||
"shareModal.downloadPdf": "تنزيل PDF",
|
||||
"shareModal.downloadSuccess": "تم التنزيل بنجاح",
|
||||
"shareModal.exportMode.full": "افتراضي",
|
||||
"shareModal.exportMode.label": "وضع التصدير",
|
||||
"shareModal.exportMode.simple": "متوافق مع OpenAI",
|
||||
"shareModal.exportPdf": "تصدير كـ PDF",
|
||||
"shareModal.exportPdf": "تصدير إلى PDF",
|
||||
"shareModal.exportTitle": "العنوان الافتراضي",
|
||||
"shareModal.generatePdf": "إنشاء PDF",
|
||||
"shareModal.generatePdf": "إنشاء ملف PDF",
|
||||
"shareModal.generatingPdf": "جارٍ إنشاء PDF...",
|
||||
"shareModal.imageType": "تنسيق الصورة",
|
||||
"shareModal.includeTool": "تضمين رسائل المهارة",
|
||||
"shareModal.includeUser": "تضمين رسائل المستخدم",
|
||||
"shareModal.loadingPdf": "جارٍ تحميل PDF...",
|
||||
"shareModal.noPdfData": "لا توجد بيانات PDF متاحة",
|
||||
"shareModal.imageType": "نوع الصورة",
|
||||
"shareModal.includeTool": "تضمين رسالة الأداة",
|
||||
"shareModal.includeUser": "تضمين رسالة المستخدم",
|
||||
"shareModal.loadingPdf": "جارٍ تحميل ملف PDF...",
|
||||
"shareModal.noPdfData": "لا توجد بيانات PDF",
|
||||
"shareModal.pdf": "PDF",
|
||||
"shareModal.pdfErrorDescription": "حدث خطأ أثناء إنشاء PDF، يرجى المحاولة مرة أخرى",
|
||||
"shareModal.pdfGenerationError": "فشل إنشاء PDF",
|
||||
"shareModal.pdfReady": "PDF جاهز",
|
||||
"shareModal.regeneratePdf": "إعادة إنشاء PDF",
|
||||
"shareModal.pdfReady": "تم تجهيز PDF",
|
||||
"shareModal.regeneratePdf": "إعادة إنشاء ملف PDF",
|
||||
"shareModal.screenshot": "لقطة شاشة",
|
||||
"shareModal.settings": "إعدادات التصدير",
|
||||
"shareModal.text": "نص",
|
||||
"shareModal.widthMode.label": "وضع العرض",
|
||||
"shareModal.widthMode.narrow": "ضيق",
|
||||
"shareModal.widthMode.wide": "عريض",
|
||||
"shareModal.widthMode.narrow": "وضع الشاشة الضيقة",
|
||||
"shareModal.widthMode.wide": "وضع الشاشة الواسعة",
|
||||
"shareModal.withBackground": "تضمين صورة الخلفية",
|
||||
"shareModal.withFooter": "تضمين التذييل",
|
||||
"shareModal.withPluginInfo": "تضمين معلومات المهارة",
|
||||
"shareModal.withRole": "تضمين دور الرسالة",
|
||||
"shareModal.withSystemRole": "تضمين ملف الوكيل",
|
||||
"shareModal.withFooter": "تضمين تذييل",
|
||||
"shareModal.withPluginInfo": "تضمين معلومات البرنامج المساعد",
|
||||
"shareModal.withRole": "تضمين رسالة الدور",
|
||||
"shareModal.withSystemRole": "تضمين دور المساعد",
|
||||
"stt.action": "إدخال صوتي",
|
||||
"stt.loading": "جارٍ التعرف...",
|
||||
"stt.prettifying": "جارٍ التجميل...",
|
||||
"supervisor.label": "المشرف",
|
||||
"supervisor.todoList.allComplete": "تم إكمال جميع المهام",
|
||||
"supervisor.todoList.title": "المهام المكتملة",
|
||||
"supervisor.todoList.allComplete": "تم إنجاز جميع المهام",
|
||||
"supervisor.todoList.title": "المهام المنجزة",
|
||||
"tab.groupProfile": "ملف المجموعة",
|
||||
"tab.profile": "ملف الوكيل",
|
||||
"tab.profile": "ملف المساعد",
|
||||
"tab.search": "بحث",
|
||||
"task.activity.calling": "جارٍ استدعاء المهارة...",
|
||||
"task.activity.calling": "جارٍ استدعاء الأداة...",
|
||||
"task.activity.generating": "جارٍ توليد الرد...",
|
||||
"task.activity.gotResult": "تم استلام نتيجة الأداة",
|
||||
"task.activity.gotResult": "تم الحصول على نتيجة الأداة",
|
||||
"task.activity.toolCalling": "جارٍ استدعاء {{toolName}}...",
|
||||
"task.activity.toolResult": "تم استلام نتيجة {{toolName}}",
|
||||
"task.batchTasks": "{{count}} مهمة فرعية مجمعة",
|
||||
"task.metrics.stepsShort": "خطوات",
|
||||
"task.metrics.toolCallsShort": "استخدامات الأداة",
|
||||
"task.status.initializing": "جارٍ تهيئة المهمة...",
|
||||
"task.subtask": "مهمة فرعية",
|
||||
"task.activity.toolResult": "تم الحصول على نتيجة {{toolName}}",
|
||||
"task.metrics.stepsShort": "خطوة",
|
||||
"task.metrics.toolCallsShort": "مرة استخدام الأداة",
|
||||
"task.status.initializing": "جارٍ بدء المهمة...",
|
||||
"thread.divider": "موضوع فرعي",
|
||||
"thread.threadMessageCount": "{{messageCount}} رسالة",
|
||||
"thread.title": "موضوع فرعي",
|
||||
"todoProgress.allCompleted": "تم إكمال جميع المهام",
|
||||
"todoProgress.title": "المهام",
|
||||
"toggleWideScreen.off": "إيقاف وضع الشاشة العريضة",
|
||||
"toggleWideScreen.on": "تشغيل وضع الشاشة العريضة",
|
||||
"tokenDetails.chats": "رسائل الدردشة",
|
||||
"tokenDetails.historySummary": "ملخص السجل",
|
||||
"tokenDetails.chats": "رسائل المحادثة",
|
||||
"tokenDetails.historySummary": "ملخص التاريخ",
|
||||
"tokenDetails.rest": "المتبقي",
|
||||
"tokenDetails.supervisor": "مضيف المجموعة",
|
||||
"tokenDetails.systemRole": "إعدادات الدور",
|
||||
"tokenDetails.title": "تفاصيل السياق",
|
||||
"tokenDetails.tools": "إعدادات المهارة",
|
||||
"tokenDetails.total": "الإجمالي المتاح",
|
||||
"tokenDetails.used": "الإجمالي المستخدم",
|
||||
"tokenDetails.supervisor": "مُنسق المجموعة",
|
||||
"tokenDetails.systemRole": "تعيين الدور",
|
||||
"tokenDetails.title": "تفاصيل الرمز",
|
||||
"tokenDetails.tools": "تعيين الإضافات",
|
||||
"tokenDetails.total": "الإجمالي",
|
||||
"tokenDetails.used": "المستخدم",
|
||||
"tokenTag.overload": "تجاوز الحد",
|
||||
"tokenTag.remained": "المتبقي",
|
||||
"tokenTag.used": "المستخدم",
|
||||
"tool.intervention.approve": "موافقة",
|
||||
"tool.intervention.approveAndRemember": "موافقة وتذكر",
|
||||
"tool.intervention.approveOnce": "الموافقة هذه المرة فقط",
|
||||
"tokenTag.remained": "متبقي",
|
||||
"tokenTag.used": "مستخدم",
|
||||
"tool.intervention.approve": "الموافقة",
|
||||
"tool.intervention.approveAndRemember": "الموافقة والتذكر",
|
||||
"tool.intervention.approveOnce": "الموافقة لمرة واحدة فقط",
|
||||
"tool.intervention.mode.allowList": "قائمة السماح",
|
||||
"tool.intervention.mode.allowListDesc": "تنفيذ الأدوات المعتمدة فقط تلقائيًا",
|
||||
"tool.intervention.mode.autoRun": "موافقة تلقائية",
|
||||
"tool.intervention.mode.autoRunDesc": "الموافقة تلقائيًا على جميع تنفيذات الأدوات",
|
||||
"tool.intervention.mode.autoRun": "الموافقة التلقائية",
|
||||
"tool.intervention.mode.autoRunDesc": "الموافقة تلقائيًا على تنفيذ جميع الأدوات",
|
||||
"tool.intervention.mode.manual": "يدوي",
|
||||
"tool.intervention.mode.manualDesc": "يتطلب الموافقة اليدوية لكل استدعاء",
|
||||
"tool.intervention.mode.manualDesc": "يتطلب الموافقة اليدوية في كل مرة يتم فيها الاستدعاء",
|
||||
"tool.intervention.reject": "رفض",
|
||||
"tool.intervention.rejectAndContinue": "رفض وإعادة المحاولة",
|
||||
"tool.intervention.rejectAndContinue": "رفض ثم إعادة المحاولة",
|
||||
"tool.intervention.rejectOnly": "رفض",
|
||||
"tool.intervention.rejectReasonPlaceholder": "سيساعد السبب الوكيل على فهم حدودك وتحسين التصرفات المستقبلية",
|
||||
"tool.intervention.rejectTitle": "رفض استدعاء المهارة",
|
||||
"tool.intervention.rejectedWithReason": "تم رفض استدعاء المهارة: {{reason}}",
|
||||
"tool.intervention.toolAbort": "لقد ألغيت استدعاء المهارة",
|
||||
"tool.intervention.toolRejected": "تم رفض استدعاء المهارة",
|
||||
"tool.intervention.rejectReasonPlaceholder": "إدخال سبب الرفض سيساعد الوكيل على الفهم وتحسين الإجراءات المستقبلية",
|
||||
"tool.intervention.rejectTitle": "رفض استدعاء الأداة هذه المرة",
|
||||
"tool.intervention.rejectedWithReason": "تم رفض استدعاء الأداة هذه المرة بشكل يدوي: {{reason}}",
|
||||
"tool.intervention.toolAbort": "تم إلغاء استدعاء الأداة من قبل المستخدم",
|
||||
"tool.intervention.toolRejected": "تم رفض استدعاء الأداة هذه المرة بشكل يدوي",
|
||||
"toolAuth.authorize": "تفويض",
|
||||
"toolAuth.authorizing": "جارٍ التفويض...",
|
||||
"toolAuth.hint": "بدون التفويض أو الإعداد، قد لا تعمل المهارات. قد يؤدي ذلك إلى تقييد الوكيل أو حدوث أخطاء.",
|
||||
"toolAuth.hint": "إذا لم يتم التفويض أو التكوين، فقد لا تعمل هذه الأدوات بشكل صحيح، مما قد يؤدي إلى فقدان وظائف المساعد أو ظهور أخطاء.",
|
||||
"toolAuth.signIn": "تسجيل الدخول",
|
||||
"toolAuth.title": "تفويض المهارات لهذا الوكيل",
|
||||
"topic.checkOpenNewTopic": "هل تريد بدء موضوع جديد؟",
|
||||
"topic.checkSaveCurrentMessages": "هل تريد حفظ المحادثة الحالية كموضوع؟",
|
||||
"toolAuth.title": "يرجى إكمال تفويض الأدوات للمساعد",
|
||||
"topic.checkOpenNewTopic": "هل ترغب في فتح موضوع جديد؟",
|
||||
"topic.checkSaveCurrentMessages": "هل ترغب في حفظ الدردشة الحالية كموضوع؟",
|
||||
"topic.openNewTopic": "فتح موضوع جديد",
|
||||
"topic.recent": "المواضيع الأخيرة",
|
||||
"topic.saveCurrentMessages": "حفظ الجلسة الحالية كموضوع",
|
||||
"translate.action": "ترجمة",
|
||||
"translate.clear": "مسح الترجمة",
|
||||
"tts.action": "تحويل النص إلى كلام",
|
||||
"tts.action": "قراءة صوتية",
|
||||
"tts.clear": "مسح الصوت",
|
||||
"untitledAgent": "وكيل بدون اسم",
|
||||
"untitledGroup": "مجموعة بدون اسم",
|
||||
"updateAgent": "تحديث معلومات الوكيل",
|
||||
"untitledAgent": "مساعد بدون اسم",
|
||||
"untitledGroup": "مجموعة بدون عنوان",
|
||||
"updateAgent": "تحديث معلومات المساعد",
|
||||
"upload.action.fileUpload": "رفع ملف",
|
||||
"upload.action.folderUpload": "رفع مجلد",
|
||||
"upload.action.imageDisabled": "النموذج الحالي لا يدعم التعرف البصري. يرجى التبديل إلى نموذج آخر لاستخدام هذه الميزة.",
|
||||
"upload.action.imageDisabled": "النموذج الحالي لا يدعم التعرف على الصور، يرجى تغيير النموذج لاستخدامه",
|
||||
"upload.action.imageUpload": "رفع صورة",
|
||||
"upload.action.tooltip": "رفع",
|
||||
"upload.clientMode.actionFiletip": "رفع ملف",
|
||||
"upload.clientMode.actionTooltip": "رفع",
|
||||
"upload.clientMode.disabled": "النموذج الحالي لا يدعم التعرف البصري وتحليل الملفات. يرجى التبديل إلى نموذج آخر لاستخدام هذه الميزة.",
|
||||
"upload.clientMode.fileNotSupported": "رفع الملفات غير مدعوم في وضع المتصفح؛ يُسمح فقط بالصور.",
|
||||
"upload.clientMode.visionNotSupported": "النموذج الحالي لا يدعم التعرف البصري. يرجى التبديل إلى نموذج مختلف لاستخدام هذه الميزة.",
|
||||
"upload.preview.prepareTasks": "جارٍ تجهيز الأجزاء...",
|
||||
"upload.preview.status.pending": "جارٍ التحضير للرفع...",
|
||||
"upload.preview.status.processing": "جارٍ معالجة الملف...",
|
||||
"upload.validation.videoSizeExceeded": "يجب ألا يتجاوز حجم ملف الفيديو 20 ميغابايت. الحجم الحالي هو {{actualSize}}.",
|
||||
"viewMode.fullWidth": "العرض الكامل",
|
||||
"viewMode.normal": "قياسي",
|
||||
"upload.clientMode.disabled": "النموذج الحالي لا يدعم التعرف على الصور وتحليل الملفات، يرجى تغيير النموذج لاستخدامه",
|
||||
"upload.clientMode.fileNotSupported": "وضع المتصفح لا يدعم تحميل الملفات حاليًا، يدعم الصور فقط",
|
||||
"upload.clientMode.visionNotSupported": "النموذج الحالي لا يدعم التعرف البصري، يرجى تبديل النموذج لاستخدام هذه الميزة",
|
||||
"upload.preview.prepareTasks": "تحضير الأجزاء...",
|
||||
"upload.preview.status.pending": "يتم التحضير للتحميل...",
|
||||
"upload.preview.status.processing": "يتم معالجة الملف...",
|
||||
"upload.validation.videoSizeExceeded": "لا يمكن أن يتجاوز حجم ملف الفيديو 20 ميغابايت، حجم الملف الحالي هو {{actualSize}}",
|
||||
"viewMode.normal": "عادي",
|
||||
"viewMode.wideScreen": "شاشة عريضة",
|
||||
"you": "أنت",
|
||||
"zenMode": "وضع التركيز"
|
||||
|
||||
+272
-272
@@ -1,40 +1,40 @@
|
||||
{
|
||||
"backButton": "رجوع",
|
||||
"backButton": "الرجوع",
|
||||
"badge__default": "افتراضي",
|
||||
"badge__otherImpersonatorDevice": "جهاز انتحال آخر",
|
||||
"badge__primary": "رئيسي",
|
||||
"badge__otherImpersonatorDevice": "جهاز تمثيل آخر",
|
||||
"badge__primary": "أساسي",
|
||||
"badge__requiresAction": "يتطلب إجراء",
|
||||
"badge__thisDevice": "هذا الجهاز",
|
||||
"badge__unverified": "غير مُحقق",
|
||||
"badge__unverified": "غير موثق",
|
||||
"badge__userDevice": "جهاز المستخدم",
|
||||
"badge__you": "أنت",
|
||||
"createOrganization.formButtonSubmit": "إنشاء منظمة",
|
||||
"createOrganization.invitePage.formButtonReset": "تخطي",
|
||||
"createOrganization.title": "إنشاء منظمة",
|
||||
"dates.lastDay": "أمس في {{ date | timeString('ar') }}",
|
||||
"dates.next6Days": "{{ date | weekday('ar','long') }} في {{ date | timeString('ar') }}",
|
||||
"dates.nextDay": "غدًا في {{ date | timeString('ar') }}",
|
||||
"dates.numeric": "{{ date | numeric('ar') }}",
|
||||
"dates.previous6Days": "{{ date | weekday('ar','long') }} الماضي في {{ date | timeString('ar') }}",
|
||||
"dates.sameDay": "اليوم في {{ date | timeString('ar') }}",
|
||||
"dates.lastDay": "أمس في {{ date | timeString('en-US') }}",
|
||||
"dates.next6Days": "{{ date | weekday('en-US','long') }} في {{ date | timeString('en-US') }}",
|
||||
"dates.nextDay": "غدًا في {{ date | timeString('en-US') }}",
|
||||
"dates.numeric": "{{ date | numeric('en-US') }}",
|
||||
"dates.previous6Days": "الماضي {{ date | weekday('en-US','long') }} في {{ date | timeString('en-US') }}",
|
||||
"dates.sameDay": "اليوم في {{ date | timeString('en-US') }}",
|
||||
"dividerText": "أو",
|
||||
"footerActionLink__useAnotherMethod": "استخدم طريقة أخرى",
|
||||
"footerPageLink__help": "مساعدة",
|
||||
"footerActionLink__useAnotherMethod": "استخدام طريقة أخرى",
|
||||
"footerPageLink__help": "المساعدة",
|
||||
"footerPageLink__privacy": "الخصوصية",
|
||||
"footerPageLink__terms": "الشروط",
|
||||
"footerPageLink__terms": "البنود",
|
||||
"formButtonPrimary": "متابعة",
|
||||
"formButtonPrimary__verify": "تحقق",
|
||||
"formButtonPrimary__verify": "التحقق",
|
||||
"formFieldAction__forgotPassword": "هل نسيت كلمة المرور؟",
|
||||
"formFieldError__matchingPasswords": "كلمات المرور متطابقة.",
|
||||
"formFieldError__matchingPasswords": "تتطابق كلمات المرور.",
|
||||
"formFieldError__notMatchingPasswords": "كلمات المرور غير متطابقة.",
|
||||
"formFieldError__verificationLinkExpired": "انتهت صلاحية رابط التحقق. يرجى طلب رابط جديد.",
|
||||
"formFieldHintText__optional": "اختياري",
|
||||
"formFieldHintText__slug": "المُعرف هو اسم قابل للقراءة يجب أن يكون فريدًا. غالبًا ما يُستخدم في عناوين الروابط.",
|
||||
"formFieldHintText__slug": "الـ Slug هو معرف يمكن قراءته بواسطة الإنسان ويجب أن يكون فريدًا. غالبًا ما يُستخدم في عناوين URL.",
|
||||
"formFieldInputPlaceholder__backupCode": "",
|
||||
"formFieldInputPlaceholder__confirmDeletionUserAccount": "حذف الحساب",
|
||||
"formFieldInputPlaceholder__emailAddress": "",
|
||||
"formFieldInputPlaceholder__emailAddress_username": "",
|
||||
"formFieldInputPlaceholder__emailAddresses": "example@email.com، example2@email.com",
|
||||
"formFieldInputPlaceholder__emailAddresses": "example@email.com, example2@email.com",
|
||||
"formFieldInputPlaceholder__firstName": "",
|
||||
"formFieldInputPlaceholder__lastName": "",
|
||||
"formFieldInputPlaceholder__organizationDomain": "",
|
||||
@@ -45,373 +45,373 @@
|
||||
"formFieldInputPlaceholder__phoneNumber": "",
|
||||
"formFieldInputPlaceholder__username": "",
|
||||
"formFieldLabel__automaticInvitations": "تمكين الدعوات التلقائية لهذا النطاق",
|
||||
"formFieldLabel__backupCode": "رمز احتياطي",
|
||||
"formFieldLabel__backupCode": "رمز النسخ الاحتياطي",
|
||||
"formFieldLabel__confirmDeletion": "تأكيد",
|
||||
"formFieldLabel__confirmPassword": "تأكيد كلمة المرور",
|
||||
"formFieldLabel__currentPassword": "كلمة المرور الحالية",
|
||||
"formFieldLabel__emailAddress": "عنوان البريد الإلكتروني",
|
||||
"formFieldLabel__emailAddress_username": "البريد الإلكتروني أو اسم المستخدم",
|
||||
"formFieldLabel__emailAddress_username": "عنوان البريد الإلكتروني أو اسم المستخدم",
|
||||
"formFieldLabel__emailAddresses": "عناوين البريد الإلكتروني",
|
||||
"formFieldLabel__firstName": "الاسم الأول",
|
||||
"formFieldLabel__lastName": "اسم العائلة",
|
||||
"formFieldLabel__lastName": "الاسم الأخير",
|
||||
"formFieldLabel__newPassword": "كلمة مرور جديدة",
|
||||
"formFieldLabel__organizationDomain": "النطاق",
|
||||
"formFieldLabel__organizationDomain": "نطاق",
|
||||
"formFieldLabel__organizationDomainDeletePending": "حذف الدعوات والاقتراحات المعلقة",
|
||||
"formFieldLabel__organizationDomainEmailAddress": "عنوان البريد الإلكتروني للتحقق",
|
||||
"formFieldLabel__organizationDomainEmailAddressDescription": "أدخل عنوان بريد إلكتروني ضمن هذا النطاق لتلقي رمز والتحقق من النطاق.",
|
||||
"formFieldLabel__organizationDomainEmailAddressDescription": "أدخل عنوان بريد إلكتروني تحت هذا النطاق لتلقي رمز والتحقق من هذا النطاق.",
|
||||
"formFieldLabel__organizationName": "الاسم",
|
||||
"formFieldLabel__organizationSlug": "المُعرف",
|
||||
"formFieldLabel__passkeyName": "اسم مفتاح المرور",
|
||||
"formFieldLabel__organizationSlug": "Slug",
|
||||
"formFieldLabel__passkeyName": "اسم مفتاح الوصول",
|
||||
"formFieldLabel__password": "كلمة المرور",
|
||||
"formFieldLabel__phoneNumber": "رقم الهاتف",
|
||||
"formFieldLabel__role": "الدور",
|
||||
"formFieldLabel__signOutOfOtherSessions": "تسجيل الخروج من جميع الأجهزة الأخرى",
|
||||
"formFieldLabel__username": "اسم المستخدم",
|
||||
"impersonationFab.action__signOut": "تسجيل الخروج",
|
||||
"impersonationFab.title": "تم تسجيل الدخول كـ {{identifier}}",
|
||||
"impersonationFab.title": "تم تسجيل الدخول بواسطة {{identifier}}",
|
||||
"locale": "ar",
|
||||
"maintenanceMode": "نقوم حاليًا بأعمال صيانة، لا تقلق، لن تستغرق أكثر من بضع دقائق.",
|
||||
"maintenanceMode": "نحن حاليًا في وضع الصيانة، ولكن لا تقلق، لن يستغرق الأمر أكثر من بضع دقائق.",
|
||||
"membershipRole__admin": "مسؤول",
|
||||
"membershipRole__basicMember": "عضو",
|
||||
"membershipRole__guestMember": "زائر",
|
||||
"membershipRole__guestMember": "ضيف",
|
||||
"organizationList.action__createOrganization": "إنشاء منظمة",
|
||||
"organizationList.action__invitationAccept": "انضمام",
|
||||
"organizationList.action__invitationAccept": "الانضمام",
|
||||
"organizationList.action__suggestionsAccept": "طلب الانضمام",
|
||||
"organizationList.createOrganization": "إنشاء منظمة",
|
||||
"organizationList.invitationAcceptedLabel": "تم الانضمام",
|
||||
"organizationList.subtitle": "للمتابعة إلى {{applicationName}}",
|
||||
"organizationList.suggestionsAcceptedLabel": "بانتظار الموافقة",
|
||||
"organizationList.invitationAcceptedLabel": "انضمام",
|
||||
"organizationList.subtitle": "لمتابعة {{applicationName}}",
|
||||
"organizationList.suggestionsAcceptedLabel": "في انتظار الموافقة",
|
||||
"organizationList.title": "اختر حسابًا",
|
||||
"organizationList.titleWithoutPersonal": "اختر منظمة",
|
||||
"organizationProfile.badge__automaticInvitation": "دعوات تلقائية",
|
||||
"organizationProfile.badge__automaticSuggestion": "اقتراحات تلقائية",
|
||||
"organizationProfile.badge__manualInvitation": "لا يوجد تسجيل تلقائي",
|
||||
"organizationProfile.badge__unverified": "غير مُحقق",
|
||||
"organizationProfile.createDomainPage.subtitle": "أضف النطاق للتحقق. يمكن للمستخدمين الذين لديهم بريد إلكتروني ضمن هذا النطاق الانضمام تلقائيًا أو طلب الانضمام.",
|
||||
"organizationProfile.createDomainPage.title": "إضافة نطاق",
|
||||
"organizationProfile.invitePage.detailsTitle__inviteFailed": "تعذر إرسال الدعوات. هناك دعوات معلقة بالفعل لعناوين البريد التالية: {{email_addresses}}.",
|
||||
"organizationProfile.badge__manualInvitation": "لا تسجيل تلقائي",
|
||||
"organizationProfile.badge__unverified": "غير موثق",
|
||||
"organizationProfile.createDomainPage.subtitle": "أضف النطاق للتحقق. يمكن للمستخدمين الذين لديهم عناوين بريد إلكتروني في هذا النطاق الانضمام إلى المنظمة تلقائيًا أو طلب الانضمام.",
|
||||
"organizationProfile.createDomainPage.title": "إضافة النطاق",
|
||||
"organizationProfile.invitePage.detailsTitle__inviteFailed": "تعذر إرسال الدعوات. هناك دعوات معلقة بالفعل لعناوين البريد الإلكتروني التالية: {{email_addresses}}.",
|
||||
"organizationProfile.invitePage.formButtonPrimary__continue": "إرسال الدعوات",
|
||||
"organizationProfile.invitePage.selectDropdown__role": "اختر الدور",
|
||||
"organizationProfile.invitePage.subtitle": "أدخل أو الصق عنوانًا أو أكثر من عناوين البريد الإلكتروني، مفصولة بمسافات أو فواصل.",
|
||||
"organizationProfile.invitePage.subtitle": "أدخل أو الصق عناوين بريد إلكتروني واحدة أو أكثر، مفصولة بمسافات أو فواصل.",
|
||||
"organizationProfile.invitePage.successMessage": "تم إرسال الدعوات بنجاح",
|
||||
"organizationProfile.invitePage.title": "دعوة أعضاء جدد",
|
||||
"organizationProfile.membersPage.action__invite": "دعوة",
|
||||
"organizationProfile.membersPage.activeMembersTab.menuAction__remove": "إزالة العضو",
|
||||
"organizationProfile.membersPage.activeMembersTab.tableHeader__actions": "",
|
||||
"organizationProfile.membersPage.activeMembersTab.tableHeader__joined": "تاريخ الانضمام",
|
||||
"organizationProfile.membersPage.activeMembersTab.tableHeader__joined": "انضم",
|
||||
"organizationProfile.membersPage.activeMembersTab.tableHeader__role": "الدور",
|
||||
"organizationProfile.membersPage.activeMembersTab.tableHeader__user": "المستخدم",
|
||||
"organizationProfile.membersPage.detailsTitle__emptyRow": "لا يوجد أعضاء لعرضهم",
|
||||
"organizationProfile.membersPage.invitationsTab.autoInvitations.headerSubtitle": "ادعُ المستخدمين من خلال ربط نطاق بريد إلكتروني بمنظمتك. سيتمكن أي شخص يسجل بعنوان بريد مطابق من الانضمام في أي وقت.",
|
||||
"organizationProfile.membersPage.invitationsTab.autoInvitations.headerSubtitle": "قم بدعوة المستخدمين عن طريق ربط نطاق البريد الإلكتروني بالمنظمة. سيتمكن أي شخص يسجل الدخول بنطاق بريد إلكتروني متطابق من الانضمام إلى المنظمة في أي وقت.",
|
||||
"organizationProfile.membersPage.invitationsTab.autoInvitations.headerTitle": "دعوات تلقائية",
|
||||
"organizationProfile.membersPage.invitationsTab.autoInvitations.primaryButton": "إدارة النطاقات المُحققة",
|
||||
"organizationProfile.membersPage.invitationsTab.autoInvitations.primaryButton": "إدارة النطاقات الموثقة",
|
||||
"organizationProfile.membersPage.invitationsTab.table__emptyRow": "لا توجد دعوات لعرضها",
|
||||
"organizationProfile.membersPage.invitedMembersTab.menuAction__revoke": "إلغاء الدعوة",
|
||||
"organizationProfile.membersPage.invitedMembersTab.tableHeader__invited": "تاريخ الدعوة",
|
||||
"organizationProfile.membersPage.requestsTab.autoSuggestions.headerSubtitle": "المستخدمون الذين يسجلون بعنوان بريد إلكتروني مطابق، سيتمكنون من رؤية اقتراح لطلب الانضمام إلى منظمتك.",
|
||||
"organizationProfile.membersPage.invitedMembersTab.tableHeader__invited": "تمت الدعوة",
|
||||
"organizationProfile.membersPage.requestsTab.autoSuggestions.headerSubtitle": "المستخدمون الذين يسجلون الدخول بنطاق بريد إلكتروني متطابق، سيتمكنون من رؤية اقتراح لطلب الانضمام إلى منظمتك.",
|
||||
"organizationProfile.membersPage.requestsTab.autoSuggestions.headerTitle": "اقتراحات تلقائية",
|
||||
"organizationProfile.membersPage.requestsTab.autoSuggestions.primaryButton": "إدارة النطاقات المُحققة",
|
||||
"organizationProfile.membersPage.requestsTab.menuAction__approve": "موافقة",
|
||||
"organizationProfile.membersPage.requestsTab.autoSuggestions.primaryButton": "إدارة النطاقات الموثقة",
|
||||
"organizationProfile.membersPage.requestsTab.menuAction__approve": "الموافقة",
|
||||
"organizationProfile.membersPage.requestsTab.menuAction__reject": "رفض",
|
||||
"organizationProfile.membersPage.requestsTab.tableHeader__requested": "طلب الوصول",
|
||||
"organizationProfile.membersPage.requestsTab.table__emptyRow": "لا توجد طلبات لعرضها",
|
||||
"organizationProfile.membersPage.start.headerTitle__invitations": "الدعوات",
|
||||
"organizationProfile.membersPage.start.headerTitle__members": "الأعضاء",
|
||||
"organizationProfile.membersPage.start.headerTitle__requests": "الطلبات",
|
||||
"organizationProfile.membersPage.start.headerTitle__invitations": "دعوات",
|
||||
"organizationProfile.membersPage.start.headerTitle__members": "أعضاء",
|
||||
"organizationProfile.membersPage.start.headerTitle__requests": "طلبات",
|
||||
"organizationProfile.navbar.description": "إدارة منظمتك.",
|
||||
"organizationProfile.navbar.general": "عام",
|
||||
"organizationProfile.navbar.members": "الأعضاء",
|
||||
"organizationProfile.navbar.members": "أعضاء",
|
||||
"organizationProfile.navbar.title": "المنظمة",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.actionDescription": "اكتب \"{{organizationName}}\" أدناه للمتابعة.",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.messageLine1": "هل أنت متأكد أنك تريد حذف هذه المؤسسة؟",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.messageLine1": "هل أنت متأكد أنك تريد حذف هذه المنظمة؟",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.messageLine2": "هذا الإجراء دائم ولا يمكن التراجع عنه.",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.successMessage": "تم حذف المؤسسة.",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.title": "حذف المؤسسة",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.successMessage": "لقد حذفت المنظمة.",
|
||||
"organizationProfile.profilePage.dangerSection.deleteOrganization.title": "حذف المنظمة",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.actionDescription": "اكتب \"{{organizationName}}\" أدناه للمتابعة.",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.messageLine1": "هل أنت متأكد أنك تريد مغادرة هذه المؤسسة؟ ستفقد الوصول إلى هذه المؤسسة وتطبيقاتها.",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.messageLine1": "هل أنت متأكد أنك تريد مغادرة هذه المنظمة؟ ستفقد الوصول إلى هذه المنظمة وتطبيقاتها.",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.messageLine2": "هذا الإجراء دائم ولا يمكن التراجع عنه.",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.successMessage": "لقد غادرت المؤسسة.",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.title": "مغادرة المؤسسة",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.successMessage": "لقد غادرت المنظمة.",
|
||||
"organizationProfile.profilePage.dangerSection.leaveOrganization.title": "مغادرة المنظمة",
|
||||
"organizationProfile.profilePage.dangerSection.title": "خطر",
|
||||
"organizationProfile.profilePage.domainSection.menuAction__manage": "إدارة",
|
||||
"organizationProfile.profilePage.domainSection.menuAction__remove": "حذف",
|
||||
"organizationProfile.profilePage.domainSection.menuAction__verify": "تحقق",
|
||||
"organizationProfile.profilePage.domainSection.primaryButton": "إضافة نطاق",
|
||||
"organizationProfile.profilePage.domainSection.subtitle": "اسمح للمستخدمين بالانضمام تلقائيًا إلى المؤسسة أو طلب الانضمام بناءً على نطاق بريد إلكتروني تم التحقق منه.",
|
||||
"organizationProfile.profilePage.domainSection.title": "النطاقات التي تم التحقق منها",
|
||||
"organizationProfile.profilePage.successMessage": "تم تحديث المؤسسة.",
|
||||
"organizationProfile.profilePage.domainSection.menuAction__verify": "التحقق",
|
||||
"organizationProfile.profilePage.domainSection.primaryButton": "إضافة النطاق",
|
||||
"organizationProfile.profilePage.domainSection.subtitle": "اسمح للمستخدمين بالانضمام إلى المنظمة تلقائيًا أو طلب الانضمام بناءً على نطاق بريد إلكتروني موثق.",
|
||||
"organizationProfile.profilePage.domainSection.title": "النطاقات الموثقة",
|
||||
"organizationProfile.profilePage.successMessage": "تم تحديث المنظمة.",
|
||||
"organizationProfile.profilePage.title": "تحديث الملف الشخصي",
|
||||
"organizationProfile.removeDomainPage.messageLine1": "سيتم إزالة نطاق البريد الإلكتروني {{domain}}.",
|
||||
"organizationProfile.removeDomainPage.messageLine2": "لن يتمكن المستخدمون من الانضمام تلقائيًا إلى المؤسسة بعد ذلك.",
|
||||
"organizationProfile.removeDomainPage.messageLine2": "لن يتمكن المستخدمون من الانضمام إلى المنظمة تلقائيًا بعد ذلك.",
|
||||
"organizationProfile.removeDomainPage.successMessage": "تمت إزالة {{domain}}.",
|
||||
"organizationProfile.removeDomainPage.title": "إزالة النطاق",
|
||||
"organizationProfile.start.headerTitle__general": "عام",
|
||||
"organizationProfile.start.headerTitle__members": "الأعضاء",
|
||||
"organizationProfile.start.headerTitle__members": "أعضاء",
|
||||
"organizationProfile.start.profileSection.primaryButton": "تحديث الملف الشخصي",
|
||||
"organizationProfile.start.profileSection.title": "ملف المؤسسة",
|
||||
"organizationProfile.start.profileSection.uploadAction__title": "الشعار",
|
||||
"organizationProfile.verifiedDomainPage.dangerTab.calloutInfoLabel": "إزالة هذا النطاق سيؤثر على المستخدمين المدعوين.",
|
||||
"organizationProfile.start.profileSection.title": "ملف المنظمة",
|
||||
"organizationProfile.start.profileSection.uploadAction__title": "شعار",
|
||||
"organizationProfile.verifiedDomainPage.dangerTab.calloutInfoLabel": "سيؤثر إزالة هذا النطاق على المستخدمين المدعوين.",
|
||||
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainActionLabel__remove": "إزالة النطاق",
|
||||
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainSubtitle": "إزالة هذا النطاق من قائمة النطاقات التي تم التحقق منها",
|
||||
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainSubtitle": "قم بإزالة هذا النطاق من نطاقاتك الموثقة",
|
||||
"organizationProfile.verifiedDomainPage.dangerTab.removeDomainTitle": "إزالة النطاق",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticInvitationOption__description": "يتم دعوة المستخدمين تلقائيًا للانضمام إلى المؤسسة عند التسجيل ويمكنهم الانضمام في أي وقت.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticInvitationOption__description": "يتم دعوة المستخدمين تلقائيًا للانضمام إلى المنظمة عند تسجيلهم، ويمكنهم الانضمام في أي وقت.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticInvitationOption__label": "دعوات تلقائية",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticSuggestionOption__description": "يتلقى المستخدمون اقتراحًا بطلب الانضمام، ولكن يجب الموافقة عليهم من قبل مسؤول قبل الانضمام.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticSuggestionOption__description": "يتلقى المستخدمون اقتراحًا لطلب الانضمام، ولكن يجب أن يتمتعوا بموافقة من مسؤول قبل الانضمام إلى المنظمة.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.automaticSuggestionOption__label": "اقتراحات تلقائية",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInfoLabel": "سيؤثر تغيير وضع التسجيل على المستخدمين الجدد فقط.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInvitationCountLabel": "الدعوات المعلقة المرسلة إلى المستخدمين: {{count}}",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutSuggestionCountLabel": "الاقتراحات المعلقة المرسلة إلى المستخدمين: {{count}}",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__description": "يمكن دعوة المستخدمين يدويًا فقط للانضمام إلى المؤسسة.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__label": "لا يوجد تسجيل تلقائي",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.subtitle": "اختر كيفية انضمام المستخدمين من هذا النطاق إلى المؤسسة.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInfoLabel": "تؤثر تغيير وضع التسجيل فقط على المستخدمين الجدد.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutInvitationCountLabel": "الدعوات المعلقة المرسلة للمستخدمين: {{count}}",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.calloutSuggestionCountLabel": "الاقتراحات المعلقة المرسلة للمستخدمين: {{count}}",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__description": "يمكن فقط دعوة المستخدمين يدويًا إلى المنظمة.",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.manualInvitationOption__label": "لا تسجيل تلقائي",
|
||||
"organizationProfile.verifiedDomainPage.enrollmentTab.subtitle": "اختر كيف يمكن للمستخدمين من هذا النطاق الانضمام إلى المنظمة.",
|
||||
"organizationProfile.verifiedDomainPage.start.headerTitle__danger": "خطر",
|
||||
"organizationProfile.verifiedDomainPage.start.headerTitle__enrollment": "خيارات التسجيل",
|
||||
"organizationProfile.verifiedDomainPage.subtitle": "تم التحقق من النطاق {{domain}}. تابع باختيار وضع التسجيل.",
|
||||
"organizationProfile.verifiedDomainPage.subtitle": "تم التحقق الآن من النطاق {{domain}}. تابع باختيار وضع التسجيل.",
|
||||
"organizationProfile.verifiedDomainPage.title": "تحديث {{domain}}",
|
||||
"organizationProfile.verifyDomainPage.formSubtitle": "أدخل رمز التحقق المرسل إلى عنوان بريدك الإلكتروني",
|
||||
"organizationProfile.verifyDomainPage.formTitle": "رمز التحقق",
|
||||
"organizationProfile.verifyDomainPage.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
|
||||
"organizationProfile.verifyDomainPage.resendButton": "لم تتلقى الرمز؟ إعادة الإرسال",
|
||||
"organizationProfile.verifyDomainPage.subtitle": "يجب التحقق من النطاق {{domainName}} عبر البريد الإلكتروني.",
|
||||
"organizationProfile.verifyDomainPage.subtitleVerificationCodeScreen": "تم إرسال رمز التحقق إلى {{emailAddress}}. أدخل الرمز للمتابعة.",
|
||||
"organizationProfile.verifyDomainPage.title": "التحقق من النطاق",
|
||||
"organizationSwitcher.action__createOrganization": "إنشاء مؤسسة",
|
||||
"organizationSwitcher.action__invitationAccept": "انضمام",
|
||||
"organizationSwitcher.action__createOrganization": "إنشاء منظمة",
|
||||
"organizationSwitcher.action__invitationAccept": "الانضمام",
|
||||
"organizationSwitcher.action__manageOrganization": "إدارة",
|
||||
"organizationSwitcher.action__suggestionsAccept": "طلب الانضمام",
|
||||
"organizationSwitcher.notSelected": "لم يتم اختيار مؤسسة",
|
||||
"organizationSwitcher.notSelected": "لم يتم تحديد أي منظمة",
|
||||
"organizationSwitcher.personalWorkspace": "الحساب الشخصي",
|
||||
"organizationSwitcher.suggestionsAcceptedLabel": "بانتظار الموافقة",
|
||||
"organizationSwitcher.suggestionsAcceptedLabel": "في انتظار الموافقة",
|
||||
"paginationButton__next": "التالي",
|
||||
"paginationButton__previous": "السابق",
|
||||
"paginationRowText__displaying": "عرض",
|
||||
"paginationRowText__of": "من",
|
||||
"signIn.accountSwitcher.action__addAccount": "إضافة حساب",
|
||||
"signIn.accountSwitcher.action__signOutAll": "تسجيل الخروج من جميع الحسابات",
|
||||
"signIn.accountSwitcher.subtitle": "اختر الحساب الذي ترغب في المتابعة به.",
|
||||
"signIn.accountSwitcher.subtitle": "اختر الحساب الذي ترغب في الاستمرار به.",
|
||||
"signIn.accountSwitcher.title": "اختر حسابًا",
|
||||
"signIn.alternativeMethods.actionLink": "الحصول على المساعدة",
|
||||
"signIn.alternativeMethods.actionText": "لا تملك أياً من هذه؟",
|
||||
"signIn.alternativeMethods.blockButton__backupCode": "استخدم رمز النسخ الاحتياطي",
|
||||
"signIn.alternativeMethods.blockButton__emailCode": "أرسل رمزًا إلى البريد الإلكتروني {{identifier}}",
|
||||
"signIn.alternativeMethods.blockButton__emailLink": "أرسل رابطًا إلى البريد الإلكتروني {{identifier}}",
|
||||
"signIn.alternativeMethods.blockButton__passkey": "تسجيل الدخول باستخدام مفتاح المرور",
|
||||
"signIn.alternativeMethods.blockButton__password": "تسجيل الدخول باستخدام كلمة المرور",
|
||||
"signIn.alternativeMethods.blockButton__phoneCode": "أرسل رمزًا عبر الرسائل القصيرة إلى {{identifier}}",
|
||||
"signIn.alternativeMethods.blockButton__totp": "استخدم تطبيق المصادقة",
|
||||
"signIn.alternativeMethods.actionLink": "احصل على مساعدة",
|
||||
"signIn.alternativeMethods.actionText": "ليس لديك أحد هذه؟",
|
||||
"signIn.alternativeMethods.blockButton__backupCode": "استخدام رمز الاحتياطي",
|
||||
"signIn.alternativeMethods.blockButton__emailCode": "إرسال رمز بريد إلكتروني إلى {{identifier}}",
|
||||
"signIn.alternativeMethods.blockButton__emailLink": "إرسال رابط بريد إلكتروني إلى {{identifier}}",
|
||||
"signIn.alternativeMethods.blockButton__passkey": "تسجيل الدخول برمز الدخول",
|
||||
"signIn.alternativeMethods.blockButton__password": "تسجيل الدخول بكلمة المرور",
|
||||
"signIn.alternativeMethods.blockButton__phoneCode": "إرسال رمز SMS إلى {{identifier}}",
|
||||
"signIn.alternativeMethods.blockButton__totp": "استخدام تطبيق الموثق الخاص بك",
|
||||
"signIn.alternativeMethods.getHelp.blockButton__emailSupport": "الدعم عبر البريد الإلكتروني",
|
||||
"signIn.alternativeMethods.getHelp.content": "إذا كنت تواجه صعوبة في تسجيل الدخول إلى حسابك، راسلنا عبر البريد الإلكتروني وسنعمل على استعادة الوصول في أقرب وقت ممكن.",
|
||||
"signIn.alternativeMethods.getHelp.title": "الحصول على المساعدة",
|
||||
"signIn.alternativeMethods.subtitle": "هل تواجه مشكلة؟ يمكنك استخدام أي من الطرق التالية لتسجيل الدخول.",
|
||||
"signIn.alternativeMethods.getHelp.content": "إذا كنت تواجه صعوبة في تسجيل الدخول إلى حسابك، ارسل لنا بريدًا إلكترونيًا وسنعمل معك لاستعادة الوصول في أقرب وقت ممكن.",
|
||||
"signIn.alternativeMethods.getHelp.title": "احصل على مساعدة",
|
||||
"signIn.alternativeMethods.subtitle": "هل تواجه مشاكل؟ يمكنك استخدام أي من هذه الطرق لتسجيل الدخول.",
|
||||
"signIn.alternativeMethods.title": "استخدم طريقة أخرى",
|
||||
"signIn.backupCodeMfa.subtitle": "رمز النسخ الاحتياطي هو الرمز الذي حصلت عليه عند إعداد المصادقة الثنائية.",
|
||||
"signIn.backupCodeMfa.title": "أدخل رمز النسخ الاحتياطي",
|
||||
"signIn.backupCodeMfa.subtitle": "رمز الاحتياطي هو الرمز الذي حصلت عليه عند إعداد المصادقة ثنائية العامل.",
|
||||
"signIn.backupCodeMfa.title": "أدخل رمز الاحتياطي",
|
||||
"signIn.emailCode.formTitle": "رمز التحقق",
|
||||
"signIn.emailCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
|
||||
"signIn.emailCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
|
||||
"signIn.emailCode.subtitle": "للمتابعة إلى {{applicationName}}",
|
||||
"signIn.emailCode.title": "تحقق من بريدك الإلكتروني",
|
||||
"signIn.emailLink.expired.subtitle": "ارجع إلى التبويب الأصلي للمتابعة.",
|
||||
"signIn.emailLink.expired.title": "انتهت صلاحية رابط التحقق",
|
||||
"signIn.emailLink.failed.subtitle": "ارجع إلى التبويب الأصلي للمتابعة.",
|
||||
"signIn.emailLink.failed.title": "رابط التحقق غير صالح",
|
||||
"signIn.emailLink.formSubtitle": "استخدم رابط التحقق المرسل إلى بريدك الإلكتروني",
|
||||
"signIn.emailLink.expired.subtitle": "الرجاء العودة إلى التبويب الأصلي للمتابعة.",
|
||||
"signIn.emailLink.expired.title": "انتهت صلاحية رابط التحقق هذا",
|
||||
"signIn.emailLink.failed.subtitle": "الرجاء العودة إلى التبويب الأصلي للمتابعة.",
|
||||
"signIn.emailLink.failed.title": "رابط التحقق هذا غير صالح",
|
||||
"signIn.emailLink.formSubtitle": "استخدم الرابط المرسل إلى بريدك الإلكتروني للتحقق",
|
||||
"signIn.emailLink.formTitle": "رابط التحقق",
|
||||
"signIn.emailLink.loading.subtitle": "سيتم تحويلك قريبًا",
|
||||
"signIn.emailLink.loading.title": "جارٍ تسجيل الدخول...",
|
||||
"signIn.emailLink.resendButton": "لم تستلم الرابط؟ أعد الإرسال",
|
||||
"signIn.emailLink.loading.subtitle": "سيتم توجيهك قريبًا",
|
||||
"signIn.emailLink.loading.title": "تسجيل الدخول...",
|
||||
"signIn.emailLink.resendButton": "لم تستلم الرابط؟ إعادة الإرسال",
|
||||
"signIn.emailLink.subtitle": "للمتابعة إلى {{applicationName}}",
|
||||
"signIn.emailLink.title": "تحقق من بريدك الإلكتروني",
|
||||
"signIn.emailLink.unusedTab.title": "يمكنك إغلاق هذا التبويب",
|
||||
"signIn.emailLink.verified.subtitle": "سيتم تحويلك قريبًا",
|
||||
"signIn.emailLink.verified.subtitle": "سيتم توجيهك قريبًا",
|
||||
"signIn.emailLink.verified.title": "تم تسجيل الدخول بنجاح",
|
||||
"signIn.emailLink.verifiedSwitchTab.subtitle": "ارجع إلى التبويب الأصلي للمتابعة",
|
||||
"signIn.emailLink.verifiedSwitchTab.subtitleNewTab": "ارجع إلى التبويب الجديد للمتابعة",
|
||||
"signIn.emailLink.verifiedSwitchTab.titleNewTab": "تم تسجيل الدخول في تبويب آخر",
|
||||
"signIn.emailLink.verifiedSwitchTab.subtitle": "الرجوع إلى التبويب الأصلي للمتابعة",
|
||||
"signIn.emailLink.verifiedSwitchTab.subtitleNewTab": "الرجوع إلى التبويب الجديد للمتابعة",
|
||||
"signIn.emailLink.verifiedSwitchTab.titleNewTab": "تم تسجيل الدخول على تبويب آخر",
|
||||
"signIn.forgotPassword.formTitle": "رمز إعادة تعيين كلمة المرور",
|
||||
"signIn.forgotPassword.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
|
||||
"signIn.forgotPassword.subtitle": "لإعادة تعيين كلمة المرور الخاصة بك",
|
||||
"signIn.forgotPassword.subtitle_email": "أدخل أولاً الرمز المرسل إلى بريدك الإلكتروني",
|
||||
"signIn.forgotPassword.subtitle_phone": "أدخل أولاً الرمز المرسل إلى هاتفك",
|
||||
"signIn.forgotPassword.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
|
||||
"signIn.forgotPassword.subtitle": "لإعادة تعيين كلمة المرور",
|
||||
"signIn.forgotPassword.subtitle_email": "أدخل أولًا الرمز المرسل إلى عنوان بريدك الإلكتروني",
|
||||
"signIn.forgotPassword.subtitle_phone": "أدخل أولًا الرمز المرسل إلى هاتفك",
|
||||
"signIn.forgotPassword.title": "إعادة تعيين كلمة المرور",
|
||||
"signIn.forgotPasswordAlternativeMethods.blockButton__resetPassword": "إعادة تعيين كلمة المرور",
|
||||
"signIn.forgotPasswordAlternativeMethods.label__alternativeMethods": "أو، سجل الدخول بطريقة أخرى",
|
||||
"signIn.forgotPasswordAlternativeMethods.title": "هل نسيت كلمة المرور؟",
|
||||
"signIn.noAvailableMethods.message": "لا يمكن المتابعة في تسجيل الدخول. لا توجد وسيلة تحقق متاحة.",
|
||||
"signIn.forgotPasswordAlternativeMethods.label__alternativeMethods": "أو، قم بتسجيل الدخول باستخدام طريقة أخرى",
|
||||
"signIn.forgotPasswordAlternativeMethods.title": "نسيت كلمة المرور؟",
|
||||
"signIn.noAvailableMethods.message": "لا يمكن المتابعة في عملية تسجيل الدخول. لا يوجد عامل مصادقة متاح.",
|
||||
"signIn.noAvailableMethods.subtitle": "حدث خطأ",
|
||||
"signIn.noAvailableMethods.title": "لا يمكن تسجيل الدخول",
|
||||
"signIn.passkey.subtitle": "استخدام مفتاح المرور يؤكد هويتك. قد يطلب منك جهازك بصمة الإصبع أو الوجه أو قفل الشاشة.",
|
||||
"signIn.passkey.title": "استخدم مفتاح المرور",
|
||||
"signIn.password.actionLink": "استخدم طريقة أخرى",
|
||||
"signIn.passkey.subtitle": "استخدام رمز الدخول يؤكد أنك أنت. قد يطلب جهازك بصمة الإصبع أو الوجه أو قفل الشاشة.",
|
||||
"signIn.passkey.title": "استخدام رمز الدخول",
|
||||
"signIn.password.actionLink": "استخدام طريقة أخرى",
|
||||
"signIn.password.subtitle": "أدخل كلمة المرور المرتبطة بحسابك",
|
||||
"signIn.password.title": "أدخل كلمة المرور",
|
||||
"signIn.passwordPwned.title": "تم تسريب كلمة المرور",
|
||||
"signIn.phoneCode.formTitle": "رمز التحقق",
|
||||
"signIn.phoneCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
|
||||
"signIn.phoneCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
|
||||
"signIn.phoneCode.subtitle": "للمتابعة إلى {{applicationName}}",
|
||||
"signIn.phoneCode.title": "تحقق من هاتفك",
|
||||
"signIn.phoneCodeMfa.formTitle": "رمز التحقق",
|
||||
"signIn.phoneCodeMfa.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
|
||||
"signIn.phoneCodeMfa.subtitle": "للمتابعة، أدخل رمز التحقق المرسل إلى هاتفك",
|
||||
"signIn.phoneCodeMfa.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
|
||||
"signIn.phoneCodeMfa.subtitle": "للمتابعة، يرجى إدخال رمز التحقق المرسل إلى هاتفك",
|
||||
"signIn.phoneCodeMfa.title": "تحقق من هاتفك",
|
||||
"signIn.resetPassword.formButtonPrimary": "إعادة تعيين كلمة المرور",
|
||||
"signIn.resetPassword.requiredMessage": "لأسباب أمنية، يجب إعادة تعيين كلمة المرور.",
|
||||
"signIn.resetPassword.successMessage": "تم تغيير كلمة المرور بنجاح. جارٍ تسجيل الدخول، يرجى الانتظار.",
|
||||
"signIn.resetPassword.requiredMessage": "من الضروري إعادة تعيين كلمة المرور لأسباب أمنية.",
|
||||
"signIn.resetPassword.successMessage": "تم تغيير كلمة المرور بنجاح. جارٍ تسجيل الدخول، يرجى الانتظار لحظة.",
|
||||
"signIn.resetPassword.title": "تعيين كلمة مرور جديدة",
|
||||
"signIn.resetPasswordMfa.detailsLabel": "نحتاج إلى التحقق من هويتك قبل إعادة تعيين كلمة المرور.",
|
||||
"signIn.start.actionLink": "إنشاء حساب",
|
||||
"signIn.start.actionLink__use_email": "استخدم البريد الإلكتروني",
|
||||
"signIn.start.actionLink__use_email_username": "استخدم البريد الإلكتروني أو اسم المستخدم",
|
||||
"signIn.start.actionLink__use_passkey": "استخدم مفتاح المرور بدلاً من ذلك",
|
||||
"signIn.start.actionLink__use_phone": "استخدم الهاتف",
|
||||
"signIn.start.actionLink__use_username": "استخدم اسم المستخدم",
|
||||
"signIn.start.actionText": "لا تملك حسابًا؟",
|
||||
"signIn.start.subtitle": "مرحبًا بعودتك! يرجى تسجيل الدخول للمتابعة",
|
||||
"signIn.start.title": "تسجيل الدخول إلى {{applicationName}}",
|
||||
"signIn.start.actionLink": "التسجيل",
|
||||
"signIn.start.actionLink__use_email": "استخدام البريد الإلكتروني",
|
||||
"signIn.start.actionLink__use_email_username": "استخدام البريد الإلكتروني أو اسم المستخدم",
|
||||
"signIn.start.actionLink__use_passkey": "استخدام رمز الدخول بدلاً",
|
||||
"signIn.start.actionLink__use_phone": "استخدام الهاتف",
|
||||
"signIn.start.actionLink__use_username": "استخدام اسم المستخدم",
|
||||
"signIn.start.actionText": "ليس لديك حساب؟",
|
||||
"signIn.start.subtitle": "مرحبًا! يرجى ملء التفاصيل للبدء.",
|
||||
"signIn.start.title": "إنشاء حسابك",
|
||||
"signIn.totpMfa.formTitle": "رمز التحقق",
|
||||
"signIn.totpMfa.subtitle": "للمتابعة، أدخل رمز التحقق الذي تم إنشاؤه بواسطة تطبيق المصادقة",
|
||||
"signIn.totpMfa.title": "التحقق بخطوتين",
|
||||
"signIn.totpMfa.subtitle": "للمتابعة، يرجى إدخال رمز التحقق الذي تم توليده بواسطة تطبيق الموثق الخاص بك",
|
||||
"signIn.totpMfa.title": "التحقق الثنائي الخطوة",
|
||||
"signInEnterPasswordTitle": "أدخل كلمة المرور الخاصة بك",
|
||||
"signUp.continue.actionLink": "تسجيل الدخول",
|
||||
"signUp.continue.actionText": "هل لديك حساب بالفعل؟",
|
||||
"signUp.continue.subtitle": "يرجى إكمال البيانات المتبقية للمتابعة.",
|
||||
"signUp.continue.title": "أكمل الحقول الناقصة",
|
||||
"signUp.emailCode.formSubtitle": "أدخل رمز التحقق المرسل إلى بريدك الإلكتروني",
|
||||
"signUp.continue.subtitle": "يرجى ملء التفاصيل المتبقية للمتابعة.",
|
||||
"signUp.continue.title": "املأ الحقول الناقصة",
|
||||
"signUp.emailCode.formSubtitle": "أدخل رمز التحقق المرسل إلى عنوان بريدك الإلكتروني",
|
||||
"signUp.emailCode.formTitle": "رمز التحقق",
|
||||
"signUp.emailCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
|
||||
"signUp.emailCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
|
||||
"signUp.emailCode.subtitle": "أدخل رمز التحقق المرسل إلى بريدك الإلكتروني",
|
||||
"signUp.emailCode.title": "تحقق من بريدك الإلكتروني",
|
||||
"signUp.emailLink.formSubtitle": "استخدم رابط التحقق المرسل إلى بريدك الإلكتروني",
|
||||
"signUp.emailLink.formSubtitle": "استخدم الرابط المرسل إلى عنوان بريدك الإلكتروني للتحقق",
|
||||
"signUp.emailLink.formTitle": "رابط التحقق",
|
||||
"signUp.emailLink.loading.title": "جارٍ إنشاء الحساب...",
|
||||
"signUp.emailLink.resendButton": "لم تستلم الرابط؟ أعد الإرسال",
|
||||
"signUp.emailLink.loading.title": "جارٍ التسجيل...",
|
||||
"signUp.emailLink.resendButton": "لم تستلم الرابط؟ إعادة الإرسال",
|
||||
"signUp.emailLink.subtitle": "للمتابعة إلى {{applicationName}}",
|
||||
"signUp.emailLink.title": "تحقق من بريدك الإلكتروني",
|
||||
"signUp.emailLink.verified.title": "تم إنشاء الحساب بنجاح",
|
||||
"signUp.emailLink.verifiedSwitchTab.subtitle": "ارجع إلى التبويب الجديد للمتابعة",
|
||||
"signUp.emailLink.verifiedSwitchTab.subtitleNewTab": "ارجع إلى التبويب السابق للمتابعة",
|
||||
"signUp.emailLink.verifiedSwitchTab.title": "تم التحقق من البريد الإلكتروني بنجاح",
|
||||
"signUp.emailLink.verified.title": "تم التسجيل بنجاح",
|
||||
"signUp.emailLink.verifiedSwitchTab.subtitle": "الرجوع إلى التبويب الجديد للمتابعة",
|
||||
"signUp.emailLink.verifiedSwitchTab.subtitleNewTab": "الرجوع إلى التبويب السابق للمتابعة",
|
||||
"signUp.emailLink.verifiedSwitchTab.title": "تم التحقق بنجاح من البريد الإلكتروني",
|
||||
"signUp.phoneCode.formSubtitle": "أدخل رمز التحقق المرسل إلى رقم هاتفك",
|
||||
"signUp.phoneCode.formTitle": "رمز التحقق",
|
||||
"signUp.phoneCode.resendButton": "لم تستلم الرمز؟ أعد الإرسال",
|
||||
"signUp.phoneCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
|
||||
"signUp.phoneCode.subtitle": "أدخل رمز التحقق المرسل إلى هاتفك",
|
||||
"signUp.phoneCode.title": "تحقق من هاتفك",
|
||||
"signUp.start.actionLink": "تسجيل الدخول",
|
||||
"signUp.start.actionText": "هل لديك حساب بالفعل؟",
|
||||
"signUp.start.subtitle": "مرحبًا بك! يرجى تعبئة البيانات للبدء.",
|
||||
"signUp.start.title": "أنشئ حسابك",
|
||||
"socialButtonsBlockButton": "المتابعة باستخدام {{provider|titleize}}",
|
||||
"unstable__errors.captcha_invalid": "فشل التسجيل بسبب عدم اجتياز التحقق الأمني. يرجى تحديث الصفحة والمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
|
||||
"unstable__errors.captcha_unavailable": "فشل التسجيل بسبب عدم اجتياز التحقق من الروبوتات. يرجى تحديث الصفحة والمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
|
||||
"signUp.start.subtitle": "مرحبًا! يرجى ملء التفاصيل للبدء.",
|
||||
"signUp.start.title": "إنشاء حسابك",
|
||||
"socialButtonsBlockButton": "المتابعة مع {{provider|titleize}}",
|
||||
"unstable__errors.captcha_invalid": "فشل تسجيل الدخول بسبب فشل التحقق من الأمان. يرجى تحديث الصفحة للمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
|
||||
"unstable__errors.captcha_unavailable": "فشل تسجيل الدخول بسبب فشل التحقق من الروبوت. يرجى تحديث الصفحة للمحاولة مرة أخرى أو التواصل مع الدعم للمزيد من المساعدة.",
|
||||
"unstable__errors.form_code_incorrect": "",
|
||||
"unstable__errors.form_identifier_exists": "",
|
||||
"unstable__errors.form_identifier_exists__email_address": "عنوان البريد الإلكتروني هذا مستخدم بالفعل. يرجى تجربة عنوان آخر.",
|
||||
"unstable__errors.form_identifier_exists__phone_number": "رقم الهاتف هذا مستخدم بالفعل. يرجى تجربة رقم آخر.",
|
||||
"unstable__errors.form_identifier_exists__username": "اسم المستخدم هذا مستخدم بالفعل. يرجى تجربة اسم آخر.",
|
||||
"unstable__errors.form_identifier_exists__email_address": "هذا البريد الإلكتروني مستخدم. يرجى المحاولة بعنوان آخر.",
|
||||
"unstable__errors.form_identifier_exists__phone_number": "هذا الرقم مستخدم. يرجى المحاولة برقم آخر.",
|
||||
"unstable__errors.form_identifier_exists__username": "اسم المستخدم هذا مستخدم. يرجى المحاولة بآخر.",
|
||||
"unstable__errors.form_identifier_not_found": "",
|
||||
"unstable__errors.form_param_format_invalid": "",
|
||||
"unstable__errors.form_param_format_invalid__email_address": "يجب أن يكون عنوان البريد الإلكتروني صالحًا.",
|
||||
"unstable__errors.form_param_format_invalid__phone_number": "يجب أن يكون رقم الهاتف بصيغة دولية صحيحة.",
|
||||
"unstable__errors.form_param_format_invalid__phone_number": "يجب أن يكون رقم الهاتف بتنسيق دولي صالح.",
|
||||
"unstable__errors.form_param_max_length_exceeded__first_name": "يجب ألا يتجاوز الاسم الأول 256 حرفًا.",
|
||||
"unstable__errors.form_param_max_length_exceeded__last_name": "يجب ألا يتجاوز اسم العائلة 256 حرفًا.",
|
||||
"unstable__errors.form_param_max_length_exceeded__last_name": "يجب ألا يتجاوز الاسم الأخير 256 حرفًا.",
|
||||
"unstable__errors.form_param_max_length_exceeded__name": "يجب ألا يتجاوز الاسم 256 حرفًا.",
|
||||
"unstable__errors.form_param_nil": "",
|
||||
"unstable__errors.form_password_incorrect": "",
|
||||
"unstable__errors.form_password_length_too_short": "",
|
||||
"unstable__errors.form_password_not_strong_enough": "كلمة المرور الخاصة بك غير قوية بما فيه الكفاية.",
|
||||
"unstable__errors.form_password_pwned": "تم العثور على هذه الكلمة المرور ضمن تسريب بيانات ولا يمكن استخدامها. يرجى تجربة كلمة مرور أخرى.",
|
||||
"unstable__errors.form_password_pwned__sign_in": "تم العثور على هذه الكلمة المرور ضمن تسريب بيانات ولا يمكن استخدامها. يرجى إعادة تعيين كلمة المرور.",
|
||||
"unstable__errors.form_password_size_in_bytes_exceeded": "تجاوزت كلمة المرور الحد الأقصى المسموح به من البايتات. يرجى تقصيرها أو إزالة بعض الرموز الخاصة.",
|
||||
"unstable__errors.form_password_pwned": "تم العثور على هذه كلمة المرور كجزء من اختراق ولا يمكن استخدامها، يرجى تجربة كلمة مرور أخرى بدلاً منها.",
|
||||
"unstable__errors.form_password_pwned__sign_in": "تم العثور على هذه كلمة المرور كجزء من اختراق ولا يمكن استخدامها، يرجى إعادة تعيين كلمة المرور الخاصة بك.",
|
||||
"unstable__errors.form_password_size_in_bytes_exceeded": "لقد تجاوزت كلمة المرور الحد الأقصى المسموح به من البايتات، يرجى تقصيرها أو إزالة بعض الرموز الخاصة.",
|
||||
"unstable__errors.form_password_validation_failed": "كلمة المرور غير صحيحة",
|
||||
"unstable__errors.form_username_invalid_character": "",
|
||||
"unstable__errors.form_username_invalid_length": "",
|
||||
"unstable__errors.identification_deletion_failed": "لا يمكنك حذف آخر وسيلة تعريف.",
|
||||
"unstable__errors.identification_deletion_failed": "لا يمكنك حذف هويتك الأخيرة.",
|
||||
"unstable__errors.not_allowed_access": "",
|
||||
"unstable__errors.passkey_already_exists": "يوجد مفتاح مرور مسجل بالفعل على هذا الجهاز.",
|
||||
"unstable__errors.passkey_not_supported": "مفاتيح المرور غير مدعومة على هذا الجهاز.",
|
||||
"unstable__errors.passkey_pa_not_supported": "يتطلب التسجيل مصادق منصة، لكن الجهاز لا يدعمه.",
|
||||
"unstable__errors.passkey_registration_cancelled": "تم إلغاء تسجيل مفتاح المرور أو انتهت المهلة.",
|
||||
"unstable__errors.passkey_retrieval_cancelled": "تم إلغاء التحقق من مفتاح المرور أو انتهت المهلة.",
|
||||
"unstable__errors.passwordComplexity.maximumLength": "أقل من {{length}} حرفًا",
|
||||
"unstable__errors.passwordComplexity.minimumLength": "{{length}} حرفًا أو أكثر",
|
||||
"unstable__errors.passkey_already_exists": "تم تسجيل مفتاح الوصول مسبقًا بهذا الجهاز.",
|
||||
"unstable__errors.passkey_not_supported": "مفاتيح الوصول غير مدعومة على هذا الجهاز.",
|
||||
"unstable__errors.passkey_pa_not_supported": "التسجيل يتطلب مصادق النظام ولكن الجهاز لا يدعم ذلك.",
|
||||
"unstable__errors.passkey_registration_cancelled": "تم إلغاء تسجيل مفتاح الوصول أو انتهت صلاحيته.",
|
||||
"unstable__errors.passkey_retrieval_cancelled": "تم إلغاء استرداد مفتاح الوصول أو انتهت صلاحيته.",
|
||||
"unstable__errors.passwordComplexity.maximumLength": "أقل من {{length}} حرف",
|
||||
"unstable__errors.passwordComplexity.minimumLength": "{{length}} أو أكثر من الأحرف",
|
||||
"unstable__errors.passwordComplexity.requireLowercase": "حرف صغير",
|
||||
"unstable__errors.passwordComplexity.requireNumbers": "رقم",
|
||||
"unstable__errors.passwordComplexity.requireSpecialCharacter": "رمز خاص",
|
||||
"unstable__errors.passwordComplexity.requireUppercase": "حرف كبير",
|
||||
"unstable__errors.passwordComplexity.sentencePrefix": "يجب أن تحتوي كلمة المرور على",
|
||||
"unstable__errors.phone_number_exists": "رقم الهاتف هذا مستخدم بالفعل. يرجى تجربة رقم آخر.",
|
||||
"unstable__errors.zxcvbn.couldBeStronger": "كلمة المرور تعمل، لكنها يمكن أن تكون أقوى. جرب إضافة المزيد من الأحرف.",
|
||||
"unstable__errors.zxcvbn.goodPassword": "كلمة المرور الخاصة بك تستوفي جميع المتطلبات اللازمة.",
|
||||
"unstable__errors.zxcvbn.notEnough": "كلمة المرور الخاصة بك غير قوية بما فيه الكفاية.",
|
||||
"unstable__errors.zxcvbn.suggestions.allUppercase": "استخدم بعض الأحرف الكبيرة، وليس جميعها.",
|
||||
"unstable__errors.zxcvbn.suggestions.anotherWord": "أضف كلمات أكثر وأقل شيوعًا.",
|
||||
"unstable__errors.passwordComplexity.sentencePrefix": "يجب أن تحتوي كلمة المرور الخاصة بك على",
|
||||
"unstable__errors.phone_number_exists": "هذا الرقم مستخدم. يرجى المحاولة برقم آخر.",
|
||||
"unstable__errors.zxcvbn.couldBeStronger": "كلمة المرور الخاصة بك تعمل، ولكن يمكن أن تكون أقوى. جرب إضافة المزيد من الأحرف.",
|
||||
"unstable__errors.zxcvbn.goodPassword": "كلمة المرور الخاصة بك تلبي جميع المتطلبات اللازمة.",
|
||||
"unstable__errors.zxcvbn.notEnough": "كلمة المرور الخاصة بك ليست قوية بما فيه الكفاية.",
|
||||
"unstable__errors.zxcvbn.suggestions.allUppercase": "قم بتحويل بعض الحروف إلى أحرف كبيرة، ولكن ليس كلها.",
|
||||
"unstable__errors.zxcvbn.suggestions.anotherWord": "أضف المزيد من الكلمات غير الشائعة.",
|
||||
"unstable__errors.zxcvbn.suggestions.associatedYears": "تجنب السنوات المرتبطة بك.",
|
||||
"unstable__errors.zxcvbn.suggestions.capitalization": "استخدم أكثر من حرف كبير واحد.",
|
||||
"unstable__errors.zxcvbn.suggestions.capitalization": "استخدم الحروف الكبيرة أكثر من الحرف الأول فقط.",
|
||||
"unstable__errors.zxcvbn.suggestions.dates": "تجنب التواريخ والسنوات المرتبطة بك.",
|
||||
"unstable__errors.zxcvbn.suggestions.l33t": "تجنب الاستبدالات المتوقعة مثل '@' بدلاً من 'a'.",
|
||||
"unstable__errors.zxcvbn.suggestions.longerKeyboardPattern": "استخدم أنماط لوحة مفاتيح أطول وغيّر اتجاه الكتابة عدة مرات.",
|
||||
"unstable__errors.zxcvbn.suggestions.noNeed": "يمكنك إنشاء كلمات مرور قوية دون استخدام رموز أو أرقام أو أحرف كبيرة.",
|
||||
"unstable__errors.zxcvbn.suggestions.pwned": "إذا كنت تستخدم هذه الكلمة في مكان آخر، يجب عليك تغييرها.",
|
||||
"unstable__errors.zxcvbn.suggestions.l33t": "تجنب التبديلات التنبؤية للحروف مثل '@' بدلاً من 'a'.",
|
||||
"unstable__errors.zxcvbn.suggestions.longerKeyboardPattern": "استخدم أنماط لوحة المفاتيح الطويلة وغير اتجاه الكتابة عدة مرات.",
|
||||
"unstable__errors.zxcvbn.suggestions.noNeed": "يمكنك إنشاء كلمات مرور قوية دون استخدام رموز أو أرقام أو حروف كبيرة.",
|
||||
"unstable__errors.zxcvbn.suggestions.pwned": "إذا استخدمت هذه كلمة المرور في مكان آخر، يجب عليك تغييرها.",
|
||||
"unstable__errors.zxcvbn.suggestions.recentYears": "تجنب السنوات الحديثة.",
|
||||
"unstable__errors.zxcvbn.suggestions.repeated": "تجنب تكرار الكلمات أو الأحرف.",
|
||||
"unstable__errors.zxcvbn.suggestions.reverseWords": "تجنب كتابة الكلمات الشائعة بشكل معكوس.",
|
||||
"unstable__errors.zxcvbn.suggestions.repeated": "تجنب تكرار الكلمات والأحرف.",
|
||||
"unstable__errors.zxcvbn.suggestions.reverseWords": "تجنب تهجئة الكلمات الشائعة بشكل معكوس.",
|
||||
"unstable__errors.zxcvbn.suggestions.sequences": "تجنب تسلسلات الأحرف الشائعة.",
|
||||
"unstable__errors.zxcvbn.suggestions.useWords": "استخدم عدة كلمات، لكن تجنب العبارات الشائعة.",
|
||||
"unstable__errors.zxcvbn.suggestions.useWords": "استخدم كلمات متعددة، ولكن تجنب العبارات الشائعة.",
|
||||
"unstable__errors.zxcvbn.warnings.common": "هذه كلمة مرور شائعة الاستخدام.",
|
||||
"unstable__errors.zxcvbn.warnings.commonNames": "الأسماء والألقاب الشائعة يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.dates": "التواريخ يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.extendedRepeat": "أنماط الأحرف المتكررة مثل \"abcabcabc\" يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.keyPattern": "أنماط لوحة المفاتيح القصيرة يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.namesByThemselves": "الأسماء أو الألقاب المفردة يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.pwned": "تم تسريب كلمة المرور الخاصة بك في خرق بيانات على الإنترنت.",
|
||||
"unstable__errors.zxcvbn.warnings.recentYears": "السنوات الحديثة يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.sequences": "تسلسلات الأحرف الشائعة مثل \"abc\" يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.similarToCommon": "تشبه كلمة مرور شائعة الاستخدام.",
|
||||
"unstable__errors.zxcvbn.warnings.simpleRepeat": "الأحرف المتكررة مثل \"aaa\" يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.straightRow": "صفوف مستقيمة من المفاتيح على لوحة المفاتيح يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.topHundred": "هذه كلمة مرور مستخدمة بشكل متكرر.",
|
||||
"unstable__errors.zxcvbn.warnings.topTen": "هذه كلمة مرور مستخدمة بكثرة.",
|
||||
"unstable__errors.zxcvbn.warnings.userInputs": "يجب ألا تحتوي على بيانات شخصية أو متعلقة بالصفحة.",
|
||||
"unstable__errors.zxcvbn.warnings.wordByItself": "الكلمات المفردة يسهل تخمينها.",
|
||||
"unstable__errors.zxcvbn.warnings.commonNames": "الأسماء الشائعة سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.dates": "التواريخ سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.extendedRepeat": "أنماط الحروف المتكررة مثل \"abcabcabc\" سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.keyPattern": "أنماط لوحة المفاتيح القصيرة سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.namesByThemselves": "الأسماء الفردية أو الأسماء العائلية سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.pwned": "تمت تعريض كلمة المرور الخاصة بك في اختراق على الإنترنت.",
|
||||
"unstable__errors.zxcvbn.warnings.recentYears": "السنوات الحديثة سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.sequences": "تسلسلات الأحرف الشائعة مثل \"abc\" سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.similarToCommon": "هذا مشابه لكلمة مرور شائعة الاستخدام.",
|
||||
"unstable__errors.zxcvbn.warnings.simpleRepeat": "الحروف المتكررة مثل \"aaa\" سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.straightRow": "صفوف الحروف المستقيمة على لوحة المفاتيح سهلة التخمين.",
|
||||
"unstable__errors.zxcvbn.warnings.topHundred": "هذه كلمة مرور تستخدم بكثرة.",
|
||||
"unstable__errors.zxcvbn.warnings.topTen": "هذه كلمة مرور تستخدم بشكل كبير.",
|
||||
"unstable__errors.zxcvbn.warnings.userInputs": "يجب ألا يكون هناك أي بيانات شخصية أو ذات صلة بالصفحة.",
|
||||
"unstable__errors.zxcvbn.warnings.wordByItself": "الكلمات الفردية سهلة التخمين.",
|
||||
"userButton.action__addAccount": "إضافة حساب",
|
||||
"userButton.action__manageAccount": "إدارة الحساب",
|
||||
"userButton.action__signOut": "تسجيل الخروج",
|
||||
"userButton.action__signOutAll": "تسجيل الخروج من جميع الحسابات",
|
||||
"userProfile.backupCodePage.actionLabel__copied": "تم النسخ!",
|
||||
"userProfile.backupCodePage.actionLabel__copy": "نسخ الكل",
|
||||
"userProfile.backupCodePage.actionLabel__download": "تنزيل .txt",
|
||||
"userProfile.backupCodePage.actionLabel__download": "تحميل .txt",
|
||||
"userProfile.backupCodePage.actionLabel__print": "طباعة",
|
||||
"userProfile.backupCodePage.infoText1": "سيتم تفعيل رموز النسخ الاحتياطي لهذا الحساب.",
|
||||
"userProfile.backupCodePage.infoText2": "احتفظ برموز النسخ الاحتياطي في مكان آمن وسري. يمكنك إعادة توليد الرموز إذا كنت تشك في أنها قد تم اختراقها.",
|
||||
"userProfile.backupCodePage.subtitle__codelist": "احتفظ بها في مكان آمن وسري.",
|
||||
"userProfile.backupCodePage.successMessage": "تم تفعيل رموز النسخ الاحتياطي. يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك إذا فقدت الوصول إلى جهاز المصادقة. يمكن استخدام كل رمز مرة واحدة فقط.",
|
||||
"userProfile.backupCodePage.successSubtitle": "يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك إذا فقدت الوصول إلى جهاز المصادقة.",
|
||||
"userProfile.backupCodePage.title": "إضافة تحقق برمز احتياطي",
|
||||
"userProfile.backupCodePage.infoText1": "سيتم تمكين رموز النسخ الاحتياطي لهذا الحساب.",
|
||||
"userProfile.backupCodePage.infoText2": "احتفظ برموز النسخ الاحتياطي بسرية وقم بتخزينها بشكل آمن. يمكنك إعادة إنشاء رموز النسخ الاحتياطي إذا كنت تشتبه في تعرضها للخطر.",
|
||||
"userProfile.backupCodePage.subtitle__codelist": "قم بتخزينها بشكل آمن واحتفظ بها سرية.",
|
||||
"userProfile.backupCodePage.successMessage": "تم تمكين رموز النسخ الاحتياطي الآن. يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك، إذا فقدت الوصول إلى جهاز المصادقة الخاص بك. يمكن استخدام كل رمز مرة واحدة فقط.",
|
||||
"userProfile.backupCodePage.successSubtitle": "يمكنك استخدام أحد هذه الرموز لتسجيل الدخول إلى حسابك، إذا فقدت الوصول إلى جهاز المصادقة الخاص بك.",
|
||||
"userProfile.backupCodePage.title": "إضافة التحقق برمز النسخ الاحتياطي",
|
||||
"userProfile.backupCodePage.title__codelist": "رموز النسخ الاحتياطي",
|
||||
"userProfile.connectedAccountPage.formHint": "اختر مزودًا لربط حسابك.",
|
||||
"userProfile.connectedAccountPage.formHint__noAccounts": "لا توجد مزودات حسابات خارجية متاحة.",
|
||||
"userProfile.connectedAccountPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
|
||||
"userProfile.connectedAccountPage.removeResource.messageLine2": "لن تتمكن من استخدام هذا الحساب المرتبط بعد الآن، وقد تتوقف بعض الميزات المعتمدة عليه.",
|
||||
"userProfile.connectedAccountPage.formHint": "حدد مزودًا للاتصال بحسابك.",
|
||||
"userProfile.connectedAccountPage.formHint__noAccounts": "لا توجد مزودي حساب خارجي متاحين.",
|
||||
"userProfile.connectedAccountPage.removeResource.messageLine1": "سيتم إزالة {{identifier}} من هذا الحساب.",
|
||||
"userProfile.connectedAccountPage.removeResource.messageLine2": "لن تتمكن بعد الآن من استخدام هذا الحساب المتصل ولن تعمل أي ميزات تعتمد عليه.",
|
||||
"userProfile.connectedAccountPage.removeResource.successMessage": "تمت إزالة {{connectedAccount}} من حسابك.",
|
||||
"userProfile.connectedAccountPage.removeResource.title": "إزالة الحساب المرتبط",
|
||||
"userProfile.connectedAccountPage.removeResource.title": "إزالة الحساب المتصل",
|
||||
"userProfile.connectedAccountPage.socialButtonsBlockButton": "{{provider|titleize}}",
|
||||
"userProfile.connectedAccountPage.successMessage": "تمت إضافة المزود إلى حسابك",
|
||||
"userProfile.connectedAccountPage.title": "إضافة حساب مرتبط",
|
||||
"userProfile.connectedAccountPage.title": "إضافة حساب متصل",
|
||||
"userProfile.deletePage.actionDescription": "اكتب \"حذف الحساب\" أدناه للمتابعة.",
|
||||
"userProfile.deletePage.confirm": "حذف الحساب",
|
||||
"userProfile.deletePage.messageLine1": "هل أنت متأكد أنك تريد حذف حسابك؟",
|
||||
"userProfile.deletePage.messageLine2": "هذا الإجراء دائم ولا يمكن التراجع عنه.",
|
||||
"userProfile.deletePage.title": "حذف الحساب",
|
||||
"userProfile.emailAddressPage.emailCode.formHint": "سيتم إرسال رسالة بريد إلكتروني تحتوي على رمز تحقق إلى هذا العنوان.",
|
||||
"userProfile.emailAddressPage.emailCode.formHint": "سيتم إرسال بريد إلكتروني يحتوي على رمز التحقق إلى هذا العنوان الإلكتروني.",
|
||||
"userProfile.emailAddressPage.emailCode.formSubtitle": "أدخل رمز التحقق المرسل إلى {{identifier}}",
|
||||
"userProfile.emailAddressPage.emailCode.formTitle": "رمز التحقق",
|
||||
"userProfile.emailAddressPage.emailCode.resendButton": "لم يصلك الرمز؟ أعد الإرسال",
|
||||
"userProfile.emailAddressPage.emailCode.resendButton": "لم تستلم الرمز؟ إعادة الإرسال",
|
||||
"userProfile.emailAddressPage.emailCode.successMessage": "تمت إضافة البريد الإلكتروني {{identifier}} إلى حسابك.",
|
||||
"userProfile.emailAddressPage.emailLink.formHint": "سيتم إرسال رسالة بريد إلكتروني تحتوي على رابط تحقق إلى هذا العنوان.",
|
||||
"userProfile.emailAddressPage.emailLink.formSubtitle": "انقر على رابط التحقق في البريد الإلكتروني المرسل إلى {{identifier}}",
|
||||
"userProfile.emailAddressPage.emailLink.formHint": "سيتم إرسال بريد إلكتروني يحتوي على رابط التحقق إلى هذا العنوان الإلكتروني.",
|
||||
"userProfile.emailAddressPage.emailLink.formSubtitle": "انقر على الرابط في البريد الإلكتروني المرسل إلى {{identifier}}",
|
||||
"userProfile.emailAddressPage.emailLink.formTitle": "رابط التحقق",
|
||||
"userProfile.emailAddressPage.emailLink.resendButton": "لم يصلك الرابط؟ أعد الإرسال",
|
||||
"userProfile.emailAddressPage.emailLink.resendButton": "لم تستلم الرابط؟ إعادة الإرسال",
|
||||
"userProfile.emailAddressPage.emailLink.successMessage": "تمت إضافة البريد الإلكتروني {{identifier}} إلى حسابك.",
|
||||
"userProfile.emailAddressPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
|
||||
"userProfile.emailAddressPage.removeResource.messageLine2": "لن تتمكن من تسجيل الدخول باستخدام هذا البريد الإلكتروني بعد الآن.",
|
||||
"userProfile.emailAddressPage.removeResource.messageLine1": "سيتم إزالة {{identifier}} من هذا الحساب.",
|
||||
"userProfile.emailAddressPage.removeResource.messageLine2": "لن تتمكن بعد الآن من تسجيل الدخول باستخدام هذا العنوان الإلكتروني.",
|
||||
"userProfile.emailAddressPage.removeResource.successMessage": "تمت إزالة {{emailAddress}} من حسابك.",
|
||||
"userProfile.emailAddressPage.removeResource.title": "إزالة عنوان البريد الإلكتروني",
|
||||
"userProfile.emailAddressPage.title": "إضافة عنوان بريد إلكتروني",
|
||||
@@ -422,33 +422,33 @@
|
||||
"userProfile.formButtonPrimary__remove": "إزالة",
|
||||
"userProfile.formButtonPrimary__save": "حفظ",
|
||||
"userProfile.formButtonReset": "إلغاء",
|
||||
"userProfile.mfaPage.formHint": "اختر طريقة للإضافة.",
|
||||
"userProfile.mfaPage.title": "إضافة تحقق بخطوتين",
|
||||
"userProfile.mfaPhoneCodePage.backButton": "استخدام رقم موجود",
|
||||
"userProfile.mfaPhoneCodePage.primaryButton__addPhoneNumber": "إضافة رقم هاتف",
|
||||
"userProfile.mfaPhoneCodePage.removeResource.messageLine1": "{{identifier}} لن يتلقى رموز التحقق عند تسجيل الدخول.",
|
||||
"userProfile.mfaPhoneCodePage.removeResource.messageLine2": "قد لا يكون حسابك آمناً كما كان. هل ترغب في المتابعة؟",
|
||||
"userProfile.mfaPage.formHint": "حدد طريقة للإضافة.",
|
||||
"userProfile.mfaPage.title": "إضافة التحقق بخطوتين",
|
||||
"userProfile.mfaPhoneCodePage.backButton": "استخدام الرقم الحالي",
|
||||
"userProfile.mfaPhoneCodePage.primaryButton__addPhoneNumber": "إضافة رقم الهاتف",
|
||||
"userProfile.mfaPhoneCodePage.removeResource.messageLine1": "لن يتم استقبال رموز التحقق من هذا الرقم بعد الآن عند تسجيل الدخول.",
|
||||
"userProfile.mfaPhoneCodePage.removeResource.messageLine2": "قد لا يكون حسابك آمنًا. هل أنت متأكد من رغبتك في المتابعة؟",
|
||||
"userProfile.mfaPhoneCodePage.removeResource.successMessage": "تمت إزالة التحقق بخطوتين عبر رمز SMS لـ {{mfaPhoneCode}}",
|
||||
"userProfile.mfaPhoneCodePage.removeResource.title": "إزالة التحقق بخطوتين",
|
||||
"userProfile.mfaPhoneCodePage.subtitle__availablePhoneNumbers": "اختر رقم هاتف موجود لتسجيله في التحقق بخطوتين عبر رمز SMS أو أضف رقمًا جديدًا.",
|
||||
"userProfile.mfaPhoneCodePage.subtitle__unavailablePhoneNumbers": "لا توجد أرقام هواتف متاحة للتسجيل في التحقق بخطوتين عبر رمز SMS، يرجى إضافة رقم جديد.",
|
||||
"userProfile.mfaPhoneCodePage.successMessage1": "عند تسجيل الدخول، ستحتاج إلى إدخال رمز تحقق يُرسل إلى هذا الرقم كخطوة إضافية.",
|
||||
"userProfile.mfaPhoneCodePage.successMessage2": "احفظ رموز النسخ الاحتياطي واحتفظ بها في مكان آمن. إذا فقدت الوصول إلى جهاز المصادقة، يمكنك استخدام الرموز لتسجيل الدخول.",
|
||||
"userProfile.mfaPhoneCodePage.successTitle": "تم تفعيل التحقق برمز SMS",
|
||||
"userProfile.mfaPhoneCodePage.title": "إضافة تحقق برمز SMS",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.buttonAbleToScan__nonPrimary": "مسح رمز QR بدلاً من ذلك",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.buttonUnableToScan__nonPrimary": "لا يمكنك مسح رمز QR؟",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.infoText__ableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة الخاص بك وامسح رمز QR التالي لربطه بحسابك.",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.infoText__unableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة وأدخل المفتاح الموضح أدناه.",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan1": "تأكد من تفعيل كلمات المرور المؤقتة أو المستندة إلى الوقت، ثم أكمل ربط الحساب.",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan2": "بدلاً من ذلك، إذا كان تطبيق المصادقة يدعم TOTP URIs، يمكنك نسخ الرابط الكامل.",
|
||||
"userProfile.mfaTOTPPage.removeResource.messageLine1": "لن يُطلب منك إدخال رموز التحقق من هذا التطبيق عند تسجيل الدخول.",
|
||||
"userProfile.mfaTOTPPage.removeResource.messageLine2": "قد لا يكون حسابك آمناً كما كان. هل ترغب في المتابعة؟",
|
||||
"userProfile.mfaPhoneCodePage.subtitle__availablePhoneNumbers": "حدد رقم هاتف موجود للتسجيل في التحقق بخطوتين عبر رمز SMS أو أضف واحدًا جديدًا.",
|
||||
"userProfile.mfaPhoneCodePage.subtitle__unavailablePhoneNumbers": "لا توجد أرقام هواتف متاحة للتسجيل في التحقق بخطوتين عبر رمز SMS، يرجى إضافة واحدة جديدة.",
|
||||
"userProfile.mfaPhoneCodePage.successMessage1": "عند تسجيل الدخول، ستحتاج إلى إدخال رمز التحقق المرسل إلى هذا الرقم كخطوة إضافية.",
|
||||
"userProfile.mfaPhoneCodePage.successMessage2": "احفظ هذه الرموز الاحتياطية وقم بتخزينها في مكان آمن. إذا فقدت الوصول إلى جهاز المصادقة الخاص بك، يمكنك استخدام رموز النسخ الاحتياطي لتسجيل الدخول.",
|
||||
"userProfile.mfaPhoneCodePage.successTitle": "تم تمكين التحقق برمز SMS",
|
||||
"userProfile.mfaPhoneCodePage.title": "إضافة التحقق برمز SMS",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.buttonAbleToScan__nonPrimary": "مسح رمز الاستجابة السريعة بدلاً من ذلك",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.buttonUnableToScan__nonPrimary": "لا يمكن مسح رمز الاستجابة السريعة؟",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.infoText__ableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة الخاص بك وامسح رمز الاستجابة السريعة التالي لربطه بحسابك.",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.infoText__unableToScan": "قم بإعداد طريقة تسجيل دخول جديدة في تطبيق المصادقة الخاص بك وأدخل المفتاح المقدم أدناه.",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan1": "تأكد من تمكين كلمة المرور الزمنية أو كلمات المرور لمرة واحدة، ثم انهي ربط حسابك.",
|
||||
"userProfile.mfaTOTPPage.authenticatorApp.inputLabel__unableToScan2": "بديلًا، إذا كان جهاز المصادقة الخاص بك يدعم TOTP URIs، يمكنك أيضًا نسخ الرابط الكامل.",
|
||||
"userProfile.mfaTOTPPage.removeResource.messageLine1": "لن تكون هناك حاجة لرموز التحقق من هذا التطبيق بعد الآن عند تسجيل الدخول.",
|
||||
"userProfile.mfaTOTPPage.removeResource.messageLine2": "قد لا يكون حسابك آمنًا. هل أنت متأكد من رغبتك في المتابعة؟",
|
||||
"userProfile.mfaTOTPPage.removeResource.successMessage": "تمت إزالة التحقق بخطوتين عبر تطبيق المصادقة.",
|
||||
"userProfile.mfaTOTPPage.removeResource.title": "إزالة التحقق بخطوتين",
|
||||
"userProfile.mfaTOTPPage.successMessage": "تم تفعيل التحقق بخطوتين. عند تسجيل الدخول، ستحتاج إلى إدخال رمز تحقق من تطبيق المصادقة كخطوة إضافية.",
|
||||
"userProfile.mfaTOTPPage.title": "إضافة تطبيق مصادقة",
|
||||
"userProfile.mfaTOTPPage.verifySubtitle": "أدخل رمز التحقق الذي أنشأه تطبيق المصادقة",
|
||||
"userProfile.mfaTOTPPage.successMessage": "تم تمكين التحقق بخطوتين الآن. عند تسجيل الدخول، ستحتاج إلى إدخال رمز التحقق من هذا التطبيق كخطوة إضافية.",
|
||||
"userProfile.mfaTOTPPage.title": "إضافة تطبيق المصادقة",
|
||||
"userProfile.mfaTOTPPage.verifySubtitle": "أدخل رمز التحقق الذي تم إنشاؤه بواسطة تطبيق المصادقة الخاص بك",
|
||||
"userProfile.mfaTOTPPage.verifyTitle": "رمز التحقق",
|
||||
"userProfile.mobileButton__menu": "القائمة",
|
||||
"userProfile.navbar.account": "الملف الشخصي",
|
||||
@@ -459,70 +459,70 @@
|
||||
"userProfile.passkeyScreen.removeResource.title": "إزالة مفتاح المرور",
|
||||
"userProfile.passkeyScreen.subtitle__rename": "يمكنك تغيير اسم مفتاح المرور لتسهيل العثور عليه.",
|
||||
"userProfile.passkeyScreen.title__rename": "إعادة تسمية مفتاح المرور",
|
||||
"userProfile.passwordPage.checkboxInfoText__signOutOfOtherSessions": "يُوصى بتسجيل الخروج من جميع الأجهزة الأخرى التي قد استخدمت كلمة المرور القديمة.",
|
||||
"userProfile.passwordPage.readonly": "لا يمكن تعديل كلمة المرور حالياً لأنك تسجل الدخول فقط عبر الاتصال المؤسسي.",
|
||||
"userProfile.passwordPage.checkboxInfoText__signOutOfOtherSessions": "يُوصى بتسجيل الخروج من جميع الأجهزة الأخرى التي قد تكون استخدمت كلمة المرور القديمة الخاصة بك.",
|
||||
"userProfile.passwordPage.readonly": "لا يمكن تحرير كلمة المرور الخاصة بك حاليًا لأنه يمكنك تسجيل الدخول فقط عبر الاتصال بالشركة.",
|
||||
"userProfile.passwordPage.successMessage__set": "تم تعيين كلمة المرور الخاصة بك.",
|
||||
"userProfile.passwordPage.successMessage__signOutOfOtherSessions": "تم تسجيل الخروج من جميع الأجهزة الأخرى.",
|
||||
"userProfile.passwordPage.successMessage__update": "تم تحديث كلمة المرور الخاصة بك.",
|
||||
"userProfile.passwordPage.title__set": "تعيين كلمة المرور",
|
||||
"userProfile.passwordPage.title__update": "تحديث كلمة المرور",
|
||||
"userProfile.phoneNumberPage.infoText": "سيتم إرسال رسالة نصية تحتوي على رمز تحقق إلى هذا الرقم. قد يتم تطبيق رسوم على الرسائل والبيانات.",
|
||||
"userProfile.phoneNumberPage.infoText": "سيتم إرسال رسالة نصية تحتوي على رمز التحقق إلى هذا الرقم. قد تنطبق رسوم الرسائل والبيانات.",
|
||||
"userProfile.phoneNumberPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
|
||||
"userProfile.phoneNumberPage.removeResource.messageLine2": "لن تتمكن من تسجيل الدخول باستخدام هذا الرقم بعد الآن.",
|
||||
"userProfile.phoneNumberPage.removeResource.messageLine2": "لن تتمكن بعد الآن من تسجيل الدخول باستخدام هذا الرقم.",
|
||||
"userProfile.phoneNumberPage.removeResource.successMessage": "تمت إزالة {{phoneNumber}} من حسابك.",
|
||||
"userProfile.phoneNumberPage.removeResource.title": "إزالة رقم الهاتف",
|
||||
"userProfile.phoneNumberPage.successMessage": "تمت إضافة {{identifier}} إلى حسابك.",
|
||||
"userProfile.phoneNumberPage.title": "إضافة رقم هاتف",
|
||||
"userProfile.phoneNumberPage.successMessage": "{{identifier}} تمت إضافته إلى حسابك.",
|
||||
"userProfile.phoneNumberPage.title": "إضافة رقم الهاتف",
|
||||
"userProfile.phoneNumberPage.verifySubtitle": "أدخل رمز التحقق المرسل إلى {{identifier}}",
|
||||
"userProfile.phoneNumberPage.verifyTitle": "تحقق من رقم الهاتف",
|
||||
"userProfile.profilePage.fileDropAreaHint": "الحجم الموصى به 1:1، حتى 10 ميجابايت.",
|
||||
"userProfile.profilePage.fileDropAreaHint": "الحجم الموصى به 1:1، حتى 10 ميغابايت.",
|
||||
"userProfile.profilePage.imageFormDestructiveActionSubtitle": "إزالة",
|
||||
"userProfile.profilePage.imageFormSubtitle": "تحميل",
|
||||
"userProfile.profilePage.imageFormTitle": "صورة الملف الشخصي",
|
||||
"userProfile.profilePage.readonly": "تم توفير معلومات ملفك الشخصي من خلال الاتصال المؤسسي ولا يمكن تعديلها.",
|
||||
"userProfile.profilePage.readonly": "تم توفير معلومات ملفك الشخصي من خلال الاتصال بالشركة ولا يمكن تحريرها.",
|
||||
"userProfile.profilePage.successMessage": "تم تحديث ملفك الشخصي.",
|
||||
"userProfile.profilePage.title": "تحديث الملف الشخصي",
|
||||
"userProfile.start.activeDevicesSection.destructiveAction": "تسجيل الخروج من الجهاز",
|
||||
"userProfile.start.activeDevicesSection.title": "الأجهزة النشطة",
|
||||
"userProfile.start.connectedAccountsSection.actionLabel__connectionFailed": "حاول مرة أخرى",
|
||||
"userProfile.start.connectedAccountsSection.actionLabel__reauthorize": "قم بالتفويض الآن",
|
||||
"userProfile.start.connectedAccountsSection.actionLabel__reauthorize": "التفويض الآن",
|
||||
"userProfile.start.connectedAccountsSection.destructiveActionTitle": "إزالة",
|
||||
"userProfile.start.connectedAccountsSection.primaryButton": "ربط الحساب",
|
||||
"userProfile.start.connectedAccountsSection.subtitle__reauthorize": "تم تحديث الأذونات المطلوبة، وقد تواجه وظائف محدودة. يرجى إعادة تفويض هذا التطبيق لتجنب أي مشاكل",
|
||||
"userProfile.start.connectedAccountsSection.title": "الحسابات المرتبطة",
|
||||
"userProfile.start.connectedAccountsSection.subtitle__reauthorize": "تم تحديث النطاقات المطلوبة، وقد تواجه قدرًا محدودًا من الوظائف. يرجى إعادة تفويض هذا التطبيق لتجنب أي مشاكل",
|
||||
"userProfile.start.connectedAccountsSection.title": "الحسابات المتصلة",
|
||||
"userProfile.start.dangerSection.deleteAccountButton": "حذف الحساب",
|
||||
"userProfile.start.dangerSection.title": "حذف الحساب",
|
||||
"userProfile.start.emailAddressesSection.destructiveAction": "إزالة البريد الإلكتروني",
|
||||
"userProfile.start.emailAddressesSection.detailsAction__nonPrimary": "تعيين كافتراضي",
|
||||
"userProfile.start.emailAddressesSection.detailsAction__primary": "إكمال التحقق",
|
||||
"userProfile.start.emailAddressesSection.detailsAction__unverified": "تحقق",
|
||||
"userProfile.start.emailAddressesSection.detailsAction__nonPrimary": "تعيين كأساسي",
|
||||
"userProfile.start.emailAddressesSection.detailsAction__primary": "اكتمال التحقق",
|
||||
"userProfile.start.emailAddressesSection.detailsAction__unverified": "التحقق",
|
||||
"userProfile.start.emailAddressesSection.primaryButton": "إضافة عنوان بريد إلكتروني",
|
||||
"userProfile.start.emailAddressesSection.title": "عناوين البريد الإلكتروني",
|
||||
"userProfile.start.enterpriseAccountsSection.title": "حسابات المؤسسات",
|
||||
"userProfile.start.enterpriseAccountsSection.title": "حسابات المؤسسة",
|
||||
"userProfile.start.headerTitle__account": "تفاصيل الملف الشخصي",
|
||||
"userProfile.start.headerTitle__security": "الأمان",
|
||||
"userProfile.start.mfaSection.backupCodes.actionLabel__regenerate": "إعادة التوليد",
|
||||
"userProfile.start.mfaSection.backupCodes.actionLabel__regenerate": "إعادة إنشاء",
|
||||
"userProfile.start.mfaSection.backupCodes.headerTitle": "رموز النسخ الاحتياطي",
|
||||
"userProfile.start.mfaSection.backupCodes.subtitle__regenerate": "احصل على مجموعة جديدة من رموز النسخ الاحتياطي الآمنة. سيتم حذف الرموز السابقة ولن تكون صالحة للاستخدام.",
|
||||
"userProfile.start.mfaSection.backupCodes.title__regenerate": "إعادة توليد رموز النسخ الاحتياطي",
|
||||
"userProfile.start.mfaSection.backupCodes.subtitle__regenerate": "احصل على مجموعة جديدة من رموز النسخ الاحتياطي الآمنة. سيتم حذف رموز النسخ الاحتياطي السابقة ولا يمكن استخدامها.",
|
||||
"userProfile.start.mfaSection.backupCodes.title__regenerate": "إعادة إنشاء رموز النسخ الاحتياطي",
|
||||
"userProfile.start.mfaSection.phoneCode.actionLabel__setDefault": "تعيين كافتراضي",
|
||||
"userProfile.start.mfaSection.phoneCode.destructiveActionLabel": "إزالة",
|
||||
"userProfile.start.mfaSection.primaryButton": "إضافة التحقق بخطوتين",
|
||||
"userProfile.start.mfaSection.title": "التحقق بخطوتين",
|
||||
"userProfile.start.mfaSection.primaryButton": "إضافة التحقق من خطوتين",
|
||||
"userProfile.start.mfaSection.title": "التحقق من خطوتين",
|
||||
"userProfile.start.mfaSection.totp.destructiveActionTitle": "إزالة",
|
||||
"userProfile.start.mfaSection.totp.headerTitle": "تطبيق المصادقة",
|
||||
"userProfile.start.passkeysSection.menuAction__destructive": "إزالة",
|
||||
"userProfile.start.passkeysSection.menuAction__rename": "إعادة التسمية",
|
||||
"userProfile.start.passkeysSection.menuAction__rename": "إعادة تسمية",
|
||||
"userProfile.start.passkeysSection.title": "مفاتيح المرور",
|
||||
"userProfile.start.passwordSection.primaryButton__setPassword": "تعيين كلمة المرور",
|
||||
"userProfile.start.passwordSection.primaryButton__setPassword": "تعيين كلمة مرور",
|
||||
"userProfile.start.passwordSection.primaryButton__updatePassword": "تحديث كلمة المرور",
|
||||
"userProfile.start.passwordSection.title": "كلمة المرور",
|
||||
"userProfile.start.phoneNumbersSection.destructiveAction": "إزالة رقم الهاتف",
|
||||
"userProfile.start.phoneNumbersSection.detailsAction__nonPrimary": "تعيين كافتراضي",
|
||||
"userProfile.start.phoneNumbersSection.detailsAction__primary": "إكمال التحقق",
|
||||
"userProfile.start.phoneNumbersSection.detailsAction__unverified": "تحقق من رقم الهاتف",
|
||||
"userProfile.start.phoneNumbersSection.primaryButton": "إضافة رقم هاتف",
|
||||
"userProfile.start.phoneNumbersSection.title": "أرقام الهاتف",
|
||||
"userProfile.start.phoneNumbersSection.detailsAction__nonPrimary": "تعيين كأساسي",
|
||||
"userProfile.start.phoneNumbersSection.detailsAction__primary": "اكتمال التحقق",
|
||||
"userProfile.start.phoneNumbersSection.detailsAction__unverified": "التحقق من رقم الهاتف",
|
||||
"userProfile.start.phoneNumbersSection.primaryButton": "إضافة رقم الهاتف",
|
||||
"userProfile.start.phoneNumbersSection.title": "أرقام الهواتف",
|
||||
"userProfile.start.profileSection.primaryButton": "تحديث الملف الشخصي",
|
||||
"userProfile.start.profileSection.title": "الملف الشخصي",
|
||||
"userProfile.start.usernameSection.primaryButton__setUsername": "تعيين اسم المستخدم",
|
||||
@@ -535,11 +535,11 @@
|
||||
"userProfile.usernamePage.title__set": "تعيين اسم المستخدم",
|
||||
"userProfile.usernamePage.title__update": "تحديث اسم المستخدم",
|
||||
"userProfile.web3WalletPage.removeResource.messageLine1": "{{identifier}} سيتم إزالته من هذا الحساب.",
|
||||
"userProfile.web3WalletPage.removeResource.messageLine2": "لن تتمكن من تسجيل الدخول باستخدام هذه المحفظة Web3 بعد الآن.",
|
||||
"userProfile.web3WalletPage.removeResource.successMessage": "{{web3Wallet}} تم إزالته من حسابك.",
|
||||
"userProfile.web3WalletPage.removeResource.title": "إزالة محفظة Web3",
|
||||
"userProfile.web3WalletPage.subtitle__availableWallets": "اختر محفظة Web3 لربطها بحسابك.",
|
||||
"userProfile.web3WalletPage.subtitle__unavailableWallets": "لا توجد محافظ Web3 متاحة.",
|
||||
"userProfile.web3WalletPage.removeResource.messageLine2": "لن تتمكن بعد الآن من تسجيل الدخول باستخدام هذا المحفظة web3.",
|
||||
"userProfile.web3WalletPage.removeResource.successMessage": "{{web3Wallet}} تمت إزالته من حسابك.",
|
||||
"userProfile.web3WalletPage.removeResource.title": "إزالة محفظة web3",
|
||||
"userProfile.web3WalletPage.subtitle__availableWallets": "حدد محفظة web3 للاتصال بحسابك.",
|
||||
"userProfile.web3WalletPage.subtitle__unavailableWallets": "لا توجد محافظ web3 متاحة.",
|
||||
"userProfile.web3WalletPage.successMessage": "تمت إضافة المحفظة إلى حسابك.",
|
||||
"userProfile.web3WalletPage.title": "إضافة محفظة Web3"
|
||||
"userProfile.web3WalletPage.title": "إضافة محفظة web3"
|
||||
}
|
||||
|
||||
+14
-12
@@ -1,20 +1,22 @@
|
||||
{
|
||||
"blue": "أزرق الفجر",
|
||||
"cyan": "سماوي ساطع",
|
||||
"custom": "مخصص",
|
||||
"cyan": "سماوي",
|
||||
"default": "افتراضي",
|
||||
"geekblue": "أزرق تقني",
|
||||
"gold": "أصفر القطيفة",
|
||||
"geekblue": "أزرق المهووسين",
|
||||
"gold": "ذهب",
|
||||
"green": "أخضر الشفق",
|
||||
"lime": "ليموني",
|
||||
"magenta": "أرجواني فرنسي",
|
||||
"mauve": "أرجواني الوستارية",
|
||||
"magenta": "ماجنتا فرنسي",
|
||||
"mauve": "بنفسجي فاتح",
|
||||
"olive": "أخضر زيتوني",
|
||||
"orange": "غروب",
|
||||
"purple": "أرجواني باذنجاني",
|
||||
"red": "أحمر الشفق",
|
||||
"sage": "أخضر الميرمية",
|
||||
"sand": "شاطئ",
|
||||
"slate": "رمادي أردوازي",
|
||||
"orange": "برتقالي الغروب",
|
||||
"presets": "الإعدادات المسبقة",
|
||||
"purple": "بنفسجي داكن",
|
||||
"red": "أحمر الغسق",
|
||||
"sage": "أخضر حكيم",
|
||||
"sand": "رمل",
|
||||
"slate": "رمادي لوحي",
|
||||
"volcano": "بركاني",
|
||||
"yellow": "شروق الشمس"
|
||||
"yellow": "أصفر الشروق"
|
||||
}
|
||||
|
||||
+190
-211
@@ -1,149 +1,149 @@
|
||||
{
|
||||
"about": "حول",
|
||||
"advanceSettings": "الإعدادات المتقدمة",
|
||||
"alert.cloud.action": "جرّب الآن",
|
||||
"alert.cloud.desc": "جميع المستخدمين المسجلين يحصلون على {{credit}} من أرصدة الحوسبة المجانية شهريًا — دون الحاجة إلى إعداد. يشمل المزامنة السحابية العالمية والبحث المتقدم على الويب.",
|
||||
"alert.cloud.descOnMobile": "جميع المستخدمين المسجلين يحصلون على {{credit}} من أرصدة الحوسبة المجانية شهريًا — دون الحاجة إلى إعداد.",
|
||||
"alert.cloud.title": "النسخة التجريبية من {{name}} متاحة الآن",
|
||||
"appLoading.appIdle": "جاهز للبدء",
|
||||
"appLoading.appInitializing": "يتم تشغيل التطبيق...",
|
||||
"appLoading.failed": "حدث خطأ أثناء بدء التشغيل. اعرض التفاصيل لاستكشاف الأخطاء، أو حاول مرة أخرى لاحقًا.",
|
||||
"appLoading.finished": "اكتمل تهيئة قاعدة البيانات",
|
||||
"appLoading.goToChat": "يتم تحميل صفحة الدردشة...",
|
||||
"appLoading.initAuth": "يتم تهيئة خدمة المصادقة...",
|
||||
"appLoading.initUser": "يتم تهيئة حالة المستخدم...",
|
||||
"appLoading.initializing": "يتم تهيئة قاعدة بيانات PGlite...",
|
||||
"appLoading.loadingDependencies": "يتم تهيئة التبعيات...",
|
||||
"appLoading.loadingWasm": "يتم تحميل وحدة WASM...",
|
||||
"appLoading.migrating": "يتم تنفيذ ترحيل قاعدة البيانات...",
|
||||
"advanceSettings": "إعدادات متقدمة",
|
||||
"alert.cloud.action": "تجربة مجانية",
|
||||
"alert.cloud.desc": "نحن نقدم {{credit}} نقطة حساب مجانية لجميع المستخدمين المسجلين، بدون الحاجة إلى تكوين معقد، فقط قم بتشغيلها، تدعم تاريخ الدردشة غير المحدود ومزامنة السحابة العالمية، والمزيد من الميزات المتقدمة بانتظار استكشافها معًا.",
|
||||
"alert.cloud.descOnMobile": "نحن نقدم {{credit}} نقطة حساب مجانية لجميع المستخدمين المسجلين، بدون الحاجة إلى إعدادات معقدة، فقط قم بالاستخدام.",
|
||||
"alert.cloud.title": "مرحبًا بك في التجربة {{name}}",
|
||||
"appLoading.appIdle": "جاهز للإطلاق",
|
||||
"appLoading.appInitializing": "جارٍ تشغيل التطبيق...",
|
||||
"appLoading.failed": "عذرًا، فشل تحميل التطبيق، يرجى مراجعة التفاصيل للتحقق من المشكلة",
|
||||
"appLoading.finished": "تم الانتهاء من تهيئة قاعدة البيانات",
|
||||
"appLoading.goToChat": "جارٍ تحميل صفحة الدردشة...",
|
||||
"appLoading.initAuth": "جارٍ تهيئة خدمة المصادقة...",
|
||||
"appLoading.initUser": "جارٍ تهيئة حالة المستخدم...",
|
||||
"appLoading.initializing": "جارٍ تهيئة قاعدة بيانات PGlite...",
|
||||
"appLoading.loadingDependencies": "جارٍ تهيئة الاعتمادات...",
|
||||
"appLoading.loadingWasm": "جارٍ تحميل وحدة WASM...",
|
||||
"appLoading.migrating": "جارٍ تنفيذ ترحيل الجداول...",
|
||||
"appLoading.ready": "قاعدة البيانات جاهزة",
|
||||
"appLoading.showDetail": "عرض التفاصيل",
|
||||
"autoGenerate": "إكمال تلقائي",
|
||||
"autoGenerateTooltip": "إكمال الوصف تلقائيًا من ملف تعريف الوكيل",
|
||||
"autoGenerateTooltipDisabled": "أضف ملف تعريف وكيل أولاً لاستخدام الإكمال التلقائي",
|
||||
"back": "رجوع",
|
||||
"batchDelete": "حذف جماعي",
|
||||
"blog": "مدونة المنتج",
|
||||
"autoGenerate": "توليد تلقائي",
|
||||
"autoGenerateTooltip": "إكمال تلقائي بناءً على الكلمات المقترحة لوصف المساعد",
|
||||
"autoGenerateTooltipDisabled": "الرجاء إدخال كلمة تلميح قبل تفعيل وظيفة الإكمال التلقائي",
|
||||
"back": "عودة",
|
||||
"batchDelete": "حذف دفعة",
|
||||
"blog": "مدونة المنتجات",
|
||||
"branching": "إنشاء موضوع فرعي",
|
||||
"branchingDisable": "ميزة \"الموضوع الفرعي\" غير متاحة في الوضع الحالي. لاستخدام هذه الميزة، يرجى التبديل إلى وضع قاعدة بيانات Postgres/Pglite أو استخدام LobeHub Cloud.",
|
||||
"branchingRequiresSavedTopic": "الموضوع الحالي غير محفوظ، يرجى حفظه أولاً لاستخدام ميزة الموضوع الفرعي",
|
||||
"branchingDisable": "ميزة \"الموضوعات الفرعية\" غير متاحة في الوضع الحالي. لاستخدام هذه الميزة، يُرجى التبديل إلى وضع قاعدة البيانات Postgres/Pglite أو استخدام LobeHub Cloud",
|
||||
"branchingRequiresSavedTopic": "الموضوع الحالي غير محفوظ، يجب الحفظ قبل استخدام ميزة الموضوع الفرعي",
|
||||
"cancel": "إلغاء",
|
||||
"changelog": "سجل التغييرات",
|
||||
"clientDB.autoInit.title": "يتم تهيئة قاعدة بيانات PGlite",
|
||||
"clientDB.error.desc": "فشل تهيئة PGlite. حاول مرة أخرى أولاً. إذا لم تنجح، افتح الإصلاحات الذاتية واتبع الخطوات. لا تزال تواجه مشكلة؟ استخدم خيار الإبلاغ عن المشكلة لإرسال تفاصيل الخطأ.",
|
||||
"clientDB.error.detail": "سبب الخطأ: [{{type}}] {{message}}. التفاصيل كما يلي:",
|
||||
"clientDB.autoInit.title": "تهيئة قاعدة بيانات PGlite",
|
||||
"clientDB.error.desc": "نعتذر، حدث خطأ أثناء عملية تهيئة قاعدة بيانات Pglite. يرجى النقر على الزر لإعادة المحاولة. إذا استمرت المشكلة بعد عدة محاولات، يرجى <1>تقديم مشكلة</1>، وسنساعدك في حلها في أسرع وقت ممكن",
|
||||
"clientDB.error.detail": "سبب الخطأ: [{{type}}] {{message}}، التفاصيل كالتالي:",
|
||||
"clientDB.error.detailTitle": "سبب الخطأ",
|
||||
"clientDB.error.report": "الإبلاغ عن مشكلة",
|
||||
"clientDB.error.retry": "إعادة المحاولة",
|
||||
"clientDB.error.selfSolve": "إصلاحات ذاتية",
|
||||
"clientDB.error.selfSolve": "حل ذاتي",
|
||||
"clientDB.error.title": "فشل تهيئة قاعدة البيانات",
|
||||
"clientDB.initing.error": "حدث خطأ، يرجى المحاولة مرة أخرى",
|
||||
"clientDB.initing.error": "حدث خطأ، يرجى إعادة المحاولة",
|
||||
"clientDB.initing.idle": "في انتظار التهيئة...",
|
||||
"clientDB.initing.initializing": "يتم التهيئة...",
|
||||
"clientDB.initing.loadingDependencies": "يتم تحميل التبعيات...",
|
||||
"clientDB.initing.loadingWasmModule": "يتم تحميل وحدة WASM...",
|
||||
"clientDB.initing.migrating": "يتم تنفيذ ترحيل قاعدة البيانات...",
|
||||
"clientDB.initing.initializing": "جارٍ التهيئة...",
|
||||
"clientDB.initing.loadingDependencies": "جارٍ تحميل الاعتماديات...",
|
||||
"clientDB.initing.loadingWasmModule": "جارٍ تحميل وحدة WASM...",
|
||||
"clientDB.initing.migrating": "جارٍ تنفيذ ترحيل البيانات...",
|
||||
"clientDB.initing.ready": "قاعدة البيانات جاهزة",
|
||||
"clientDB.modal.desc": "فعّل قاعدة البيانات العميلة من الجيل التالي. احفظ بيانات الدردشة في متصفحك وافتح ميزات متقدمة مثل المكتبة.",
|
||||
"clientDB.modal.enable": "فعّل الآن",
|
||||
"clientDB.modal.features.knowledgeBase.desc": "أنشئ مكتبتك الشخصية وتحدث مع الوكلاء باستخدامها (قريبًا).",
|
||||
"clientDB.modal.features.knowledgeBase.title": "دردشة المكتبة — عقلك الثاني",
|
||||
"clientDB.modal.features.localFirst.desc": "يتم تخزين بيانات الدردشة بالكامل في المتصفح، مما يحافظ على خصوصيتك وتحكمك الكامل.",
|
||||
"clientDB.modal.features.localFirst.title": "محلي أولاً، خصوصية أولاً",
|
||||
"clientDB.modal.features.pglite.desc": "مبني على PGlite، مع دعم مدمج لميزات متقدمة مثل البحث الشعاعي",
|
||||
"clientDB.modal.features.pglite.title": "بنية تخزين عميل من الجيل التالي",
|
||||
"clientDB.modal.init.desc": "يتم تهيئة قاعدة البيانات. قد يستغرق ذلك من 5 إلى 30 ثانية حسب جهازك وشبكتك. يمكنك القيام بشيء آخر والعودة لاحقًا.",
|
||||
"clientDB.modal.init.title": "يتم تهيئة قاعدة بيانات PGlite",
|
||||
"clientDB.modal.title": "تفعيل قاعدة البيانات العميلة",
|
||||
"clientDB.modal.desc": "فعّل قاعدة بيانات العميل من الجيل التالي الآن. خزّن بيانات الدردشة بشكل دائم في متصفحك، واستفد من ميزات متقدمة مثل مكتبة الموارد.",
|
||||
"clientDB.modal.enable": "تمكين الآن",
|
||||
"clientDB.modal.features.knowledgeBase.desc": "أنشئ مكتبة مواردك الشخصية وابدأ محادثات مع مساعدك باستخدامها بسهولة (قريبًا).",
|
||||
"clientDB.modal.features.knowledgeBase.title": "دعم محادثات مكتبة الموارد، لتفعيل العقل الثاني",
|
||||
"clientDB.modal.features.localFirst.desc": "تُخزن بيانات الدردشة بالكامل في المتصفح، بياناتك دائمًا تحت سيطرتك.",
|
||||
"clientDB.modal.features.localFirst.title": "الأولوية محلية، الخصوصية أولاً",
|
||||
"clientDB.modal.features.pglite.desc": "مبني على PGlite، يدعم بشكل أصلي ميزات AI Native المتقدمة (استرجاع المتجهات)",
|
||||
"clientDB.modal.features.pglite.title": "بنية تخزين عميل من الجيل الجديد",
|
||||
"clientDB.modal.init.desc": "جارٍ تهيئة قاعدة البيانات، قد يستغرق الأمر من 5 إلى 30 ثانية حسب اختلاف الشبكة",
|
||||
"clientDB.modal.init.title": "جارٍ تهيئة قاعدة بيانات PGlite",
|
||||
"clientDB.modal.title": "فتح قاعدة بيانات العميل",
|
||||
"clientDB.ready.button": "استخدم الآن",
|
||||
"clientDB.ready.desc": "جاهز للاستخدام",
|
||||
"clientDB.ready.desc": "استخدم الآن",
|
||||
"clientDB.ready.title": "قاعدة بيانات PGlite جاهزة",
|
||||
"clientDB.solve.backup.backup": "نسخ احتياطي",
|
||||
"clientDB.solve.backup.backupSuccess": "تم النسخ الاحتياطي بنجاح",
|
||||
"clientDB.solve.backup.desc": "تصدير البيانات الأساسية من قاعدة البيانات الحالية",
|
||||
"clientDB.solve.backup.export": "تصدير كل البيانات",
|
||||
"clientDB.solve.backup.exportDesc": "سيتم حفظ البيانات المصدرة بصيغة JSON، ويمكن استخدامها للاستعادة أو التحليل لاحقًا.",
|
||||
"clientDB.solve.backup.export": "تصدير جميع البيانات",
|
||||
"clientDB.solve.backup.exportDesc": "سيتم حفظ البيانات المصدرة بتنسيق JSON، ويمكن استخدامها لاستعادة أو تحليل لاحق.",
|
||||
"clientDB.solve.backup.reset.alert": "تحذير",
|
||||
"clientDB.solve.backup.reset.alertDesc": "قد تؤدي الإجراءات التالية إلى حذف البيانات. قم بالنسخ الاحتياطي أولاً — القرار لك.",
|
||||
"clientDB.solve.backup.reset.button": "إعادة تعيين قاعدة البيانات بالكامل (حذف كل البيانات)",
|
||||
"clientDB.solve.backup.reset.confirm.desc": "سيؤدي هذا الإجراء إلى حذف جميع البيانات ولا يمكن التراجع عنه. هل تؤكد المتابعة؟",
|
||||
"clientDB.solve.backup.reset.alertDesc": "قد تؤدي العمليات التالية إلى فقدان البيانات. يرجى التأكد من أنك قد قمت بعمل نسخة احتياطية من البيانات الهامة قبل المتابعة.",
|
||||
"clientDB.solve.backup.reset.button": "إعادة تعيين قاعدة البيانات بالكامل (حذف جميع البيانات)",
|
||||
"clientDB.solve.backup.reset.confirm.desc": "ستؤدي هذه العملية إلى حذف جميع البيانات ولا يمكن التراجع عنها، هل تؤكد المتابعة؟",
|
||||
"clientDB.solve.backup.reset.confirm.title": "تأكيد إعادة تعيين قاعدة البيانات",
|
||||
"clientDB.solve.backup.reset.desc": "أعد تعيين قاعدة البيانات في حال حدوث ترحيل غير قابل للاسترداد",
|
||||
"clientDB.solve.backup.reset.desc": "إعادة تعيين قاعدة البيانات في حالة عدم إمكانية الاستعادة",
|
||||
"clientDB.solve.backup.reset.title": "إعادة تعيين قاعدة البيانات",
|
||||
"clientDB.solve.backup.restore": "استعادة",
|
||||
"clientDB.solve.backup.restoreSuccess": "تمت الاستعادة بنجاح",
|
||||
"clientDB.solve.backup.restoreSuccess": "تم الاستعادة بنجاح",
|
||||
"clientDB.solve.backup.title": "نسخ احتياطي للبيانات",
|
||||
"clientDB.solve.diagnosis.createdAt": "وقت الإنشاء",
|
||||
"clientDB.solve.diagnosis.migratedAt": "وقت اكتمال الترحيل",
|
||||
"clientDB.solve.diagnosis.sql": "SQL الترحيل",
|
||||
"clientDB.solve.diagnosis.title": "حالة الترحيل",
|
||||
"clientDB.solve.repair.desc": "إدارة حالة الترحيل يدويًا",
|
||||
"clientDB.solve.diagnosis.createdAt": "تاريخ الإنشاء",
|
||||
"clientDB.solve.diagnosis.migratedAt": "تاريخ اكتمال النقل",
|
||||
"clientDB.solve.diagnosis.sql": "نقل SQL",
|
||||
"clientDB.solve.diagnosis.title": "حالة النقل",
|
||||
"clientDB.solve.repair.desc": "إدارة حالة النقل يدويًا",
|
||||
"clientDB.solve.repair.runSQL": "تنفيذ مخصص",
|
||||
"clientDB.solve.repair.sql.clear": "مسح",
|
||||
"clientDB.solve.repair.sql.desc": "تنفيذ أوامر SQL مخصصة لإصلاح مشكلات قاعدة البيانات",
|
||||
"clientDB.solve.repair.sql.markFinished": "وضع علامة كمكتمل",
|
||||
"clientDB.solve.repair.sql.placeholder": "أدخل أمر SQL...",
|
||||
"clientDB.solve.repair.sql.desc": "تنفيذ عبارة SQL مخصصة لإصلاح مشاكل قاعدة البيانات",
|
||||
"clientDB.solve.repair.sql.markFinished": "تحديد كمنتهية",
|
||||
"clientDB.solve.repair.sql.placeholder": "أدخل عبارة SQL...",
|
||||
"clientDB.solve.repair.sql.result": "نتيجة التنفيذ",
|
||||
"clientDB.solve.repair.sql.run": "تنفيذ",
|
||||
"clientDB.solve.repair.sql.title": "منفذ SQL",
|
||||
"clientDB.solve.repair.title": "التحكم في الترحيل",
|
||||
"clientDB.solve.repair.title": "تحكم النقل",
|
||||
"clientDB.solve.tabs.backup": "نسخ احتياطي واستعادة",
|
||||
"clientDB.solve.tabs.diagnosis": "تشخيص",
|
||||
"clientDB.solve.tabs.repair": "إصلاح",
|
||||
"close": "إغلاق",
|
||||
"cmdk.about": "حول",
|
||||
"cmdk.aiModeEmptyState": "اكتب سؤالك أعلاه لبدء الدردشة مع الذكاء الاصطناعي",
|
||||
"cmdk.aiModeHint": "اضغط Enter للسؤال",
|
||||
"cmdk.aiModePlaceholder": "اسأل الذكاء الاصطناعي عن أي شيء...",
|
||||
"cmdk.aiPainting": "فن الذكاء الاصطناعي",
|
||||
"cmdk.askAI": "اسأل الوكيل",
|
||||
"cmdk.askAIHeading": "استخدم الميزات التالية لـ {{query}}",
|
||||
"cmdk.askAIHeadingEmpty": "اختر ميزة ذكاء اصطناعي",
|
||||
"cmdk.aiModeEmptyState": "أدخل سؤالك في الحقل أعلاه لبدء المحادثة مع الذكاء الاصطناعي",
|
||||
"cmdk.aiModeHint": "اضغط Enter لطرح سؤال على Lobe AI",
|
||||
"cmdk.aiModePlaceholder": "اطرح سؤالاً على الذكاء الاصطناعي...",
|
||||
"cmdk.aiPainting": "الرسم بالذكاء الاصطناعي",
|
||||
"cmdk.askAI": "اسأل الذكاء الاصطناعي",
|
||||
"cmdk.askAIHeading": "استخدم الوظائف التالية لمعالجة {{query}}",
|
||||
"cmdk.askAIHeadingEmpty": "اختر وظيفة ذكاء اصطناعي",
|
||||
"cmdk.askLobeAI": "اسأل Lobe AI",
|
||||
"cmdk.community": "المجتمع",
|
||||
"cmdk.communitySupport": "دعم المجتمع",
|
||||
"cmdk.contactViaEmail": "اتصل بنا",
|
||||
"cmdk.context.agent": "وكيل",
|
||||
"cmdk.contactViaEmail": "اتصل بنا عبر البريد الإلكتروني",
|
||||
"cmdk.context.agent": "المساعد",
|
||||
"cmdk.context.community": "المجتمع",
|
||||
"cmdk.context.general": "عام",
|
||||
"cmdk.context.group": "مجموعة",
|
||||
"cmdk.context.group": "المجموعة",
|
||||
"cmdk.context.memory": "الذاكرة",
|
||||
"cmdk.context.page": "صفحة",
|
||||
"cmdk.context.painting": "رسم",
|
||||
"cmdk.context.resource": "مورد",
|
||||
"cmdk.context.page": "الوثيقة",
|
||||
"cmdk.context.painting": "الرسم",
|
||||
"cmdk.context.resource": "الموارد",
|
||||
"cmdk.context.settings": "الإعدادات",
|
||||
"cmdk.discover": "استكشاف",
|
||||
"cmdk.keyboard.ESC": "ESC",
|
||||
"cmdk.keyboard.Tab": "Tab",
|
||||
"cmdk.memory": "الذاكرة",
|
||||
"cmdk.navigate": "تنقل",
|
||||
"cmdk.newAgent": "إنشاء وكيل جديد",
|
||||
"cmdk.newAgentTeam": "إنشاء مجموعة جديدة",
|
||||
"cmdk.newLibrary": "مكتبة جديدة",
|
||||
"cmdk.newPage": "صفحة جديدة",
|
||||
"cmdk.newTopic": "موضوع جديد في الوكيل الحالي",
|
||||
"cmdk.navigate": "التنقل",
|
||||
"cmdk.newAgent": "إنشاء مساعد جديد",
|
||||
"cmdk.newAgentTeam": "إنشاء فريق مساعد جديد",
|
||||
"cmdk.newLibrary": "إنشاء مكتبة جديدة",
|
||||
"cmdk.newPage": "إنشاء مستند جديد",
|
||||
"cmdk.newTopic": "إنشاء موضوع جديد في المساعد الحالي",
|
||||
"cmdk.noResults": "لم يتم العثور على نتائج",
|
||||
"cmdk.openSettings": "فتح الإعدادات",
|
||||
"cmdk.pages": "الصفحات",
|
||||
"cmdk.pages": "المستندات",
|
||||
"cmdk.painting": "الرسم",
|
||||
"cmdk.resource": "الموارد",
|
||||
"cmdk.search.agent": "وكيل",
|
||||
"cmdk.search.agents": "وكلاء",
|
||||
"cmdk.search.assistant": "وكيل",
|
||||
"cmdk.search.assistants": "وكلاء",
|
||||
"cmdk.search.communityAgent": "وكيل المجتمع",
|
||||
"cmdk.search.agent": "مساعد",
|
||||
"cmdk.search.agents": "مساعدون",
|
||||
"cmdk.search.assistant": "مساعد الذكاء الاصطناعي",
|
||||
"cmdk.search.assistants": "مساعدو الذكاء الاصطناعي",
|
||||
"cmdk.search.communityAgent": "مساعد المجتمع",
|
||||
"cmdk.search.file": "ملف",
|
||||
"cmdk.search.files": "ملفات",
|
||||
"cmdk.search.loading": "يتم البحث...",
|
||||
"cmdk.search.loading": "جارٍ البحث...",
|
||||
"cmdk.search.market": "المجتمع",
|
||||
"cmdk.search.mcp": "خادم MCP",
|
||||
"cmdk.search.mcps": "خوادم MCP",
|
||||
"cmdk.search.message": "رسالة",
|
||||
"cmdk.search.messages": "رسائل",
|
||||
"cmdk.search.page": "صفحة",
|
||||
"cmdk.search.pages": "صفحات",
|
||||
"cmdk.search.plugin": "مهارة",
|
||||
"cmdk.search.plugins": "مهارات",
|
||||
"cmdk.search.message": "المحادثة",
|
||||
"cmdk.search.messages": "المحادثات",
|
||||
"cmdk.search.page": "المستند",
|
||||
"cmdk.search.pages": "المستندات",
|
||||
"cmdk.search.plugin": "الملحق",
|
||||
"cmdk.search.plugins": "الملحقات",
|
||||
"cmdk.search.searchMore": "البحث عن المزيد من {{type}}",
|
||||
"cmdk.search.searching": "نتائج البحث",
|
||||
"cmdk.search.topic": "موضوع",
|
||||
@@ -153,116 +153,95 @@
|
||||
"cmdk.starOnGitHub": "قيّمنا على GitHub",
|
||||
"cmdk.submitIssue": "إرسال مشكلة",
|
||||
"cmdk.theme": "السمة",
|
||||
"cmdk.themeAuto": "تلقائي",
|
||||
"cmdk.themeDark": "داكن",
|
||||
"cmdk.themeLight": "فاتح",
|
||||
"cmdk.themeAuto": "اتباع النظام",
|
||||
"cmdk.themeDark": "الوضع الداكن",
|
||||
"cmdk.themeLight": "الوضع الفاتح",
|
||||
"cmdk.toOpen": "فتح",
|
||||
"cmdk.toSelect": "تحديد",
|
||||
"confirm": "تأكيد",
|
||||
"contact": "اتصل بنا",
|
||||
"copy": "نسخ",
|
||||
"copyFail": "فشل النسخ",
|
||||
"copyFail": "فشل في النسخ",
|
||||
"copySuccess": "تم النسخ بنجاح",
|
||||
"dataStatistics.messages": "الرسائل",
|
||||
"dataStatistics.sessions": "الوكلاء",
|
||||
"dataStatistics.today": "الجديد اليوم",
|
||||
"dataStatistics.topics": "المواضيع",
|
||||
"defaultAgent": "وكيل مخصص",
|
||||
"defaultSession": "وكيل مخصص",
|
||||
"dataStatistics.messages": "رسائل",
|
||||
"dataStatistics.sessions": "جلسات",
|
||||
"dataStatistics.today": "اليوم",
|
||||
"dataStatistics.topics": "مواضيع",
|
||||
"defaultAgent": "مساعد افتراضي",
|
||||
"defaultSession": "جلسة افتراضية",
|
||||
"delete": "حذف",
|
||||
"document": "دليل المستخدم",
|
||||
"download": "تنزيل",
|
||||
"duplicate": "تكرار",
|
||||
"edit": "تعديل",
|
||||
"document": "وثيقة الاستخدام",
|
||||
"download": "تحميل",
|
||||
"duplicate": "إنشاء نسخة",
|
||||
"edit": "تحرير",
|
||||
"errors.invalidFileFormat": "تنسيق الملف غير صالح",
|
||||
"errors.unimplementedType": "نوع غير مدعوم. يرجى التحقق من المُخفض.",
|
||||
"errors.unimplementedType": "النوع غير مدعوم حالياً، يرجى التحقق من المُخفض",
|
||||
"export": "تصدير الإعدادات",
|
||||
"exportType.agent": "تصدير إعدادات الوكيل",
|
||||
"exportType.agentWithMessage": "تصدير الوكيل والرسائل",
|
||||
"exportType.all": "تصدير الإعدادات العامة وجميع بيانات الوكلاء",
|
||||
"exportType.allAgent": "تصدير جميع إعدادات الوكلاء",
|
||||
"exportType.allAgentWithMessage": "تصدير جميع الوكلاء والرسائل",
|
||||
"exportType.agent": "تصدير إعدادات المساعد",
|
||||
"exportType.agentWithMessage": "تصدير المساعد والرسائل",
|
||||
"exportType.all": "تصدير الإعدادات العامة وجميع بيانات المساعد",
|
||||
"exportType.allAgent": "تصدير جميع إعدادات المساعد",
|
||||
"exportType.allAgentWithMessage": "تصدير جميع المساعدين والرسائل",
|
||||
"exportType.globalSetting": "تصدير الإعدادات العامة",
|
||||
"feedback": "ملاحظات",
|
||||
"feedback.errors.fileTooLarge": "الملف يتجاوز الحجم المسموح به (5 ميغابايت)",
|
||||
"feedback.errors.submitFailed": "فشل في الإرسال. حاول مرة أخرى.",
|
||||
"feedback.errors.teamNotFound": "خطأ في التكوين",
|
||||
"feedback.errors.uploadFailed": "فشل في التحميل",
|
||||
"feedback.fields.message.label": "الرسالة",
|
||||
"feedback.fields.message.maxLength": "يجب ألا تتجاوز الرسالة 5000 حرف",
|
||||
"feedback.fields.message.placeholder": "أخبرنا بالمزيد...",
|
||||
"feedback.fields.message.required": "يرجى إدخال رسالة",
|
||||
"feedback.fields.screenshot.hint": "الحد الأقصى 5 ميغابايت. PNG، JPG، GIF",
|
||||
"feedback.fields.screenshot.label": "لقطة شاشة (اختياري)",
|
||||
"feedback.fields.screenshot.remove": "إزالة",
|
||||
"feedback.fields.screenshot.upload": "تحميل لقطة شاشة",
|
||||
"feedback.fields.screenshot.uploading": "جارٍ التحميل...",
|
||||
"feedback.fields.title.label": "العنوان",
|
||||
"feedback.fields.title.maxLength": "يجب ألا يتجاوز العنوان 200 حرف",
|
||||
"feedback.fields.title.placeholder": "ملخص موجز لسؤالك أو ملاحظاتك",
|
||||
"feedback.fields.title.required": "يرجى إدخال عنوان",
|
||||
"feedback.screenshotUploaded": "تم تحميل لقطة الشاشة",
|
||||
"feedback.submit": "إرسال الملاحظات",
|
||||
"feedback.success": "شكرًا لك! تم إرسال ملاحظاتك.",
|
||||
"feedback.title": "كيف يمكننا مساعدتك؟",
|
||||
"feedback": "تقديم ملاحظات",
|
||||
"follow": "تابعنا على {{name}}",
|
||||
"footer.action.feedback": "مشاركة الملاحظات",
|
||||
"footer.action.star": "قيّمنا على GitHub",
|
||||
"footer.action.feedback": "مشاركة ملاحظاتك الثمينة",
|
||||
"footer.action.star": "قم بإضافة نجمة على GitHub",
|
||||
"footer.and": "و",
|
||||
"footer.feedback.action": "مشاركة الملاحظات",
|
||||
"footer.feedback.desc": "أفكارك تساعدنا على تحسين {{appName}}. شاركنا اقتراحاتك أو ملاحظاتك حول تجربة الاستخدام وسنتولى الأمر.",
|
||||
"footer.feedback.title": "شارك ملاحظاتك على GitHub",
|
||||
"footer.feedback.desc": "كل فكرة ومقترح لديك ثمين بالنسبة لنا، نحن نتطلع بشوق لمعرفة آرائك! نرحب بالتواصل معنا لتقديم ملاحظاتك حول ميزات المنتج وتجربة الاستخدام، لمساعدتنا في تحسين LobeChat بشكل أفضل.",
|
||||
"footer.feedback.title": "مشاركة ملاحظاتك الثمينة على GitHub",
|
||||
"footer.later": "لاحقًا",
|
||||
"footer.star.action": "قيّمنا",
|
||||
"footer.star.desc": "إذا أعجبك {{appName}}، فإن تقييمك على GitHub يساعدنا كثيرًا. شكرًا لك.",
|
||||
"footer.star.title": "قيّمنا على GitHub",
|
||||
"footer.title": "هل أعجبك منتجنا؟",
|
||||
"fullscreen": "وضع ملء الشاشة",
|
||||
"footer.star.action": "قم بإضاءة النجمة",
|
||||
"footer.star.desc": "إذا كنت تحب منتجنا وترغب في دعمنا، هل يمكنك إضافة نجمة لنا على GitHub؟ هذا الإجراء الصغير له أهمية كبيرة بالنسبة لنا، حيث يمكن أن يلهمنا لتقديم تجربة ميزات مستمرة لك.",
|
||||
"footer.star.title": "قم بإضاءة النجمة لنا على GitHub",
|
||||
"footer.title": "هل تحب منتجنا؟",
|
||||
"fullscreen": "وضع كامل الشاشة",
|
||||
"geminiImageChineseWarning.content": "قد يفشل Nano Banana أحيانًا في إنشاء الصور عند استخدام اللغة الصينية. يُنصح باستخدام اللغة الإنجليزية للحصول على نتائج أفضل.",
|
||||
"geminiImageChineseWarning.continueGenerate": "متابعة التوليد",
|
||||
"geminiImageChineseWarning.continueGenerate": "متابعة الإنشاء",
|
||||
"geminiImageChineseWarning.continueSend": "متابعة الإرسال",
|
||||
"geminiImageChineseWarning.doNotShowAgain": "عدم الإظهار مرة أخرى",
|
||||
"geminiImageChineseWarning.title": "تنبيه إدخال باللغة الصينية",
|
||||
"historyRange": "نطاق السجل",
|
||||
"geminiImageChineseWarning.title": "تنبيه إدخال اللغة الصينية",
|
||||
"historyRange": "نطاق التاريخ",
|
||||
"import": "استيراد",
|
||||
"importData": "استيراد البيانات",
|
||||
"importModal.error.desc": "عذرًا، حدث خطأ أثناء عملية استيراد البيانات. يرجى المحاولة مرة أخرى، أو <1>إرسال طلب</1> وسنساعدك في حل المشكلة في أقرب وقت ممكن.",
|
||||
"importModal.error.desc": "عذرًا، حدث استثناء أثناء عملية استيراد البيانات. يرجى المحاولة مرة أخرى، أو <1>تقديم مشكلتك</1>، وسنقوم بمساعدتك على الفور في تحديد المشكلة.",
|
||||
"importModal.error.title": "فشل استيراد البيانات",
|
||||
"importModal.finish.onlySettings": "تم استيراد إعدادات النظام بنجاح",
|
||||
"importModal.finish.start": "ابدأ الاستخدام",
|
||||
"importModal.finish.subTitle": "تم استيراد البيانات بنجاح خلال {{duration}} ثانية. تفاصيل الاستيراد كالتالي:",
|
||||
"importModal.finish.title": "اكتمل استيراد البيانات",
|
||||
"importModal.loading": "جارٍ استيراد البيانات، يرجى الانتظار...",
|
||||
"importModal.preparing": "جارٍ تحضير وحدة استيراد البيانات...",
|
||||
"importModal.result.added": "تم الاستيراد بنجاح",
|
||||
"importModal.result.errors": "أخطاء في الاستيراد",
|
||||
"importModal.finish.subTitle": "تم استيراد البيانات بنجاح، وقت الاستيراد {{duration}} ثانية. تفاصيل الاستيراد كالتالي:",
|
||||
"importModal.finish.title": "اكتمال عملية الاستيراد",
|
||||
"importModal.loading": "جاري استيراد البيانات، يرجى الانتظار...",
|
||||
"importModal.preparing": "جاري تجهيز وحدة استيراد البيانات...",
|
||||
"importModal.result.added": "تمت الإضافة بنجاح",
|
||||
"importModal.result.errors": "حدثت أخطاء أثناء الاستيراد",
|
||||
"importModal.result.messages": "الرسائل",
|
||||
"importModal.result.sessionGroups": "المجموعات",
|
||||
"importModal.result.sessions": "الوكلاء",
|
||||
"importModal.result.skips": "تم تجاوز التكرارات",
|
||||
"importModal.result.sessionGroups": "مجموعات الجلسة",
|
||||
"importModal.result.sessions": "الجلسات",
|
||||
"importModal.result.skips": "التخطيات",
|
||||
"importModal.result.topics": "المواضيع",
|
||||
"importModal.result.type": "نوع البيانات",
|
||||
"importModal.result.update": "تم تحديث السجل",
|
||||
"importModal.result.update": "تحديث السجل",
|
||||
"importModal.title": "استيراد البيانات",
|
||||
"importModal.uploading.desc": "الملف الحالي كبير ويتم رفعه...",
|
||||
"importModal.uploading.desc": "الملف الحالي كبير نسبيًا، يتم رفعه بجد...",
|
||||
"importModal.uploading.restTime": "الوقت المتبقي",
|
||||
"importModal.uploading.speed": "سرعة الرفع",
|
||||
"importPreview.confirmImport": "تأكيد الاستيراد",
|
||||
"importPreview.hashLabel": "الهاش",
|
||||
"importPreview.tables.count": "عدد السجلات",
|
||||
"importPreview.tables.name": "اسم الجدول",
|
||||
"importPreview.title": "معاينة استيراد البيانات",
|
||||
"importPreview.totalRecords": "سيتم استيراد ما مجموعه {{count}} سجل",
|
||||
"importPreview.totalTables": "{{count}} جداول",
|
||||
"information": "المجتمع والأخبار",
|
||||
"importPreview.title": "معاينة بيانات الاستيراد",
|
||||
"importPreview.totalRecords": "إجمالي السجلات التي سيتم استيرادها {{count}}",
|
||||
"importPreview.totalTables": "{{count}} جدول",
|
||||
"information": "المجتمع والمعلومات",
|
||||
"installPWA": "تثبيت تطبيق المتصفح",
|
||||
"labs": "المختبرات",
|
||||
"lang.ar": "العربية",
|
||||
"lang.auto": "اتباع إعدادات لغة النظام",
|
||||
"lang.auto": "اتبع إعدادات لغة النظام",
|
||||
"lang.bg-BG": "البلغارية",
|
||||
"lang.bn": "البنغالية",
|
||||
"lang.cs-CZ": "التشيكية",
|
||||
"lang.da-DK": "الدانماركية",
|
||||
"lang.da-DK": "الدنماركية",
|
||||
"lang.de-DE": "الألمانية",
|
||||
"lang.el-GR": "اليونانية",
|
||||
"lang.en": "الإنجليزية",
|
||||
@@ -280,7 +259,7 @@
|
||||
"lang.nl-NL": "الهولندية",
|
||||
"lang.no-NO": "النرويجية",
|
||||
"lang.pl-PL": "البولندية",
|
||||
"lang.pt-BR": "البرتغالية (البرازيل)",
|
||||
"lang.pt-BR": "البرتغالية",
|
||||
"lang.pt-PT": "البرتغالية",
|
||||
"lang.ro-RO": "الرومانية",
|
||||
"lang.ru-RU": "الروسية",
|
||||
@@ -294,31 +273,31 @@
|
||||
"lang.zh": "الصينية المبسطة",
|
||||
"lang.zh-CN": "الصينية المبسطة",
|
||||
"lang.zh-TW": "الصينية التقليدية",
|
||||
"layoutInitializing": "جارٍ تحميل التخطيط...",
|
||||
"legal": "إخلاء المسؤولية القانونية",
|
||||
"loading": "جارٍ التحميل...",
|
||||
"mail.business": "تعاون تجاري",
|
||||
"mail.support": "دعم عبر البريد الإلكتروني",
|
||||
"layoutInitializing": "جاري تحميل التخطيط...",
|
||||
"legal": "بيان قانوني",
|
||||
"loading": "جارِ التحميل...",
|
||||
"mail.business": "شراكات تجارية",
|
||||
"mail.support": "الدعم عبر البريد الإلكتروني",
|
||||
"more": "المزيد",
|
||||
"navPanel.agent": "الوكيل",
|
||||
"navPanel.displayItems": "عناصر العرض",
|
||||
"navPanel.agent": "المساعد",
|
||||
"navPanel.displayItems": "عرض العناصر",
|
||||
"navPanel.library": "المكتبة",
|
||||
"navPanel.searchAgent": "بحث عن وكيل...",
|
||||
"navPanel.searchResultEmpty": "لم يتم العثور على نتائج",
|
||||
"navPanel.searchAgent": "بحث عن مساعد...",
|
||||
"navPanel.searchResultEmpty": "لا توجد نتائج بحث",
|
||||
"new": "جديد",
|
||||
"noContent": "لا يوجد محتوى",
|
||||
"oauth": "تسجيل الدخول الموحد",
|
||||
"noContent": "لا يوجد محتوى حالياً",
|
||||
"oauth": "تسجيل الدخول SSO",
|
||||
"officialSite": "الموقع الرسمي",
|
||||
"ok": "موافق",
|
||||
"or": "أو",
|
||||
"pageSizeItem": "{{count}} عنصر",
|
||||
"password": "كلمة المرور",
|
||||
"pin": "تثبيت",
|
||||
"pin": "تثبيت في الأعلى",
|
||||
"pinOff": "إلغاء التثبيت",
|
||||
"privacy": "سياسة الخصوصية",
|
||||
"regenerate": "إعادة التوليد",
|
||||
"regenerate": "إعادة توليد",
|
||||
"releaseNotes": "تفاصيل الإصدار",
|
||||
"rename": "إعادة التسمية",
|
||||
"rename": "إعادة تسمية",
|
||||
"reset": "إعادة تعيين",
|
||||
"retry": "إعادة المحاولة",
|
||||
"run": "تشغيل",
|
||||
@@ -328,65 +307,65 @@
|
||||
"share": "مشاركة",
|
||||
"stop": "إيقاف",
|
||||
"sync.actions.settings": "إعدادات المزامنة",
|
||||
"sync.actions.sync": "مزامنة الآن",
|
||||
"sync.actions.sync": "مزامنة فورية",
|
||||
"sync.awareness.current": "الجهاز الحالي",
|
||||
"sync.channel": "القناة",
|
||||
"sync.disabled.actions.enable": "تمكين المزامنة السحابية",
|
||||
"sync.disabled.actions.settings": "إعدادات المزامنة",
|
||||
"sync.disabled.desc": "يتم تخزين بيانات الجلسة الحالية فقط في هذا المتصفح. إذا كنت بحاجة إلى مزامنة البيانات عبر أجهزة متعددة، يرجى تهيئة وتمكين المزامنة السحابية.",
|
||||
"sync.disabled.title": "تم تعطيل مزامنة البيانات",
|
||||
"sync.disabled.actions.settings": "تكوين معلمات المزامنة",
|
||||
"sync.disabled.desc": "بيانات الجلسة الحالية تُخزن فقط في هذا المتصفح. إذا كنت بحاجة إلى مزامنة البيانات بين عدة أجهزة، يرجى تكوين وتمكين المزامنة السحابية.",
|
||||
"sync.disabled.title": "لم يتم تشغيل مزامنة البيانات",
|
||||
"sync.enabled.title": "مزامنة البيانات",
|
||||
"sync.status.connecting": "جارٍ الاتصال",
|
||||
"sync.status.disabled": "المزامنة معطلة",
|
||||
"sync.status.connecting": "جار الاتصال",
|
||||
"sync.status.disabled": "مزامنة غير مفعلة",
|
||||
"sync.status.ready": "متصل",
|
||||
"sync.status.synced": "تمت المزامنة",
|
||||
"sync.status.syncing": "جارٍ المزامنة",
|
||||
"sync.status.syncing": "جار المزامنة",
|
||||
"sync.status.unconnected": "فشل الاتصال",
|
||||
"sync.title": "حالة المزامنة",
|
||||
"sync.unconnected.tip": "فشل الاتصال بخادم الإشارة، ولا يمكن إنشاء قناة اتصال من نظير إلى نظير. يرجى التحقق من الشبكة والمحاولة مرة أخرى.",
|
||||
"tab.aiImage": "الرسومات",
|
||||
"sync.unconnected.tip": "فشل اتصال خادم الإشارة، لن يتمكن من إنشاء قناة اتصال نقطية، يرجى التحقق من الشبكة وإعادة المحاولة",
|
||||
"tab.aiImage": "رسم",
|
||||
"tab.audio": "الصوت",
|
||||
"tab.chat": "الدردشة",
|
||||
"tab.community": "المجتمع",
|
||||
"tab.discover": "اكتشف",
|
||||
"tab.files": "الملفات",
|
||||
"tab.home": "الرئيسية",
|
||||
"tab.knowledgeBase": "المكتبة",
|
||||
"tab.discover": "اكتشاف",
|
||||
"tab.files": "ملفات",
|
||||
"tab.home": "الصفحة الرئيسية",
|
||||
"tab.knowledgeBase": "مكتبة الموارد",
|
||||
"tab.me": "أنا",
|
||||
"tab.memory": "الذاكرة",
|
||||
"tab.pages": "الصفحات",
|
||||
"tab.pages": "المستندات",
|
||||
"tab.resource": "الموارد",
|
||||
"tab.search": "بحث",
|
||||
"tab.search": "البحث",
|
||||
"tab.setting": "الإعدادات",
|
||||
"tab.video": "الفيديو",
|
||||
"telemetry.allow": "السماح",
|
||||
"telemetry.deny": "رفض",
|
||||
"telemetry.desc": "نود جمع معلومات الاستخدام بشكل مجهول لمساعدتنا في تحسين {{appName}} وتقديم تجربة أفضل لك. يمكنك تعطيل هذا في أي وقت من خلال الإعدادات - حول.",
|
||||
"telemetry.learnMore": "اعرف المزيد",
|
||||
"telemetry.title": "ساعدنا في تحسين {{appName}}",
|
||||
"telemetry.desc": "نحن نأمل في الحصول على معلومات استخدامك بشكل مجهول لمساعدتنا في تحسين LobeChat وتوفير تجربة منتج أفضل لك. يمكنك إيقاف ذلك في أي وقت من \"الإعدادات\" - \"حول\".",
|
||||
"telemetry.learnMore": "معرفة المزيد",
|
||||
"telemetry.title": "مساعدة LobeChat في التحسن",
|
||||
"temp": "مؤقت",
|
||||
"terms": "شروط الخدمة",
|
||||
"unknownError": "خطأ غير معروف",
|
||||
"update": "تحديث",
|
||||
"updateAgent": "تحديث معلومات الوكيل",
|
||||
"upgradeVersion.action": "ترقية",
|
||||
"upgradeVersion.hasNew": "تحديث متوفر",
|
||||
"upgradeVersion.newVersion": "تحديث متوفر: {{version}}",
|
||||
"upgradeVersion.hasNew": "يوجد تحديث متاح",
|
||||
"upgradeVersion.newVersion": "هناك إصدار جديد متاح: {{version}}",
|
||||
"userPanel.anonymousNickName": "مستخدم مجهول",
|
||||
"userPanel.billing": "إدارة الفوترة",
|
||||
"userPanel.cloud": "تشغيل {{name}}",
|
||||
"userPanel.community": "المجتمع",
|
||||
"userPanel.billing": "إدارة الفواتير",
|
||||
"userPanel.cloud": "تجربة {{name}}",
|
||||
"userPanel.community": "نسخة المجتمع",
|
||||
"userPanel.data": "تخزين البيانات",
|
||||
"userPanel.defaultNickname": "مستخدم المجتمع",
|
||||
"userPanel.discord": "دعم المجتمع",
|
||||
"userPanel.docs": "الوثائق",
|
||||
"userPanel.email": "دعم البريد الإلكتروني",
|
||||
"userPanel.feedback": "اتصل بنا",
|
||||
"userPanel.defaultNickname": "مستخدم النسخة المجتمعية",
|
||||
"userPanel.discord": "الدعم المجتمعي",
|
||||
"userPanel.docs": "وثائق الاستخدام",
|
||||
"userPanel.email": "الدعم عبر البريد الإلكتروني",
|
||||
"userPanel.feedback": "تقديم ملاحظات واقتراحات",
|
||||
"userPanel.help": "مركز المساعدة",
|
||||
"userPanel.moveGuide": "تم نقل زر الإعدادات إلى هنا",
|
||||
"userPanel.plans": "خطط الاشتراك",
|
||||
"userPanel.profile": "الحساب",
|
||||
"userPanel.setting": "الإعدادات",
|
||||
"userPanel.usages": "إحصائيات الاستخدام",
|
||||
"userPanel.profile": "إدارة الحساب",
|
||||
"userPanel.setting": "إعدادات التطبيق",
|
||||
"userPanel.usages": "إحصاءات الاستخدام",
|
||||
"version": "الإصدار"
|
||||
}
|
||||
|
||||
+97
-92
@@ -1,26 +1,32 @@
|
||||
{
|
||||
"ArgsInput.addArgument": "إضافة وسيطة",
|
||||
"ArgsInput.argumentPlaceholder": "وسيطة {{index}}",
|
||||
"ArgsInput.enterFirstArgument": "أدخل الوسيطة الأولى...",
|
||||
"DragUpload.dragDesc": "اسحب الملفات وأفلتها هنا لتحميل صور متعددة.",
|
||||
"DragUpload.dragFileDesc": "اسحب الصور والملفات وأفلتها هنا لتحميل صور وملفات متعددة.",
|
||||
"ArgsInput.addArgument": "إضافة وسيط",
|
||||
"ArgsInput.argumentPlaceholder": "الوسيط {{index}}",
|
||||
"ArgsInput.enterFirstArgument": "أدخل الوسيط الأول...",
|
||||
"DragUpload.dragDesc": "اسحب الملفات هنا، يدعم تحميل عدة صور.",
|
||||
"DragUpload.dragFileDesc": "اسحب الصور والملفات هنا، يدعم تحميل عدة صور وملفات.",
|
||||
"DragUpload.dragFileTitle": "تحميل الملفات",
|
||||
"DragUpload.dragTitle": "تحميل الصور",
|
||||
"FileManager.actions.addToKnowledgeBase": "إضافة إلى المكتبة",
|
||||
"FileManager.actions.addToOtherKnowledgeBase": "إضافة إلى مكتبة أخرى",
|
||||
"FileManager.actions.batchChunking": "تجزئة جماعية",
|
||||
"FileManager.actions.chunking": "تجزئة",
|
||||
"FileManager.actions.chunkingTooltip": "تقسيم الملف إلى أجزاء نصية متعددة وتضمينها للبحث الدلالي والحوار مع الملف.",
|
||||
"FileManager.actions.chunkingUnsupported": "هذا الملف لا يدعم التجزئة.",
|
||||
"FileManager.actions.confirmDelete": "أنت على وشك حذف هذا الملف. لا يمكن استعادته بعد الحذف. يرجى تأكيد الإجراء.",
|
||||
"FileManager.actions.confirmDeleteFolder": "أنت على وشك حذف هذا المجلد وجميع محتوياته. لا يمكن التراجع عن هذا الإجراء. يرجى تأكيد القرار.",
|
||||
"FileManager.actions.confirmDeleteMultiFiles": "أنت على وشك حذف {{count}} ملفًا محددًا. لا يمكن استعادتها بعد الحذف. يرجى تأكيد الإجراء.",
|
||||
"FileManager.actions.confirmRemoveFromKnowledgeBase": "أنت على وشك إزالة {{count}} ملف(ات) من المكتبة. ستظل متاحة في جميع الملفات. يرجى التأكيد للمتابعة.",
|
||||
"EmojiPicker.delete": "حذف الصورة الرمزية",
|
||||
"EmojiPicker.draggerDesc": "انقر أو اسحب الصورة إلى هذه المنطقة للتحميل",
|
||||
"EmojiPicker.emoji": "رمز تعبيري",
|
||||
"EmojiPicker.fileTypeError": "يرجى تحميل ملف صورة صالح",
|
||||
"EmojiPicker.upload": "تحميل الصورة الرمزية",
|
||||
"EmojiPicker.uploadBtn": "قص وتحميل",
|
||||
"FileManager.actions.addToKnowledgeBase": "إضافة إلى قاعدة الموارد",
|
||||
"FileManager.actions.addToOtherKnowledgeBase": "إضافة إلى قاعدة موارد أخرى",
|
||||
"FileManager.actions.batchChunking": "تقسيم دفعي",
|
||||
"FileManager.actions.chunking": "تقسيم",
|
||||
"FileManager.actions.chunkingTooltip": "قم بتقسيم الملف إلى عدة كتل نصية وتحويلها إلى متجهات، يمكن استخدامها في البحث الدلالي والمحادثة حول الملفات",
|
||||
"FileManager.actions.chunkingUnsupported": "هذا الملف لا يدعم تقسيم الأجزاء",
|
||||
"FileManager.actions.confirmDelete": "سيتم حذف هذا الملف، ولن يمكن استعادته بعد الحذف، يرجى تأكيد العملية",
|
||||
"FileManager.actions.confirmDeleteFolder": "سيتم حذف هذا المجلد وجميع محتوياته، ولن يكون بالإمكان استعادته بعد الحذف. يرجى تأكيد العملية.",
|
||||
"FileManager.actions.confirmDeleteMultiFiles": "سيتم حذف {{count}} ملفًا محددًا، ولن يمكن استعادته بعد الحذف، يرجى تأكيد العملية",
|
||||
"FileManager.actions.confirmRemoveFromKnowledgeBase": "سيتم إزالة {{count}} ملفًا محددًا من قاعدة الموارد. بعد الإزالة، ستظل الملفات مرئية في جميع الملفات. يرجى تأكيد الإجراء.",
|
||||
"FileManager.actions.copyUrl": "نسخ الرابط",
|
||||
"FileManager.actions.copyUrlSuccess": "تم نسخ رابط الملف بنجاح.",
|
||||
"FileManager.actions.copyUrlSuccess": "تم نسخ عنوان الملف بنجاح",
|
||||
"FileManager.actions.createChunkingTask": "جارٍ التحضير...",
|
||||
"FileManager.actions.deleteSuccess": "تم حذف الملف بنجاح.",
|
||||
"FileManager.actions.downloading": "جارٍ تنزيل الملف...",
|
||||
"FileManager.actions.deleteSuccess": "تم حذف الملف بنجاح",
|
||||
"FileManager.actions.downloading": "جارٍ تحميل الملف...",
|
||||
"FileManager.actions.goBack": "العودة إلى الصفحة السابقة",
|
||||
"FileManager.actions.goForward": "الانتقال إلى الصفحة التالية",
|
||||
"FileManager.actions.goToParent": "الانتقال إلى المجلد الرئيسي",
|
||||
@@ -28,110 +34,109 @@
|
||||
"FileManager.actions.moveHere": "نقل إلى هنا",
|
||||
"FileManager.actions.moveSuccess": "تم نقل الملف بنجاح",
|
||||
"FileManager.actions.moveToFolder": "نقل إلى...",
|
||||
"FileManager.actions.moveToRoot": "نقل إلى الدليل الرئيسي",
|
||||
"FileManager.actions.moving": "جارٍ النقل...",
|
||||
"FileManager.actions.removeFromKnowledgeBase": "إزالة من المكتبة",
|
||||
"FileManager.actions.removeFromKnowledgeBaseSuccess": "تمت إزالة الملف بنجاح.",
|
||||
"FileManager.actions.moveToRoot": "نقل إلى الدليل الجذري",
|
||||
"FileManager.actions.removeFromKnowledgeBase": "إزالة من قاعدة الموارد",
|
||||
"FileManager.actions.removeFromKnowledgeBaseSuccess": "تمت إزالة الملف بنجاح",
|
||||
"FileManager.actions.rename": "إعادة التسمية",
|
||||
"FileManager.actions.renameError": "فشل في إعادة التسمية",
|
||||
"FileManager.actions.renameSuccess": "تمت إعادة التسمية بنجاح",
|
||||
"FileManager.bottom": "لقد وصلت إلى النهاية.",
|
||||
"FileManager.config.showFilesInKnowledgeBase": "عرض المحتوى في المكتبة",
|
||||
"FileManager.emptyStatus.actions.file": "تحميل ملف",
|
||||
"FileManager.emptyStatus.actions.folder": "تحميل مجلد",
|
||||
"FileManager.emptyStatus.actions.knowledgeBase": "إنشاء مكتبة",
|
||||
"FileManager.bottom": "لقد وصلت إلى النهاية",
|
||||
"FileManager.config.showFilesInKnowledgeBase": "عرض المحتوى في قاعدة الموارد",
|
||||
"FileManager.emptyStatus.actions.file": "رفع ملف",
|
||||
"FileManager.emptyStatus.actions.folder": "رفع مجلد",
|
||||
"FileManager.emptyStatus.actions.knowledgeBase": "إنشاء قاعدة موارد جديدة",
|
||||
"FileManager.emptyStatus.or": "أو",
|
||||
"FileManager.emptyStatus.title": "اسحب الملفات أو المجلدات إلى هنا",
|
||||
"FileManager.noFolders": "لا توجد مجلدات متاحة",
|
||||
"FileManager.emptyStatus.title": "قم بسحب الملف أو المجلد هنا",
|
||||
"FileManager.noFolders": "لا توجد مجلدات حالياً",
|
||||
"FileManager.sort.dateAdded": "تاريخ الإضافة",
|
||||
"FileManager.sort.name": "الاسم",
|
||||
"FileManager.sort.size": "الحجم",
|
||||
"FileManager.title.createdAt": "تاريخ الإنشاء",
|
||||
"FileManager.title.size": "الحجم",
|
||||
"FileManager.title.title": "الملف",
|
||||
"FileManager.total.fileCount": "الإجمالي {{count}} عنصر",
|
||||
"FileManager.total.selectedCount": "المحدد {{count}} عنصر",
|
||||
"FileManager.title.title": "ملف",
|
||||
"FileManager.total.fileCount": "إجمالي {{count}} عنصر",
|
||||
"FileManager.total.selectedCount": "تم تحديد {{count}} عنصر",
|
||||
"FileManager.view.list": "عرض القائمة",
|
||||
"FileManager.view.masonry": "عرض الشبكة",
|
||||
"FileParsingStatus.chunks.embeddingStatus.empty": "لم يتم تضمين جميع أجزاء النص، مما يجعل ميزة البحث الدلالي غير متاحة. لتحسين جودة البحث، يرجى تضمين أجزاء النص.",
|
||||
"FileParsingStatus.chunks.embeddingStatus.error": "فشل في التضمين",
|
||||
"FileParsingStatus.chunks.embeddingStatus.errorResult": "فشل في التوجيه الشعاعي، يرجى التحقق والمحاولة مرة أخرى. تفاصيل الخطأ:",
|
||||
"FileParsingStatus.chunks.embeddingStatus.processing": "جارٍ تضمين أجزاء النص، يرجى الانتظار.",
|
||||
"FileParsingStatus.chunks.embeddingStatus.success": "تم تضمين جميع أجزاء النص الحالية",
|
||||
"FileParsingStatus.chunks.embeddings": "التضمين",
|
||||
"FileParsingStatus.chunks.status.error": "فشل في التجزئة",
|
||||
"FileParsingStatus.chunks.status.errorResult": "فشل في التجزئة، يرجى التحقق والمحاولة مرة أخرى. تفاصيل الخطأ:",
|
||||
"FileParsingStatus.chunks.status.processing": "جارٍ التجزئة",
|
||||
"FileParsingStatus.chunks.status.processingTip": "الخادم يقوم بتقسيم أجزاء النص؛ إغلاق الصفحة لن يؤثر على تقدم التجزئة.",
|
||||
"GoBack.back": "رجوع",
|
||||
"FileParsingStatus.chunks.embeddingStatus.empty": "لم يتم تحويل كتل النص بالكامل إلى متجهات، مما سيؤدي إلى عدم توفر وظيفة البحث الدلالي، لتحسين جودة البحث، يرجى تحويل كتل النص إلى متجهات",
|
||||
"FileParsingStatus.chunks.embeddingStatus.error": "فشل في تحويل البيانات إلى متجهات",
|
||||
"FileParsingStatus.chunks.embeddingStatus.errorResult": "فشل في تحويل البيانات إلى متجهات، يرجى التحقق والمحاولة مرة أخرى. سبب الفشل:",
|
||||
"FileParsingStatus.chunks.embeddingStatus.processing": "يتم تحويل كتل النص إلى متجهات، يرجى الانتظار",
|
||||
"FileParsingStatus.chunks.embeddingStatus.success": "تم تحويل جميع كتل النص الحالية إلى متجهات",
|
||||
"FileParsingStatus.chunks.embeddings": "تحويل إلى متجهات",
|
||||
"FileParsingStatus.chunks.status.error": "فشل في التقسيم",
|
||||
"FileParsingStatus.chunks.status.errorResult": "فشل في التقسيم، يرجى التحقق والمحاولة مرة أخرى. سبب الفشل:",
|
||||
"FileParsingStatus.chunks.status.processing": "جارٍ التقسيم",
|
||||
"FileParsingStatus.chunks.status.processingTip": "الخادم يقوم بتقسيم كتل النص، إغلاق الصفحة لا يؤثر على تقدم التقسيم",
|
||||
"GoBack.back": "عودة",
|
||||
"HtmlPreview.actions.download": "تنزيل",
|
||||
"HtmlPreview.actions.preview": "معاينة",
|
||||
"HtmlPreview.iframeTitle": "معاينة HTML",
|
||||
"HtmlPreview.mode.code": "كود",
|
||||
"HtmlPreview.mode.code": "رمز",
|
||||
"HtmlPreview.mode.preview": "معاينة",
|
||||
"HtmlPreview.title": "معاينة HTML",
|
||||
"ImageUpload.actions.changeImage": "انقر لتغيير الصورة",
|
||||
"ImageUpload.actions.dropMultipleFiles": "تحميل ملفات متعددة غير مدعوم؛ سيتم استخدام الملف الأول فقط",
|
||||
"ImageUpload.actions.dropMultipleFiles": "لا يدعم تحميل ملفات متعددة في آن واحد، سيتم استخدام الملف الأول فقط",
|
||||
"ImageUpload.placeholder.primary": "إضافة صورة",
|
||||
"ImageUpload.placeholder.secondary": "انقر أو اسحب للتحميل",
|
||||
"KeyValueEditor.addButton": "إضافة صف",
|
||||
"ImageUpload.placeholder.secondary": "انقر أو اسحب للإرفاق",
|
||||
"KeyValueEditor.addButton": "إضافة صف جديد",
|
||||
"KeyValueEditor.deleteTooltip": "حذف",
|
||||
"KeyValueEditor.duplicateKeyError": "يجب أن يكون المفتاح فريدًا",
|
||||
"KeyValueEditor.duplicateKeyError": "يجب أن يكون اسم المفتاح فريدًا",
|
||||
"KeyValueEditor.keyPlaceholder": "المفتاح",
|
||||
"KeyValueEditor.valuePlaceholder": "القيمة",
|
||||
"LocalFile.action.open": "فتح",
|
||||
"LocalFile.action.showInFolder": "عرض في المجلد",
|
||||
"MaxTokenSlider.unlimited": "غير محدود",
|
||||
"ModelSelect.featureTag.custom": "نموذج مخصص، يدعم افتراضيًا استدعاء الوظائف والتعرف البصري. يرجى التحقق من توفر هذه القدرات حسب الحالة الفعلية.",
|
||||
"ModelSelect.featureTag.file": "يدعم هذا النموذج تحميل الملفات للقراءة والتعرف.",
|
||||
"ModelSelect.featureTag.functionCall": "يدعم هذا النموذج استدعاء الوظائف.",
|
||||
"ModelSelect.featureTag.imageOutput": "يدعم هذا النموذج توليد الصور.",
|
||||
"ModelSelect.featureTag.reasoning": "يدعم هذا النموذج التفكير العميق.",
|
||||
"ModelSelect.featureTag.search": "يدعم هذا النموذج البحث عبر الإنترنت.",
|
||||
"ModelSelect.featureTag.tokens": "يدعم هذا النموذج حتى {{tokens}} رمزًا في جلسة واحدة.",
|
||||
"ModelSelect.featureTag.video": "يدعم هذا النموذج التعرف على الفيديو",
|
||||
"ModelSelect.featureTag.vision": "يدعم هذا النموذج التعرف البصري.",
|
||||
"ModelSelect.removed": "النموذج غير موجود في القائمة. سيتم حذفه تلقائيًا إذا تم إلغاء تحديده.",
|
||||
"ModelSwitchPanel.emptyModel": "لا يوجد نموذج مفعل. يرجى الذهاب إلى الإعدادات لتفعيله.",
|
||||
"ModelSwitchPanel.emptyProvider": "لا يوجد مزود مفعل. يرجى الذهاب إلى الإعدادات لتفعيل أحدهم.",
|
||||
"ModelSwitchPanel.goToSettings": "الذهاب إلى الإعدادات",
|
||||
"ModelSwitchPanel.provider": "المزود",
|
||||
"ModelSwitchPanel.title": "النموذج",
|
||||
"MultiImagesUpload.actions.uploadMore": "انقر أو اسحب لتحميل المزيد",
|
||||
"MultiImagesUpload.modal.complete": "تم",
|
||||
"ModelSelect.featureTag.custom": "نموذج مخصص، الإعداد الافتراضي يدعم الاستدعاء الوظيفي والتعرف البصري، يرجى التحقق من قدرة النموذج على القيام بذلك بناءً على الحالة الفعلية",
|
||||
"ModelSelect.featureTag.file": "يدعم هذا النموذج قراءة وتعرف الملفات المرفوعة",
|
||||
"ModelSelect.featureTag.functionCall": "يدعم هذا النموذج استدعاء الوظائف",
|
||||
"ModelSelect.featureTag.imageOutput": "يدعم هذا النموذج إنشاء الصور",
|
||||
"ModelSelect.featureTag.reasoning": "يدعم هذا النموذج التفكير العميق",
|
||||
"ModelSelect.featureTag.search": "يدعم هذا النموذج البحث عبر الإنترنت",
|
||||
"ModelSelect.featureTag.tokens": "يدعم هذا النموذج حتى {{tokens}} رمزًا في جلسة واحدة",
|
||||
"ModelSelect.featureTag.video": "هذا النموذج يدعم التعرف على الفيديو",
|
||||
"ModelSelect.featureTag.vision": "يدعم هذا النموذج التعرف البصري",
|
||||
"ModelSelect.removed": "هذا النموذج لم يعد متوفر في القائمة، سيتم إزالته تلقائيًا إذا تم إلغاء تحديده",
|
||||
"ModelSwitchPanel.emptyModel": "لا توجد نماذج ممكن تمكينها، يرجى الانتقال إلى الإعدادات لتمكينها",
|
||||
"ModelSwitchPanel.emptyProvider": "لا توجد مزودات مفعلة، يرجى الذهاب إلى الإعدادات لتفعيلها",
|
||||
"ModelSwitchPanel.goToSettings": "اذهب إلى الإعدادات",
|
||||
"ModelSwitchPanel.provider": "مزود",
|
||||
"ModelSwitchPanel.title": "نموذج",
|
||||
"MultiImagesUpload.actions.uploadMore": "انقر أو اسحب لإضافة المزيد",
|
||||
"MultiImagesUpload.modal.complete": "اكتمل",
|
||||
"MultiImagesUpload.modal.newFileIndicator": "جديد",
|
||||
"MultiImagesUpload.modal.selectImageToPreview": "يرجى اختيار صورة للمعاينة",
|
||||
"MultiImagesUpload.modal.title": "إدارة الصور ({{count}})",
|
||||
"MultiImagesUpload.modal.upload": "تحميل الصور",
|
||||
"MultiImagesUpload.placeholder.primary": "انقر أو اسحب لتحميل الصور",
|
||||
"MultiImagesUpload.placeholder.secondary": "يدعم اختيار صور متعددة",
|
||||
"MultiImagesUpload.progress.uploadingWithCount": "{{completed}}/{{total}} تم تحميلها",
|
||||
"MultiImagesUpload.validation.fileSizeExceeded": "يتجاوز حجم الملف الحد الأقصى المسموح به",
|
||||
"MultiImagesUpload.validation.fileSizeExceededDetail": "{{fileName}} ({{actualSize}}) يتجاوز الحد الأقصى المسموح به وهو {{maxSize}}",
|
||||
"MultiImagesUpload.validation.fileSizeExceededMultiple": "{{count}} ملف(ات) تتجاوز الحد الأقصى المسموح به وهو {{maxSize}}: {{fileList}}",
|
||||
"MultiImagesUpload.validation.imageCountExceeded": "تم تجاوز الحد الأقصى لعدد الصور",
|
||||
"OllamaSetupGuide.action.close": "إغلاق النافذة",
|
||||
"MultiImagesUpload.placeholder.secondary": "يدعم اختيار عدة صور",
|
||||
"MultiImagesUpload.progress.uploadingWithCount": "تم تحميل {{completed}} من أصل {{total}}",
|
||||
"MultiImagesUpload.validation.fileSizeExceeded": "تجاوز حجم الملف الحد المسموح",
|
||||
"MultiImagesUpload.validation.fileSizeExceededDetail": "{{fileName}} ({{actualSize}}) يتجاوز الحد الأقصى للحجم {{maxSize}}",
|
||||
"MultiImagesUpload.validation.fileSizeExceededMultiple": "{{count}} ملفات تتجاوز الحد الأقصى للحجم {{maxSize}}: {{fileList}}",
|
||||
"MultiImagesUpload.validation.imageCountExceeded": "تجاوز عدد الصور الحد المسموح",
|
||||
"OllamaSetupGuide.action.close": "إغلاق الإشعار",
|
||||
"OllamaSetupGuide.action.start": "تم التثبيت",
|
||||
"OllamaSetupGuide.cors.description": "بسبب قيود أمان المتصفح، تحتاج إلى تكوين إعدادات الوصول عبر النطاقات ليعمل Ollama بشكل صحيح.",
|
||||
"OllamaSetupGuide.cors.linux.env": "أضف `Environment` ضمن قسم [Service]، وقم بتعيين متغير البيئة OLLAMA_ORIGINS:",
|
||||
"OllamaSetupGuide.cors.description": "بسبب قيود أمان المتصفح، تحتاج إلى تكوين CORS لـ Ollama لاستخدامه بشكل صحيح.",
|
||||
"OllamaSetupGuide.cors.linux.env": "أضف `Environment` تحت قسم [Service]، وأضف متغير البيئة OLLAMA_ORIGINS:",
|
||||
"OllamaSetupGuide.cors.linux.reboot": "أعد تحميل systemd وأعد تشغيل Ollama",
|
||||
"OllamaSetupGuide.cors.linux.systemd": "قم بتحرير خدمة ollama باستخدام systemd:",
|
||||
"OllamaSetupGuide.cors.macos": "يرجى فتح تطبيق 'Terminal'، ولصق الأمر التالي، ثم الضغط على Enter لتنفيذه.",
|
||||
"OllamaSetupGuide.cors.reboot": "يرجى إعادة تشغيل خدمة Ollama بعد الانتهاء من التنفيذ.",
|
||||
"OllamaSetupGuide.cors.title": "تكوين Ollama للوصول عبر النطاقات",
|
||||
"OllamaSetupGuide.cors.windows": "في Windows، انقر على 'لوحة التحكم' واذهب إلى تحرير متغيرات بيئة النظام. أنشئ متغير بيئة جديد باسم 'OLLAMA_ORIGINS' لحساب المستخدم الخاص بك، واجعل القيمة *، ثم انقر على 'موافق/تطبيق' للحفظ.",
|
||||
"OllamaSetupGuide.install.description": "يرجى التأكد من أنك قمت بتشغيل Ollama. إذا لم تقم بتنزيله بعد، يرجى زيارة الموقع الرسمي لـ<1>تحميله</1>.",
|
||||
"OllamaSetupGuide.install.docker": "إذا كنت تفضل استخدام Docker، فإن Ollama يوفر أيضًا صورة Docker رسمية يمكنك سحبها باستخدام الأمر التالي:",
|
||||
"OllamaSetupGuide.install.linux.command": "قم بالتثبيت باستخدام الأمر التالي:",
|
||||
"OllamaSetupGuide.install.linux.manual": "بدلاً من ذلك، يمكنك الرجوع إلى <1>دليل التثبيت اليدوي لنظام Linux</1>.",
|
||||
"OllamaSetupGuide.cors.linux.systemd": "استخدم systemd لتحرير خدمة ollama:",
|
||||
"OllamaSetupGuide.cors.macos": "يرجى فتح تطبيق «الطرفية» ولصق الأوامر التالية ثم الضغط على Enter للتنفيذ",
|
||||
"OllamaSetupGuide.cors.reboot": "يرجى إعادة تشغيل خدمة Ollama بعد الانتهاء من التنفيذ",
|
||||
"OllamaSetupGuide.cors.title": "تكوين Ollama للسماح بالوصول عبر النطاقات المتعددة",
|
||||
"OllamaSetupGuide.cors.windows": "على نظام Windows، انقر على «لوحة التحكم»، ثم انتقل إلى تحرير متغيرات البيئة للنظام. أنشئ متغير بيئة جديد باسم «OLLAMA_ORIGINS» لقائمة المستخدم الخاصة بك، وقيمته هي *، ثم انقر على «موافق/تطبيق» لحفظ التغييرات.",
|
||||
"OllamaSetupGuide.install.description": "يرجى التأكد من أنك قد قمت بتشغيل Ollama، إذا لم تقم بتنزيل Ollama، يرجى زيارة الموقع الرسمي <1>للتنزيل</1>",
|
||||
"OllamaSetupGuide.install.docker": "إذا كنت تفضل استخدام Docker، فإن Ollama يوفر أيضًا صورة Docker رسمية، يمكنك سحبها باستخدام الأمر التالي:",
|
||||
"OllamaSetupGuide.install.linux.command": "قم بتثبيت باستخدام الأمر التالي:",
|
||||
"OllamaSetupGuide.install.linux.manual": "أو يمكنك الرجوع إلى <1>دليل التثبيت اليدوي لنظام Linux</1> للتثبيت بنفسك.",
|
||||
"OllamaSetupGuide.install.title": "تثبيت وتشغيل تطبيق Ollama محليًا",
|
||||
"OllamaSetupGuide.install.windowsTab": "Windows (معاينة)",
|
||||
"Thinking.thinking": "تفكير عميق...",
|
||||
"Thinking.thought": "تم التفكير بعمق (في {{duration}} ثانية)",
|
||||
"Thinking.thoughtWithDuration": "تم التفكير بعمق",
|
||||
"devTools.cache.empty": "الذاكرة المؤقتة فارغة",
|
||||
"devTools.metadata.empty": "لا توجد بيانات وصفية متاحة",
|
||||
"knowledgeBase.empty.description": "أنشئ مكتبة لتنظيم وإدارة مواردك",
|
||||
"knowledgeBase.empty.search": "لم يتم العثور على مكتبة مطابقة",
|
||||
"knowledgeBase.empty.title": "لا توجد مكتبة متاحة"
|
||||
"OllamaSetupGuide.install.windowsTab": "Windows (نسخة المعاينة)",
|
||||
"Thinking.thinking": "في حالة تفكير عميق...",
|
||||
"Thinking.thought": "لقد فكرت بعمق (استغرق الأمر {{duration}} ثانية)",
|
||||
"Thinking.thoughtWithDuration": "لقد فكرت بعمق",
|
||||
"devTools.cache.empty": "ذاكرة التخزين المؤقت فارغة",
|
||||
"devTools.metadata.empty": "لا توجد بيانات وصفية حالياً",
|
||||
"knowledgeBase.empty.description": "أنشئ قاعدة موارد لتنظيم وإدارة ملفاتك",
|
||||
"knowledgeBase.empty.search": "لم يتم العثور على قاعدة موارد مطابقة",
|
||||
"knowledgeBase.empty.title": "لا توجد قواعد موارد حالياً"
|
||||
}
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
{
|
||||
"authResult.failed.desc": "يرجى المحاولة مرة أخرى أو التبديل إلى طريقة تسجيل دخول مختلفة",
|
||||
"authResult.failed.title": "فشل التفويض",
|
||||
"authResult.success.desc": "يرجى النقر على زر البدء أدناه لمتابعة استخدام LobeHub Desktop",
|
||||
"authResult.success.title": "تم التفويض بنجاح",
|
||||
"back": "رجوع",
|
||||
"navigation.next": "متابعة",
|
||||
"next": "التالي",
|
||||
"screen1.description": "منصة إنتاجية مدعومة بالذكاء الاصطناعي مع وكلاء ذكيين",
|
||||
"screen1.navigation.next": "ابدأ الإعداد",
|
||||
"screen1.slogan.line1": "مصمم من أجلك",
|
||||
"screen1.slogan.line2": "الفرد الخارق",
|
||||
"screen2.badge": "الميزات",
|
||||
"screen2.description": "قدرات ذكاء اصطناعي متقدمة مصممة لتناسب سير عملك",
|
||||
"screen2.features.1.subtitle": "توليد الصور",
|
||||
"screen2.features.1.title": "أنشئ ما تشعر به",
|
||||
"screen2.features.2.subtitle": "سوق MCP",
|
||||
"screen2.features.2.title": "اكتشف، تواصل، ووسّع",
|
||||
"screen2.features.3.subtitle": "بحث ذكي على الويب",
|
||||
"screen2.features.3.title": "معرفة العالم جاهزة",
|
||||
"screen2.features.4.subtitle": "مزامنة عبر الأنظمة",
|
||||
"screen2.features.4.title": "مساحة عملك، في أي مكان",
|
||||
"screen2.features.5.subtitle": "القطع الفنية",
|
||||
"screen2.features.5.title": "الذكاء الاصطناعي يلتقي الإبداع البصري",
|
||||
"screen2.features.6.subtitle": "مزودو ذكاء اصطناعي متعددون",
|
||||
"screen2.features.6.title": "منصة واحدة، جميع النماذج",
|
||||
"screen2.title": "كل ما تحتاجه",
|
||||
"screen3.actions.grantAccess": "منح الإذن",
|
||||
"screen3.actions.granted": "تم منح الإذن",
|
||||
"screen3.actions.openSettings": "فتح الإعدادات",
|
||||
"screen3.badge": "الأذونات",
|
||||
"screen3.description": "امنح الأذونات لفتح الإمكانات الكاملة للوكلاء والمجموعات. يمكنك إدارة هذه الأذونات في أي وقت من الإعدادات.",
|
||||
"screen3.permissions.1.description": "تلقي الإشعارات عند اكتمال المهام، أو استجابة الوكلاء، أو وصول التحديثات المهمة",
|
||||
"screen3.permissions.1.title": "الإشعارات",
|
||||
"screen3.permissions.2.description": "الوصول إلى الملفات والمجلدات لتمكين تحليل المستندات، وإنشاء قواعد المعرفة، وسير عمل معالجة الملفات",
|
||||
"screen3.permissions.2.title": "الوصول إلى الملفات",
|
||||
"screen3.permissions.3.description": "التقاط محتوى الشاشة والصوت للتفاعل الصوتي، وتحليل الشاشة، والمساعدة متعددة الوسائط",
|
||||
"screen3.permissions.3.title": "الشاشة والصوت",
|
||||
"screen3.permissions.4.description": "تمكين الأتمتة على مستوى النظام لتنفيذ سير العمل بسلاسة عبر التطبيقات",
|
||||
"screen3.permissions.4.title": "إمكانية الوصول",
|
||||
"screen3.title": "منح الأذونات",
|
||||
"screen3.title2": "فعّل الوصول لفتح جميع الميزات",
|
||||
"screen3.title3": "يمكنك إدارة هذه الأذونات في أي وقت من الإعدادات",
|
||||
"screen4.badge": "الخصوصية",
|
||||
"screen4.description": "اختر كيف تريد مشاركة البيانات. يساعدنا اختيارك على التحسين، ويمكنك تغيير ذلك في أي وقت من الإعدادات.",
|
||||
"screen4.footerNote": "يمكنك تغيير ذلك في أي وقت من الإعدادات",
|
||||
"screen4.navigation.next": "متابعة",
|
||||
"screen4.privacy.description": "احتفظ بكل شيء محليًا. لا يتم جمع أو مشاركة أي بيانات — خصوصية كاملة لمحادثاتك وسير عملك.",
|
||||
"screen4.privacy.items.1": "لا جمع للبيانات",
|
||||
"screen4.privacy.items.2": "لا تحليلات استخدام",
|
||||
"screen4.privacy.items.3": "جميع المعالجة تتم محليًا",
|
||||
"screen4.privacy.title": "وضع الخصوصية",
|
||||
"screen4.share.description": "شارك بيانات استخدام مجهولة المصدر لمساعدتنا في تحسين LobeHub. يساعدنا ذلك على فهم كيفية استخدام الوكلاء وتحسينهم.",
|
||||
"screen4.share.items.1": "مقاييس الأداء",
|
||||
"screen4.share.items.2": "أنماط استخدام النماذج",
|
||||
"screen4.share.items.3": "تفاعلات الميزات",
|
||||
"screen4.share.title": "ساعد في تحسين LobeHub",
|
||||
"screen4.title": "كيف تود مشاركة البيانات؟",
|
||||
"screen4.title2": "اختيارك يساعدنا على التحسين",
|
||||
"screen4.title3": "يمكنك تغيير ذلك في أي وقت من الإعدادات",
|
||||
"screen5.actions.connectToServer": "الاتصال بالخادم",
|
||||
"screen5.actions.connecting": "جارٍ الاتصال...",
|
||||
"screen5.actions.signInCloud": "تسجيل الدخول إلى LobeHub Cloud",
|
||||
"screen5.actions.signOut": "تسجيل الخروج",
|
||||
"screen5.actions.signingIn": "جارٍ تسجيل الدخول...",
|
||||
"screen5.actions.signingOut": "جارٍ تسجيل الخروج...",
|
||||
"screen5.actions.tryAgain": "حاول مرة أخرى",
|
||||
"screen5.badge": "تسجيل الدخول",
|
||||
"screen5.description": "سجّل الدخول لمزامنة الوكلاء والمجموعات والإعدادات والسياق عبر جميع الأجهزة.",
|
||||
"screen5.errors.desktopOnlyOidc": "تفويض OIDC متاح فقط في تطبيق سطح المكتب.",
|
||||
"screen5.methods.cloud.description": "سجّل الدخول باستخدام حساب LobeHub Cloud الخاص بك لمزامنة كل شيء بسلاسة",
|
||||
"screen5.methods.cloud.name": "LobeHub Cloud",
|
||||
"screen5.methods.selfhost.description": "اتصل بنسختك الخاصة من خادم LobeHub",
|
||||
"screen5.methods.selfhost.name": "نسخة مستضافة ذاتيًا",
|
||||
"screen5.navigation.next": "ابدأ الآن",
|
||||
"screen5.selfhost.endpointPlaceholder": "أدخل عنوان خادمك (مثال: https://your-server.com)",
|
||||
"screen5.title": "سجّل الدخول للمزامنة عبر الأجهزة",
|
||||
"screen5.title2": "احتفظ ببياناتك متزامنة في كل مكان",
|
||||
"screen5.title3": "بياناتك تحت سيطرتك دائمًا"
|
||||
}
|
||||
+296
-296
@@ -1,214 +1,214 @@
|
||||
{
|
||||
"assistant.favorite": "حفظ",
|
||||
"assistant.favoriteFailed": "فشل في الحفظ",
|
||||
"assistant.favoriteSuccess": "تم الحفظ",
|
||||
"assistant.favorite": "إضافة إلى المفضلة",
|
||||
"assistant.favoriteFailed": "فشل في الإضافة إلى المفضلة",
|
||||
"assistant.favoriteSuccess": "تمت الإضافة إلى المفضلة",
|
||||
"assistant.like": "إعجاب",
|
||||
"assistant.likeFailed": "فشل في الإعجاب",
|
||||
"assistant.likeSuccess": "تم الإعجاب",
|
||||
"assistant.unfavorite": "إلغاء الحفظ",
|
||||
"assistant.unfavoriteFailed": "فشل في إلغاء الحفظ",
|
||||
"assistant.unfavoriteSuccess": "تم إلغاء الحفظ",
|
||||
"assistant.unfavorite": "إزالة من المفضلة",
|
||||
"assistant.unfavoriteFailed": "فشل في الإزالة من المفضلة",
|
||||
"assistant.unfavoriteSuccess": "تمت الإزالة من المفضلة",
|
||||
"assistant.unlike": "إلغاء الإعجاب",
|
||||
"assistant.unlikeSuccess": "تم إلغاء الإعجاب",
|
||||
"assistants.addAgent": "إضافة وكيل",
|
||||
"assistants.addAgentAndConverse": "إضافة وكيل والدردشة",
|
||||
"assistants.addAgentSuccess": "تمت الإضافة",
|
||||
"assistants.conversation.l1": "مرحبًا، أنا **{{name}}**. شاركني هدفك أو السياق وسنتعاون من هنا.",
|
||||
"assistants.conversation.l2": "إليك ما يمكنني فعله:",
|
||||
"assistants.conversation.l3": "ابدأ المحادثة",
|
||||
"assistants.description": "حول هذا الوكيل",
|
||||
"assistants.addAgent": "إضافة مساعد",
|
||||
"assistants.addAgentAndConverse": "إضافة مساعد والدردشة",
|
||||
"assistants.addAgentSuccess": "تمت الإضافة بنجاح",
|
||||
"assistants.conversation.l1": "مرحبًا، أنا **{{name}}**، يمكنك أن تسألني أي سؤال وسأبذل قصارى جهدي للإجابة ~",
|
||||
"assistants.conversation.l2": "إليك مقدمة عن قدراتي: ",
|
||||
"assistants.conversation.l3": "لنبدأ المحادثة!",
|
||||
"assistants.description": "مقدمة المساعد",
|
||||
"assistants.detail": "تفاصيل",
|
||||
"assistants.details.capabilities.knowledge.desc": "يتضمن هذا الوكيل المكتبات التالية للمساعدة في الإجابة على المزيد من الأسئلة.",
|
||||
"assistants.details.capabilities.knowledge.title": "المكتبة",
|
||||
"assistants.details.capabilities.plugin.desc": "يتضمن هذا الوكيل المهارات التالية لمساعدتك في إنجاز المزيد من المهام.",
|
||||
"assistants.details.capabilities.plugin.title": "المهارات المدمجة",
|
||||
"assistants.details.capabilities.title": "قدرات الوكيل",
|
||||
"assistants.details.overview.example": "عرض توضيحي للوكيل",
|
||||
"assistants.details.capabilities.knowledge.desc": "يحتوي المساعد على مكتبات معرفية مدمجة لمساعدتك في الإجابة على المزيد من الأسئلة.",
|
||||
"assistants.details.capabilities.knowledge.title": "المكتبات المعرفية",
|
||||
"assistants.details.capabilities.plugin.desc": "المساعد مزود بالإضافة التالية لمساعدتك في إتمام المزيد من المهام.",
|
||||
"assistants.details.capabilities.plugin.title": "الإضافات المدمجة",
|
||||
"assistants.details.capabilities.title": "قدرات المساعد",
|
||||
"assistants.details.overview.example": "عرض المساعد",
|
||||
"assistants.details.overview.title": "نظرة عامة",
|
||||
"assistants.details.related.listTitle": "وكلاء ذوو صلة",
|
||||
"assistants.details.related.listTitle": "المساعدون المرتبطون",
|
||||
"assistants.details.related.more": "عرض المزيد",
|
||||
"assistants.details.related.title": "وكلاء مشابهون",
|
||||
"assistants.details.sidebar.toc": "جدول المحتويات",
|
||||
"assistants.details.summary.title": "ما الذي يمكنك فعله باستخدام هذا الوكيل؟",
|
||||
"assistants.details.systemRole.openingMessage": "رسالة الترحيب",
|
||||
"assistants.details.systemRole.openingQuestions": "أسئلة البداية",
|
||||
"assistants.details.systemRole.title": "ملف تعريف الوكيل",
|
||||
"assistants.details.version.empty": "لا توجد إصدارات سابقة بعد",
|
||||
"assistants.details.related.title": "اقتراحات ذات صلة",
|
||||
"assistants.details.sidebar.toc": "المحتوى",
|
||||
"assistants.details.summary.title": "ما الذي يمكنك فعله باستخدام هذا المساعد؟",
|
||||
"assistants.details.systemRole.openingMessage": "رسالة الافتتاح",
|
||||
"assistants.details.systemRole.openingQuestions": "أسئلة الافتتاح",
|
||||
"assistants.details.systemRole.title": "إعدادات المساعد",
|
||||
"assistants.details.version.empty": "لا توجد إصدارات سابقة",
|
||||
"assistants.details.version.status.archived": "مؤرشف",
|
||||
"assistants.details.version.status.deprecated": "مرفوض",
|
||||
"assistants.details.version.status.unpublished": "قيد المراجعة",
|
||||
"assistants.details.version.table.isLatest": "أحدث إصدار",
|
||||
"assistants.details.version.table.isValidated": "تم التحقق منه",
|
||||
"assistants.details.version.table.publishAt": "تاريخ النشر",
|
||||
"assistants.details.version.table.version": "الإصدار",
|
||||
"assistants.details.version.table.version": "رقم الإصدار",
|
||||
"assistants.details.version.title": "سجل الإصدارات",
|
||||
"assistants.downloads": "التنزيلات",
|
||||
"assistants.duplicateAdd.content": "“{{title}}” موجود بالفعل في وكلائك. هل ترغب في إضافة نسخة أخرى؟",
|
||||
"assistants.duplicateAdd.ok": "إضافة نسخة",
|
||||
"assistants.duplicateAdd.title": "إضافة نسخة مكررة؟",
|
||||
"assistants.empty.description": "حاول تعديل الفلاتر، أو استكشف المزيد من الوكلاء في المجتمع.",
|
||||
"assistants.empty.search": "لم يتم العثور على وكلاء مطابقين",
|
||||
"assistants.empty.title": "لم يتم العثور على وكلاء",
|
||||
"assistants.list": "قائمة الوكلاء",
|
||||
"assistants.downloads": "عدد التنزيلات",
|
||||
"assistants.duplicateAdd.content": "لقد قمت بإضافة المساعد «{{title}}» مسبقًا، هل ترغب في إضافته مرة أخرى؟",
|
||||
"assistants.duplicateAdd.ok": "تأكيد الإضافة",
|
||||
"assistants.duplicateAdd.title": "تأكيد الإضافة المكررة",
|
||||
"assistants.empty.description": "حاول تعديل معايير التصفية أو زيارة المجتمع لاكتشاف المزيد من المساعدين",
|
||||
"assistants.empty.search": "لم يتم العثور على مساعدين مطابقين",
|
||||
"assistants.empty.title": "لا يوجد مساعدين حالياً",
|
||||
"assistants.list": "قائمة المساعدين",
|
||||
"assistants.marketSource.label": "تبديل مصدر المجتمع",
|
||||
"assistants.marketSource.legacy": "المجتمع القديم",
|
||||
"assistants.marketSource.new": "المجتمع الجديد",
|
||||
"assistants.more": "المزيد",
|
||||
"assistants.plugins": "المهارات المدمجة",
|
||||
"assistants.recentSubmits": "التحديثات الأخيرة",
|
||||
"assistants.sorts.createdAt": "تم النشر مؤخرًا",
|
||||
"assistants.sorts.identifier": "معرّف الوكيل",
|
||||
"assistants.sorts.knowledgeCount": "عدد المكتبات",
|
||||
"assistants.sorts.myown": "عرض وكلائي",
|
||||
"assistants.sorts.pluginCount": "عدد المهارات",
|
||||
"assistants.sorts.title": "اسم الوكيل",
|
||||
"assistants.sorts.tokenUsage": "استخدام الرموز",
|
||||
"assistants.status.archived.reasons.official": "قامت المنصة بإزالة هذا الوكيل لأسباب تتعلق بالأمان أو السياسات أو غيرها.",
|
||||
"assistants.status.archived.reasons.owner": "قام المنشئ بأرشفة أو إزالة هذا الوكيل.",
|
||||
"assistants.status.archived.subtitle": "تمت أرشفة هذا الوكيل. الأسباب المحتملة:",
|
||||
"assistants.status.archived.title": "تمت أرشفة الوكيل",
|
||||
"assistants.status.backToMarket": "العودة إلى مجتمع الوكلاء",
|
||||
"assistants.status.deprecated.reasons.official": "قامت المنصة بإزالة هذا الوكيل لأسباب تتعلق بالأمان أو السياسات أو غيرها.",
|
||||
"assistants.status.deprecated.reasons.owner": "قام المنشئ برفض أو إزالة هذا الوكيل.",
|
||||
"assistants.status.deprecated.subtitle": "هذا الوكيل غير متاح حاليًا. الأسباب المحتملة:",
|
||||
"assistants.status.deprecated.title": "الوكيل غير متاح",
|
||||
"assistants.status.support": "لأي استفسارات، يرجى نسخ الرابط وإرساله إلى <email>support@lobehub.com</email> للحصول على المساعدة.",
|
||||
"assistants.status.unpublished.subtitle": "هذا الوكيل قيد المراجعة. لتأكيد حالته، انسخ الرابط وأرسله إلى <email>support@lobehub.com</email>.",
|
||||
"assistants.status.unpublished.title": "الوكيل قيد المراجعة",
|
||||
"assistants.suggestions": "وكلاء مشابهون",
|
||||
"assistants.systemRole": "ملف تعريف الوكيل",
|
||||
"assistants.tokenUsage": "استخدام رموز الوكيل",
|
||||
"assistants.try": "جرّب",
|
||||
"assistants.withKnowledge": "يتضمن هذا الوكيل مكتبات",
|
||||
"assistants.withPlugin": "يتضمن هذا الوكيل مهارات",
|
||||
"back": "العودة إلى الاكتشاف",
|
||||
"assistants.plugins": "دمج الإضافات",
|
||||
"assistants.recentSubmits": "آخر التحديثات",
|
||||
"assistants.sorts.createdAt": "تم النشر مؤخراً",
|
||||
"assistants.sorts.identifier": "معرف المساعد",
|
||||
"assistants.sorts.knowledgeCount": "عدد المكتبات المعرفية",
|
||||
"assistants.sorts.myown": "عرض مساعدي",
|
||||
"assistants.sorts.pluginCount": "عدد الإضافات",
|
||||
"assistants.sorts.title": "اسم المساعد",
|
||||
"assistants.sorts.tokenUsage": "استهلاك التوكن",
|
||||
"assistants.status.archived.reasons.official": "تمت إزالة المساعد من قبل الإدارة لأسباب أمنية أو سياسية",
|
||||
"assistants.status.archived.reasons.owner": "قام مالك المساعد بإزالته أو أرشفته طوعًا",
|
||||
"assistants.status.archived.subtitle": "المساعد الذي تحاول الوصول إليه تم أرشفته للأسباب التالية المحتملة:",
|
||||
"assistants.status.archived.title": "تم أرشفة المساعد",
|
||||
"assistants.status.backToMarket": "العودة إلى مجتمع المساعد",
|
||||
"assistants.status.deprecated.reasons.official": "تمت إزالة المساعد من قبل الإدارة لأسباب أمنية أو سياسية",
|
||||
"assistants.status.deprecated.reasons.owner": "قام مالك المساعد بإزالته أو رفضه طوعًا",
|
||||
"assistants.status.deprecated.subtitle": "المساعد الذي تحاول الوصول إليه تم رفضه للأسباب التالية المحتملة:",
|
||||
"assistants.status.deprecated.title": "تم رفض المساعد",
|
||||
"assistants.status.support": "لأي استفسارات، يرجى نسخ الرابط وإرساله إلى <email>support@lobehub.com</email>.",
|
||||
"assistants.status.unpublished.subtitle": "المساعد الذي تحاول الوصول إليه يخضع حاليًا لمراجعة الإصدار. إذا كان لديك أي استفسار، يرجى نسخ الرابط وإرساله إلى <email>support@lobehub.com</email>.",
|
||||
"assistants.status.unpublished.title": "المساعد قيد المراجعة",
|
||||
"assistants.suggestions": "اقتراحات ذات صلة",
|
||||
"assistants.systemRole": "إعدادات المساعد",
|
||||
"assistants.tokenUsage": "استهلاك توكنات تعليمات المساعد",
|
||||
"assistants.try": "جرب",
|
||||
"assistants.withKnowledge": "هذا المساعد مزود بمكتبات معرفية",
|
||||
"assistants.withPlugin": "هذا المساعد مزود بالإضافة",
|
||||
"back": "عودة إلى الاكتشاف",
|
||||
"category.assistant.academic": "أكاديمي",
|
||||
"category.assistant.all": "الكل",
|
||||
"category.assistant.career": "المسار المهني",
|
||||
"category.assistant.copywriting": "كتابة المحتوى",
|
||||
"category.assistant.career": "مهنة",
|
||||
"category.assistant.copywriting": "كتابة نصوص",
|
||||
"category.assistant.design": "تصميم",
|
||||
"category.assistant.education": "تعليم",
|
||||
"category.assistant.emotions": "العواطف",
|
||||
"category.assistant.emotions": "عواطف",
|
||||
"category.assistant.entertainment": "ترفيه",
|
||||
"category.assistant.games": "ألعاب",
|
||||
"category.assistant.general": "عام",
|
||||
"category.assistant.life": "الحياة",
|
||||
"category.assistant.life": "حياة",
|
||||
"category.assistant.marketing": "تسويق",
|
||||
"category.assistant.office": "مكتب",
|
||||
"category.assistant.programming": "برمجة",
|
||||
"category.assistant.translation": "ترجمة",
|
||||
"category.plugin.all": "الكل",
|
||||
"category.plugin.gaming-entertainment": "الألعاب والترفيه",
|
||||
"category.plugin.life-style": "نمط الحياة",
|
||||
"category.plugin.gaming-entertainment": "ألعاب وترفيه",
|
||||
"category.plugin.life-style": "أسلوب حياة",
|
||||
"category.plugin.lifestyle": "نمط الحياة",
|
||||
"category.plugin.media-generate": "إنشاء الوسائط",
|
||||
"category.plugin.science-education": "العلم والتعليم",
|
||||
"category.plugin.media-generate": "توليد الوسائط",
|
||||
"category.plugin.science-education": "علوم وتعليم",
|
||||
"category.plugin.social": "وسائل التواصل الاجتماعي",
|
||||
"category.plugin.stocks-finance": "الأسهم والتمويل",
|
||||
"category.plugin.tools": "أدوات مساعدة",
|
||||
"category.plugin.web-search": "البحث على الويب",
|
||||
"cleanFilter": "مسح الفلاتر",
|
||||
"category.plugin.stocks-finance": "أسواق مالية",
|
||||
"category.plugin.tools": "أدوات عملية",
|
||||
"category.plugin.web-search": "بحث على الويب",
|
||||
"cleanFilter": "مسح الفلتر",
|
||||
"create": "إنشاء",
|
||||
"createGuide.func1.desc1": "في المحادثة، افتح إعدادات الوكيل من القائمة في الزاوية العلوية اليمنى.",
|
||||
"createGuide.func1.desc2": "ثم انقر على إرسال إلى مجتمع الوكلاء في الزاوية العلوية اليمنى.",
|
||||
"createGuide.func1.tag": "الخيار 1",
|
||||
"createGuide.func1.title": "الإرسال في LobeHub",
|
||||
"createGuide.func2.button": "افتح مستودع وكيل GitHub",
|
||||
"createGuide.func2.desc": "لإضافة وكيل إلى الفهرس، أنشئ إدخالًا في `plugins/` باستخدام `agent-template.json` أو `agent-template-full.json`، أضف وصفًا قصيرًا وعلامات، ثم افتح طلب سحب.",
|
||||
"createGuide.func2.tag": "الخيار 2",
|
||||
"createGuide.func2.title": "الإرسال على GitHub",
|
||||
"dislike": "عدم الإعجاب",
|
||||
"createGuide.func1.desc1": "ادخل إلى صفحة إعداد المساعد الذي ترغب في تقديمه من خلال الإعدادات في الزاوية العليا اليمنى من نافذة المحادثة;",
|
||||
"createGuide.func1.desc2": "انقر على زر الإرسال إلى مجتمع المساعد في الزاوية اليمنى العليا.",
|
||||
"createGuide.func1.tag": "الطريقة الأولى",
|
||||
"createGuide.func1.title": "تقديم عبر LobeChat",
|
||||
"createGuide.func2.button": "اذهب إلى مستودع مساعدي Github",
|
||||
"createGuide.func2.desc": "إذا كنت ترغب في إضافة مساعد إلى الفهرس، يرجى استخدام agent-template.json أو agent-template-full.json لإنشاء إدخال في دليل الإضافات، كتابة وصف قصير ووضع علامات مناسبة، ثم إنشاء طلب سحب.",
|
||||
"createGuide.func2.tag": "الطريقة الثانية",
|
||||
"createGuide.func2.title": "تقديم عبر Github",
|
||||
"dislike": "لا يعجبني",
|
||||
"filter": "تصفية",
|
||||
"filterBy.authorRange.everyone": "جميع المؤلفين",
|
||||
"filterBy.authorRange.followed": "المؤلفون المتابعون",
|
||||
"filterBy.authorRange.title": "نطاق المؤلف",
|
||||
"filterBy.contentLength": "الحد الأدنى لطول السياق",
|
||||
"filterBy.maxToken.title": "تحديد الحد الأقصى للطول (رموز)",
|
||||
"filterBy.authorRange.title": "نطاق المؤلفين",
|
||||
"filterBy.contentLength": "أقل طول للسياق",
|
||||
"filterBy.maxToken.title": "تعيين الحد الأقصى للطول (Token)",
|
||||
"filterBy.maxToken.unlimited": "غير محدود",
|
||||
"filterBy.other.functionCall": "يدعم استدعاء الوظائف",
|
||||
"filterBy.other.functionCall": "دعم استدعاء الوظائف",
|
||||
"filterBy.other.title": "أخرى",
|
||||
"filterBy.other.vision": "يدعم التعرف البصري",
|
||||
"filterBy.other.withKnowledge": "يتضمن مكتبات",
|
||||
"filterBy.other.withTool": "يتضمن مهارات",
|
||||
"filterBy.pricing": "تسعير النموذج",
|
||||
"filterBy.other.vision": "دعم التعرف البصري",
|
||||
"filterBy.other.withKnowledge": "مزود بمكتبات معرفية",
|
||||
"filterBy.other.withTool": "مع الإضافات",
|
||||
"filterBy.pricing": "أسعار النموذج",
|
||||
"filterBy.timePeriod.all": "كل الوقت",
|
||||
"filterBy.timePeriod.day": "آخر 24 ساعة",
|
||||
"filterBy.timePeriod.month": "آخر 30 يومًا",
|
||||
"filterBy.timePeriod.title": "النطاق الزمني",
|
||||
"filterBy.timePeriod.title": "نطاق الوقت",
|
||||
"filterBy.timePeriod.week": "آخر 7 أيام",
|
||||
"filterBy.timePeriod.year": "العام الماضي",
|
||||
"footer.desc": "تطوّر مع مستخدمي الذكاء الاصطناعي حول العالم. كن منشئًا وشارك وكلاءك ومهاراتك في مجتمع LobeHub.",
|
||||
"footer.title": "شارك إبداعاتك في مجتمع LobeHub اليوم",
|
||||
"home.communityAgents": "وكلاء المجتمع",
|
||||
"home.featuredAssistants": "وكلاء مميزون",
|
||||
"filterBy.timePeriod.year": "آخر سنة",
|
||||
"footer.desc": "بكل سهولة، شارك مساعديك ومواردك على مجتمع LobeHub، وتعاون مع مستخدمي الذكاء الاصطناعي حول العالم في الاستخدام والتغذية الراجعة والتطوير.",
|
||||
"footer.title": "انشر إبداعاتك الآن على مجتمع LobeHub",
|
||||
"home.communityAgents": "مساعدو المجتمع",
|
||||
"home.featuredAssistants": "مساعدون مميزون",
|
||||
"home.featuredModels": "نماذج مميزة",
|
||||
"home.featuredPlugins": "مهارات مميزة",
|
||||
"home.featuredProviders": "مزودون مميزون",
|
||||
"home.featuredTools": "مهارات مميزة",
|
||||
"home.featuredPlugins": "الإضافات المميزة",
|
||||
"home.featuredProviders": "مزودو نماذج مميزون",
|
||||
"home.featuredTools": "إضافات مميزة",
|
||||
"home.more": "اكتشف المزيد",
|
||||
"isClaimed": "تم المطالبة به",
|
||||
"isClaimed": "تم المطالبة",
|
||||
"isFeatured": "مميز",
|
||||
"isOfficial": "تم التحقق منه رسميًا",
|
||||
"like": "إعجاب",
|
||||
"isOfficial": "معتمد رسميًا",
|
||||
"like": "أحب",
|
||||
"mcp.categories.all.description": "جميع خوادم MCP",
|
||||
"mcp.categories.all.name": "الكل",
|
||||
"mcp.categories.business.description": "خدمات الأعمال والمؤسسات",
|
||||
"mcp.categories.business.name": "خدمات الأعمال",
|
||||
"mcp.categories.developer.description": "أدوات وخدمات للمطورين",
|
||||
"mcp.categories.developer.name": "أدوات المطورين",
|
||||
"mcp.categories.gaming-entertainment.description": "الألعاب، الترفيه، والأنشطة الترفيهية",
|
||||
"mcp.categories.business.description": "الخدمات التجارية والمؤسساتية",
|
||||
"mcp.categories.business.name": "الخدمات التجارية",
|
||||
"mcp.categories.developer.description": "أدوات وخدمات متعلقة بالتطوير",
|
||||
"mcp.categories.developer.name": "أدوات التطوير",
|
||||
"mcp.categories.gaming-entertainment.description": "الألعاب، الترفيه والأنشطة الترفيهية",
|
||||
"mcp.categories.gaming-entertainment.name": "الألعاب والترفيه",
|
||||
"mcp.categories.health-wellness.description": "الصحة، اللياقة، والعافية",
|
||||
"mcp.categories.health-wellness.description": "الصحة، اللياقة والعناية بالجسم والعقل",
|
||||
"mcp.categories.health-wellness.name": "الصحة والعافية",
|
||||
"mcp.categories.lifestyle.description": "نمط الحياة الشخصية، العادات، والأنشطة اليومية",
|
||||
"mcp.categories.lifestyle.description": "أسلوب الحياة الشخصية، العادات والأنشطة اليومية",
|
||||
"mcp.categories.lifestyle.name": "نمط الحياة",
|
||||
"mcp.categories.media-generate.description": "إنشاء الوسائط، تحريرها، ومعالجتها",
|
||||
"mcp.categories.media-generate.description": "إنشاء، تحرير ومعالجة الوسائط",
|
||||
"mcp.categories.media-generate.name": "إنشاء الوسائط",
|
||||
"mcp.categories.news.description": "تجميع الأخبار، التقارير، وخدمات المعلومات",
|
||||
"mcp.categories.news.description": "تجميع الأخبار، التقارير وخدمات المعلومات",
|
||||
"mcp.categories.news.name": "الأخبار والمعلومات",
|
||||
"mcp.categories.productivity.description": "إدارة المهام، الملاحظات، وأدوات الإنتاجية",
|
||||
"mcp.categories.productivity.description": "إدارة المهام، الملاحظات وأدوات الكفاءة",
|
||||
"mcp.categories.productivity.name": "أدوات الإنتاجية",
|
||||
"mcp.categories.science-education.description": "البحث العلمي، التعلم، وأدوات التعليم",
|
||||
"mcp.categories.science-education.name": "العلم والتعليم",
|
||||
"mcp.categories.science-education.description": "البحث العلمي، التعلم وأدوات التعليم",
|
||||
"mcp.categories.science-education.name": "العلوم والتعليم",
|
||||
"mcp.categories.social.description": "الشبكات الاجتماعية والتواصل",
|
||||
"mcp.categories.social.name": "وسائل التواصل الاجتماعي",
|
||||
"mcp.categories.stocks-finance.description": "الأسواق المالية، التداول، والاستثمار",
|
||||
"mcp.categories.stocks-finance.name": "الأسهم والتمويل",
|
||||
"mcp.categories.tools.description": "أدوات وخدمات عملية متعددة الأغراض",
|
||||
"mcp.categories.tools.name": "أدوات مساعدة",
|
||||
"mcp.categories.travel-transport.description": "تخطيط السفر والمواصلات",
|
||||
"mcp.categories.travel-transport.name": "السفر والمواصلات",
|
||||
"mcp.categories.stocks-finance.description": "أسواق المال، التداول والاستثمار",
|
||||
"mcp.categories.stocks-finance.name": "الأسهم والمالية",
|
||||
"mcp.categories.tools.description": "أدوات وخدمات عامة وعملية",
|
||||
"mcp.categories.tools.name": "أدوات عملية",
|
||||
"mcp.categories.travel-transport.description": "تخطيط السفر والتنقل",
|
||||
"mcp.categories.travel-transport.name": "السفر والنقل",
|
||||
"mcp.categories.weather.description": "توقعات الطقس وخدمات الأرصاد الجوية",
|
||||
"mcp.categories.weather.name": "الطقس",
|
||||
"mcp.categories.weather.name": "الطقس والأرصاد",
|
||||
"mcp.categories.web-search.description": "البحث على الويب واسترجاع المعلومات",
|
||||
"mcp.categories.web-search.name": "استرجاع المعلومات",
|
||||
"mcp.details.connectionType.hybrid.desc": "يمكن تشغيل هذه الخدمة محليًا أو عبر السحابة حسب الإعداد أو سيناريو الاستخدام، مما يوفر إمكانية التشغيل المزدوج.",
|
||||
"mcp.details.connectionType.hybrid.desc": "هذه الخدمة يمكن تشغيلها محلياً أو على السحابة حسب الإعداد أو سيناريو الاستخدام، وتتمتع بقدرة تشغيل مزدوجة.",
|
||||
"mcp.details.connectionType.hybrid.title": "خدمة هجينة",
|
||||
"mcp.details.connectionType.local.desc": "يمكن تشغيل هذا الخادم فقط على جهاز المستخدم المحلي، ويتطلب التثبيت ويعتمد على الموارد المحلية.",
|
||||
"mcp.details.connectionType.local.desc": "هذا الخادم يعمل فقط على جهاز العميل المحلي، ويتطلب التثبيت والاعتماد على الموارد المحلية.",
|
||||
"mcp.details.connectionType.local.title": "خدمة محلية",
|
||||
"mcp.details.connectionType.remote.desc": "يتم استضافة هذا الخادم عن بُعد لأنه يعتمد بشكل أساسي على خدمات خارجية ولا يعتمد على البيئة المحلية.",
|
||||
"mcp.details.connectionType.remote.desc": "هذا الخادم مستضاف ويعمل عن بُعد، لأنه يعتمد بشكل رئيسي على خدمات بعيدة ولا يعتمد على البيئة المحلية.",
|
||||
"mcp.details.connectionType.remote.title": "خدمة سحابية",
|
||||
"mcp.details.deployment.args": "المعلمات",
|
||||
"mcp.details.deployment.args": "المعطيات",
|
||||
"mcp.details.deployment.checkCommand": "أمر التحقق",
|
||||
"mcp.details.deployment.command": "الأمر",
|
||||
"mcp.details.deployment.commandLine": "اعتمادات النظام",
|
||||
"mcp.details.deployment.connection": "طريقة الاتصال",
|
||||
"mcp.details.deployment.connectionType": "نوع الاتصال",
|
||||
"mcp.details.deployment.description": "طريقة تثبيت ونشر المهارة",
|
||||
"mcp.details.deployment.description": "طريقة تثبيت ونشر الإضافة",
|
||||
"mcp.details.deployment.descriptionPlaceholder": "وصف اختياري",
|
||||
"mcp.details.deployment.empty": "لا توجد خيارات نشر متاحة",
|
||||
"mcp.details.deployment.empty": "لا توجد خيارات نشر حالياً",
|
||||
"mcp.details.deployment.env": "متغيرات البيئة",
|
||||
"mcp.details.deployment.guide": "دليل التثبيت",
|
||||
"mcp.details.deployment.guide": "تعليمات التثبيت",
|
||||
"mcp.details.deployment.installation": "التثبيت عبر {{method}}",
|
||||
"mcp.details.deployment.installationMethod": "طريقة التثبيت",
|
||||
"mcp.details.deployment.other": "إعدادات أخرى",
|
||||
"mcp.details.deployment.packageName": "اسم الحزمة",
|
||||
"mcp.details.deployment.platform.steps.claude": "- افتح تطبيق **Claude Desktop**\n- انتقل إلى **الإعدادات** ثم اختر **المطور**\n- انقر على **تحرير الإعدادات**\n- افتح ملف **claude_desktop_config.json**\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
|
||||
"mcp.details.deployment.platform.steps.cline": "- افتح VS Code مع تثبيت إضافة Cline\n- انقر على أيقونة Cline في الشريط الجانبي\n- اختر **MCP Servers** من القائمة المنسدلة\n- في تبويب **الخوادم البعيدة**، أدخل اسم الخادم ورابط MCP الخاص بك\n- انقر على **إضافة خادم** للاتصال",
|
||||
"mcp.details.deployment.platform.steps.cursor": "- انتقل إلى **الإعدادات** ثم اختر إعدادات Cursor\n- اختر **MCP** من القائمة الجانبية\n- انقر على **إضافة خادم MCP عالمي جديد** في الأعلى\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
|
||||
"mcp.details.deployment.platform.steps.lobeChat": "- افتح تطبيق **LobeHub Desktop**\n- انتقل إلى **الإعدادات** - **الوكيل الافتراضي**\n- ثم اختر **إعدادات المهارة** - **مهارات مخصصة**\n- انقر على **استيراد سريع لإعدادات JSON**\n- انسخ والصق إعدادات الخادم في مربع النص ثم قم بالتثبيت",
|
||||
"mcp.details.deployment.platform.steps.openai": "- افتح تطبيق **OpenAI** أو بيئة التطوير الخاصة بك\n- قم بإعداد أدوات MCP في **Responses API**\n- أضف كتل MCP إلى مصفوفة **tools** في طلبات API\n- عيّن **server_url** إلى نقطة نهاية خادم MCP الخاص بك\n- أدرج رؤوس المصادقة المطلوبة (مفتاح API، رمز، إلخ)\n- استخدم المعامل `allowed_tools` لتقييد الأدوات المتاحة\n- عيّن `require_approval` للتحكم في الموافقة على تنفيذ الأدوات",
|
||||
"mcp.details.deployment.platform.steps.vscode": "- افتح VS Code\n- افتح لوحة الأوامر (`Ctrl+Shift+P` / `Cmd+Shift+P`)\n- اكتب **MCP: Add Server** واختره\n- اختر الإضافة إلى إعدادات مساحة العمل أو المستخدم\n- انسخ والصق إعدادات الخادم",
|
||||
"mcp.details.deployment.platform.steps.claude": "- افتح تطبيق **Claude Desktop**\n- اذهب إلى **الإعدادات** ثم اختر **المطور**\n- اضغط على **تحرير الإعدادات**\n- افتح ملف **claude_desktop_config.json**\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
|
||||
"mcp.details.deployment.platform.steps.cline": "- افتح VS Code مع إضافة Cline المثبتة\n- اضغط على أيقونة Cline في الشريط الجانبي\n- اختر **MCP Servers** من القائمة المنسدلة\n- في تبويب **الخوادم البعيدة**، أدخل اسم الخادم ورابط MCP الخاص بك\n- اضغط **Add Server** للاتصال",
|
||||
"mcp.details.deployment.platform.steps.cursor": "- انتقل إلى **الإعدادات** ثم إعدادات Cursor\n- اختر **MCP** من الجانب الأيسر\n- اضغط على **إضافة خادم MCP عالمي جديد** في الأعلى يمين\n- انسخ والصق إعدادات الخادم في الملف الحالي ثم احفظ",
|
||||
"mcp.details.deployment.platform.steps.lobeChat": "- افتح تطبيق **LobeChat لسطح المكتب**\n- اذهب إلى **الإعدادات** - **المساعد الافتراضي**\n- اختر **إعدادات الإضافة** - **إضافة مخصصة**\n- اضغط على **استيراد سريع لإعدادات JSON**\n- انسخ والصق إعدادات الخادم في مربع النص ثم ثبت",
|
||||
"mcp.details.deployment.platform.steps.openai": "- افتح تطبيق **OpenAI** أو بيئة التطوير الخاصة بك\n- قم بإعداد أدوات MCP في **Responses API**\n- أضف كتلة MCP إلى مصفوفة **tools** في طلب API\n- عيّن **server_url** إلى نقطة نهاية خادم MCP الخاص بك\n- أدرج رؤوس المصادقة المطلوبة (مفتاح API، رموز، إلخ)\n- استخدم معلمة `allowed_tools` لتقييد الأدوات المكشوفة\n- عيّن `require_approval` للتحكم في موافقة تنفيذ الأدوات",
|
||||
"mcp.details.deployment.platform.steps.vscode": "- افتح VS Code\n- افتح لوحة الأوامر (`Ctrl+Shift+P` / `Cmd+Shift+P`)\n- اكتب **MCP: Add Server** واختره\n- اختر الإضافة إلى مساحة العمل أو إعدادات المستخدم\n- انسخ والصق إعدادات الخادم",
|
||||
"mcp.details.deployment.platform.title": "التثبيت على {{platform}}",
|
||||
"mcp.details.deployment.recommended": "موصى به",
|
||||
"mcp.details.deployment.systemDependencies": "اعتمادات النظام",
|
||||
@@ -217,267 +217,267 @@
|
||||
"mcp.details.deployment.table.required": "مطلوب",
|
||||
"mcp.details.deployment.table.type": "النوع",
|
||||
"mcp.details.deployment.title": "طريقة التثبيت",
|
||||
"mcp.details.githubBadge.desc": "يقوم LobeHub بمسح مستودعات الشيفرة والمستندات بانتظام من أجل:\n- التحقق من حالة تشغيل خادم MCP.\n- استخراج ميزات الخادم مثل الأدوات، الموارد، التعليمات، والمعلمات المطلوبة.\n- تساعد شارة MCP المستخدمين على تقييم أمان الخادم وميزاته وتعليمات التثبيت بسرعة. يرجى نسخ الكود التالي إلى ملف `README.md` الخاص بك:",
|
||||
"mcp.details.nav.needHelp": "هل تحتاج إلى مساعدة؟",
|
||||
"mcp.details.githubBadge.desc": "يقوم LobeHub بمسح مستودعات الأكواد والوثائق بانتظام من أجل:\n\n- التأكد من أن خوادم MCP تعمل بشكل صحيح.\n- استخراج ميزات الخادم مثل الأدوات، الموارد، التعليمات والمعطيات المطلوبة.\n- تساعد شارة التقييم المستخدمين على تقييم أمان الخادم، ميزاته ودليل التثبيت بسرعة.\n\nيرجى نسخ الكود التالي إلى ملف `README.md` الخاص بك:",
|
||||
"mcp.details.nav.needHelp": "هل تحتاج مساعدة؟",
|
||||
"mcp.details.nav.reportIssue": "الإبلاغ عن مشكلة",
|
||||
"mcp.details.nav.viewSourceCode": "عرض الشيفرة المصدرية",
|
||||
"mcp.details.overview.title": "نظرة عامة",
|
||||
"mcp.details.related.listTitle": "خوادم MCP ذات صلة",
|
||||
"mcp.details.related.listTitle": "خوادم MCP ذات الصلة",
|
||||
"mcp.details.related.more": "عرض المزيد",
|
||||
"mcp.details.related.title": "توصيات ذات صلة",
|
||||
"mcp.details.related.title": "اقتراحات ذات صلة",
|
||||
"mcp.details.schema.mode.docs": "الوثائق",
|
||||
"mcp.details.schema.prompts.arguments": "إعداد المعلمات",
|
||||
"mcp.details.schema.prompts.desc": "قوالب تفاعلية يتم تفعيلها عند اختيار المستخدم",
|
||||
"mcp.details.schema.prompts.empty": "لا توجد تعليمات متاحة",
|
||||
"mcp.details.schema.prompts.instructions": "وصف التعليمات",
|
||||
"mcp.details.schema.prompts.arguments": "إعدادات المعطيات",
|
||||
"mcp.details.schema.prompts.desc": "قوالب تفاعلية يتم تفعيلها باختيار المستخدم",
|
||||
"mcp.details.schema.prompts.empty": "لا توجد تعليمات حالياً",
|
||||
"mcp.details.schema.prompts.instructions": "تعليمات",
|
||||
"mcp.details.schema.prompts.table.description": "الوصف",
|
||||
"mcp.details.schema.prompts.table.name": "الاسم",
|
||||
"mcp.details.schema.prompts.table.required": "مطلوب",
|
||||
"mcp.details.schema.prompts.title": "قائمة التعليمات",
|
||||
"mcp.details.schema.resources.desc": "بيانات السياق المرفقة والمدارة من قبل العميل",
|
||||
"mcp.details.schema.resources.empty": "لا توجد موارد متاحة",
|
||||
"mcp.details.schema.resources.desc": "بيانات سياقية مرفقة ومدارة من قبل العميل",
|
||||
"mcp.details.schema.resources.empty": "لا توجد موارد",
|
||||
"mcp.details.schema.resources.table.description": "الوصف",
|
||||
"mcp.details.schema.resources.table.mineType": "نوع MIME",
|
||||
"mcp.details.schema.resources.table.name": "الاسم",
|
||||
"mcp.details.schema.resources.table.uri": "الرابط URI",
|
||||
"mcp.details.schema.resources.table.uri": "رابط URI",
|
||||
"mcp.details.schema.resources.title": "قائمة الموارد",
|
||||
"mcp.details.schema.title": "ميزات المهارة",
|
||||
"mcp.details.schema.tools.desc": "واجهات وظيفية مكشوفة لنماذج اللغة الكبيرة (LLM) لتنفيذ العمليات",
|
||||
"mcp.details.schema.tools.empty": "لا توجد أدوات متاحة",
|
||||
"mcp.details.schema.title": "وظائف الإضافة",
|
||||
"mcp.details.schema.tools.desc": "واجهات وظائف مكشوفة لنموذج اللغة الكبير (LLM) لتنفيذ العمليات",
|
||||
"mcp.details.schema.tools.empty": "لا توجد أدوات",
|
||||
"mcp.details.schema.tools.inputSchema": "وصف الإدخال",
|
||||
"mcp.details.schema.tools.instructions": "وصف التعليمات",
|
||||
"mcp.details.schema.tools.instructions": "تعليمات",
|
||||
"mcp.details.schema.tools.table.description": "الوصف",
|
||||
"mcp.details.schema.tools.table.name": "الاسم",
|
||||
"mcp.details.schema.tools.table.required": "مطلوب",
|
||||
"mcp.details.schema.tools.table.type": "النوع",
|
||||
"mcp.details.schema.tools.title": "قائمة الأدوات",
|
||||
"mcp.details.score.claimed.desc": "تم تأكيد ملكية هذا الخادم MCP من قبل مالكه، مما يضمن إدارته.",
|
||||
"mcp.details.score.claimed.title": "تمت المطالبة به من قبل المالك",
|
||||
"mcp.details.score.deployMoreThanManual.desc": "يوفر هذا الخادم MCP طرق تثبيت أسهل من التثبيت اليدوي، مما يسهل على المستخدمين نشره واستخدامه.",
|
||||
"mcp.details.score.claimed.desc": "تمت المطالبة بهذا الخادم من قبل المالك، مما يضمن ملكيته وإدارته.",
|
||||
"mcp.details.score.claimed.title": "مطالب به من قبل المالك",
|
||||
"mcp.details.score.deployMoreThanManual.desc": "يوفر هذا الخادم طرق تثبيت أكثر سهولة من الطريقة اليدوية، مما يسمح للمستخدمين بالنشر والاستخدام بسهولة.",
|
||||
"mcp.details.score.deployMoreThanManual.title": "يوفر طرق تثبيت سهلة",
|
||||
"mcp.details.score.deployment.desc": "يوفر هذا الخادم MCP طريقة تثبيت واحدة على الأقل، مما يتيح للمستخدمين نشره واستخدامه.",
|
||||
"mcp.details.score.deployment.descWithCount": "يوفر هذا الخادم MCP {{number}} طريقة تثبيت، مما يتيح للمستخدمين نشره واستخدامه.",
|
||||
"mcp.details.score.deployment.desc": "يوفر هذا الخادم على الأقل طريقة تثبيت واحدة تسمح للمستخدمين بالنشر والاستخدام.",
|
||||
"mcp.details.score.deployment.descWithCount": "يوفر هذا الخادم {{number}} طريقة تثبيت تسمح للمستخدمين بالنشر والاستخدام.",
|
||||
"mcp.details.score.deployment.title": "يوفر طريقة تثبيت واحدة على الأقل",
|
||||
"mcp.details.score.license.desc": "يحتوي هذا المستودع على ملف ترخيص LICENSE.",
|
||||
"mcp.details.score.license.descWithlicense": "تم ترخيص هذا المستودع بموجب {{license}}.",
|
||||
"mcp.details.score.license.title": "يحتوي على ترخيص",
|
||||
"mcp.details.score.license.desc": "يحتوي هذا المستودع على ملف LICENSE.",
|
||||
"mcp.details.score.license.descWithlicense": "رخصة هذا المستودع هي {{license}}.",
|
||||
"mcp.details.score.license.title": "يحتوي على رخصة",
|
||||
"mcp.details.score.listTitle": "تفاصيل التقييم",
|
||||
"mcp.details.score.notClaimed.desc": "إذا كنت مالك هذا الخادم MCP، يمكنك المطالبة به عبر الطرق التالية.",
|
||||
"mcp.details.score.notClaimed.title": "لم تتم المطالبة به من قبل المالك",
|
||||
"mcp.details.score.prompts.desc": "يوفر هذا الخادم MCP تعليمات تتيح للمستخدمين التفاعل مع الخدمة.",
|
||||
"mcp.details.score.prompts.descWithCount": "يوفر هذا الخادم MCP {{number}} تعليمات تتيح للمستخدمين التفاعل مع الخدمة.",
|
||||
"mcp.details.score.prompts.title": "يتضمن تعليمات",
|
||||
"mcp.details.score.notClaimed.desc": "إذا كنت مالك هذا الخادم، يمكنك المطالبة به بالطرق التالية.",
|
||||
"mcp.details.score.notClaimed.title": "غير مطالب به من قبل المالك",
|
||||
"mcp.details.score.prompts.desc": "يوفر هذا الخادم تعليمات تسمح للمستخدمين بالتفاعل مع الخدمة.",
|
||||
"mcp.details.score.prompts.descWithCount": "يوفر هذا الخادم {{number}} تعليمات تسمح للمستخدمين بالتفاعل مع الخدمة.",
|
||||
"mcp.details.score.prompts.title": "يحتوي على تعليمات",
|
||||
"mcp.details.score.readme.desc": "يحتوي هذا المستودع على ملف README.md.",
|
||||
"mcp.details.score.readme.title": "يحتوي على README",
|
||||
"mcp.details.score.resources.desc": "يوفر هذا الخادم MCP موارد تتيح للمستخدمين إرفاق بيانات السياق وإدارتها.",
|
||||
"mcp.details.score.resources.descWithCount": "يوفر هذا الخادم MCP {{number}} من الموارد تتيح للمستخدمين إرفاق بيانات السياق وإدارتها.",
|
||||
"mcp.details.score.resources.title": "يتضمن موارد",
|
||||
"mcp.details.score.resources.desc": "يوفر هذا الخادم موارد تسمح للمستخدمين بإرفاق وإدارة بيانات السياق.",
|
||||
"mcp.details.score.resources.descWithCount": "يوفر هذا الخادم {{number}} موارد تسمح للمستخدمين بإرفاق وإدارة بيانات السياق.",
|
||||
"mcp.details.score.resources.title": "يحتوي على موارد",
|
||||
"mcp.details.score.title": "التقييم",
|
||||
"mcp.details.score.tools.desc": "يجب أن يوفر هذا الخادم أداة واحدة على الأقل تتيح للمستخدمين تنفيذ عمليات محددة.",
|
||||
"mcp.details.score.tools.descWithCount": "يوفر هذا الخادم MCP {{number}} من الأدوات التي تتيح للمستخدمين تنفيذ عمليات محددة.",
|
||||
"mcp.details.score.tools.title": "يتضمن أداة واحدة على الأقل",
|
||||
"mcp.details.score.validated.desc": "تم التحقق من هذا الخادم MCP لضمان جودته وموثوقيته.",
|
||||
"mcp.details.score.tools.desc": "يجب أن يوفر الخادم أداة واحدة على الأقل تسمح للمستخدمين بتنفيذ عمليات محددة.",
|
||||
"mcp.details.score.tools.descWithCount": "يوفر هذا الخادم {{number}} أداة تسمح للمستخدمين بتنفيذ عمليات محددة.",
|
||||
"mcp.details.score.tools.title": "يحتوي على أداة واحدة على الأقل",
|
||||
"mcp.details.score.validated.desc": "تم التحقق من هذا الخادم لضمان جودته وموثوقيته.",
|
||||
"mcp.details.score.validated.title": "تم التحقق منه",
|
||||
"mcp.details.scoreLevel.a.desc": "تم التحقق من هذا الخادم MCP بدقة، ويقدم ميزات شاملة وتجربة مستخدم عالية الجودة.",
|
||||
"mcp.details.scoreLevel.a.fullTitle": "مهارة ممتازة",
|
||||
"mcp.details.scoreLevel.a.title": "مميز",
|
||||
"mcp.details.scoreLevel.b.desc": "يقدم هذا الخادم MCP ميزات جيدة وتجربة مستخدم مقبولة، لكنه قد يحتاج إلى تحسينات في بعض الجوانب.",
|
||||
"mcp.details.scoreLevel.a.desc": "تم التحقق من هذا الخادم بدقة، ويوفر وظائف شاملة وتجربة مستخدم عالية الجودة.",
|
||||
"mcp.details.scoreLevel.a.fullTitle": "إضافة ممتازة",
|
||||
"mcp.details.scoreLevel.a.title": "ممتاز",
|
||||
"mcp.details.scoreLevel.b.desc": "يوفر هذا الخادم وظائف وتجربة مستخدم جيدة، لكنه قد يحتاج إلى تحسين في بعض الجوانب.",
|
||||
"mcp.details.scoreLevel.b.fullTitle": "وظائف جيدة",
|
||||
"mcp.details.scoreLevel.b.title": "جيد",
|
||||
"mcp.details.scoreLevel.f.desc": "هذا الخادم MCP غير مكتمل أو منخفض الجودة؛ يُنصح المستخدمون باستخدامه بحذر.",
|
||||
"mcp.details.scoreLevel.f.desc": "وظائف هذا الخادم غير مكتملة أو جودته منخفضة، ينصح المستخدمون بالحذر عند الاستخدام.",
|
||||
"mcp.details.scoreLevel.f.fullTitle": "جودة ضعيفة",
|
||||
"mcp.details.scoreLevel.f.title": "ضعيف",
|
||||
"mcp.details.settings.capabilities.prompts": "المحفزات",
|
||||
"mcp.details.settings.capabilities.prompts": "التلميحات",
|
||||
"mcp.details.settings.capabilities.resources": "الموارد",
|
||||
"mcp.details.settings.capabilities.title": "قدرات المهارة",
|
||||
"mcp.details.settings.capabilities.title": "قدرات الإضافة",
|
||||
"mcp.details.settings.capabilities.tools": "الأدوات",
|
||||
"mcp.details.settings.configuration.title": "إعدادات المهارة",
|
||||
"mcp.details.settings.connection.args": "وسائط التشغيل",
|
||||
"mcp.details.settings.configuration.title": "تكوين الإضافة",
|
||||
"mcp.details.settings.connection.args": "معاملات التشغيل",
|
||||
"mcp.details.settings.connection.command": "أمر التشغيل",
|
||||
"mcp.details.settings.connection.title": "معلومات الاتصال",
|
||||
"mcp.details.settings.connection.type": "نوع الاتصال",
|
||||
"mcp.details.settings.connection.url": "رابط الخدمة",
|
||||
"mcp.details.settings.connection.url": "عنوان الخدمة",
|
||||
"mcp.details.settings.saveSettings": "حفظ الإعدادات",
|
||||
"mcp.details.settings.title": "إعدادات المهارة",
|
||||
"mcp.details.settings.title": "إعدادات الإضافة",
|
||||
"mcp.details.sidebar.install": "تثبيت خادم MCP",
|
||||
"mcp.details.sidebar.meta.homepage": "الصفحة الرسمية",
|
||||
"mcp.details.sidebar.meta.homepage": "الصفحة الرئيسية",
|
||||
"mcp.details.sidebar.meta.installCount": "عدد التثبيتات",
|
||||
"mcp.details.sidebar.meta.language": "لغة المصدر",
|
||||
"mcp.details.sidebar.meta.license": "الرخصة",
|
||||
"mcp.details.sidebar.meta.published": "تاريخ النشر",
|
||||
"mcp.details.sidebar.meta.repo": "مستودع المصدر",
|
||||
"mcp.details.sidebar.meta.stars": "التقييمات",
|
||||
"mcp.details.sidebar.meta.title": "التفاصيل",
|
||||
"mcp.details.sidebar.meta.repo": "مستودع الشيفرة",
|
||||
"mcp.details.sidebar.meta.stars": "عدد النجوم",
|
||||
"mcp.details.sidebar.meta.title": "معلومات مفصلة",
|
||||
"mcp.details.sidebar.meta.updated": "آخر تحديث",
|
||||
"mcp.details.sidebar.moreServerConfig": "عرض التفاصيل",
|
||||
"mcp.details.sidebar.recommendServers": "خوادم MCP ذات صلة",
|
||||
"mcp.details.sidebar.serverConfig": "إعدادات التثبيت",
|
||||
"mcp.details.sidebar.toc": "جدول المحتويات",
|
||||
"mcp.details.summary.title": "ماذا يمكنك أن تفعل بهذا الخادم MCP؟",
|
||||
"mcp.details.totalScore.description": "تم حساب الدرجة الإجمالية بناءً على مؤشرات متعددة",
|
||||
"mcp.details.totalScore.legend.aGrade": "الدرجة A ({{minPercent}}-100%)",
|
||||
"mcp.details.totalScore.legend.bGrade": "الدرجة B ({{minPercent}}-{{maxPercent}}%)",
|
||||
"mcp.details.totalScore.legend.fGrade": "الدرجة F (0-{{maxPercent}}%)",
|
||||
"mcp.details.totalScore.pointsFormat": "{{score}}/{{total}} نقطة",
|
||||
"mcp.details.totalScore.popover.completedOptional": "✅ العناصر الاختيارية المكتملة ({{count}})",
|
||||
"mcp.details.totalScore.popover.completedRequired": "✅ العناصر المطلوبة المكتملة ({{count}})",
|
||||
"mcp.details.totalScore.popover.incompleteOptional": "⏸️ العناصر الاختيارية غير المكتملة ({{count}})",
|
||||
"mcp.details.totalScore.popover.incompleteRequired": "❌ العناصر المطلوبة غير المكتملة ({{count}})",
|
||||
"mcp.details.sidebar.toc": "المحتوى",
|
||||
"mcp.details.summary.title": "ما الذي يمكنك فعله باستخدام خادم MCP هذا؟",
|
||||
"mcp.details.totalScore.description": "الدرجة الإجمالية المحسوبة بناءً على مؤشرات متعددة",
|
||||
"mcp.details.totalScore.legend.aGrade": "الدرجة أ ({{minPercent}}-100%)",
|
||||
"mcp.details.totalScore.legend.bGrade": "الدرجة ب ({{minPercent}}-{{maxPercent}}%)",
|
||||
"mcp.details.totalScore.legend.fGrade": "الدرجة ف (0-{{maxPercent}}%)",
|
||||
"mcp.details.totalScore.pointsFormat": "{{score}}/{{total}} نقاط",
|
||||
"mcp.details.totalScore.popover.completedOptional": "✅ تم إكمال الخيارات الاختيارية ({{count}} عناصر)",
|
||||
"mcp.details.totalScore.popover.completedRequired": "✅ تم إكمال العناصر المطلوبة ({{count}} عناصر)",
|
||||
"mcp.details.totalScore.popover.incompleteOptional": "⏸️ لم تكتمل الخيارات الاختيارية ({{count}} عناصر)",
|
||||
"mcp.details.totalScore.popover.incompleteRequired": "❌ لم تكتمل العناصر المطلوبة ({{count}} عناصر)",
|
||||
"mcp.details.totalScore.popover.title": "تفاصيل التقييم",
|
||||
"mcp.details.totalScore.ratingFormat": "التقييم: {{level}}",
|
||||
"mcp.details.totalScore.scoreInfo.items": "العناصر",
|
||||
"mcp.details.totalScore.scoreInfo.points": "النقاط",
|
||||
"mcp.details.totalScore.scoreInfo.requiredItems": "العناصر المطلوبة",
|
||||
"mcp.details.totalScore.scoreInfo.items": "عناصر",
|
||||
"mcp.details.totalScore.scoreInfo.points": "نقاط",
|
||||
"mcp.details.totalScore.scoreInfo.requiredItems": "عناصر مطلوبة",
|
||||
"mcp.details.totalScore.title": "الدرجة الإجمالية",
|
||||
"mcp.details.versions.table.isLatest": "أحدث إصدار",
|
||||
"mcp.details.versions.table.isValidated": "تم التحقق منه",
|
||||
"mcp.details.versions.table.isValidated": "تم التحقق",
|
||||
"mcp.details.versions.table.publishAt": "تاريخ النشر",
|
||||
"mcp.details.versions.table.version": "الإصدار",
|
||||
"mcp.details.versions.title": "سجل الإصدارات",
|
||||
"mcp.hero.desc": "مجتمع خوادم MCP مفتوح المصدر وقابل للنشر—يساعد أنظمة الذكاء الاصطناعي على الوصول إلى أنظمة الملفات وقواعد البيانات وواجهات البرمجة وغيرها من الموارد الأساسية.",
|
||||
"mcp.hero.subTitle": "مفتوح المصدر وجاهز للتشغيل",
|
||||
"mcp.hero.desc": "منصة MCP Servers مفتوحة المصدر وقابلة للنشر، تساعد أنظمة الذكاء الاصطناعي على الوصول بسهولة إلى أنظمة الملفات، قواعد البيانات، واجهات برمجة التطبيقات وغيرها من الموارد الحيوية، لتوسيع قدرات الذكاء الاصطناعي الخاصة بك بشكل شامل.",
|
||||
"mcp.hero.subTitle": "مفتوح المصدر وجاهز للاستخدام",
|
||||
"mcp.hero.title": "مجتمع MCP مفتوح المصدر للذكاء الاصطناعي",
|
||||
"mcp.sorts.createdAt": "أُضيف حديثًا",
|
||||
"mcp.sorts.createdAt": "أضيف مؤخراً",
|
||||
"mcp.sorts.installCount": "عدد التثبيتات",
|
||||
"mcp.sorts.isFeatured": "المهارات المميزة",
|
||||
"mcp.sorts.isValidated": "المهارات المُتحقق منها",
|
||||
"mcp.sorts.promptsCount": "عدد المحفزات",
|
||||
"mcp.sorts.isFeatured": "الإضافات المميزة",
|
||||
"mcp.sorts.isValidated": "الإضافات التي تم التحقق منها",
|
||||
"mcp.sorts.promptsCount": "عدد التعليمات",
|
||||
"mcp.sorts.ratingCount": "عدد التقييمات",
|
||||
"mcp.sorts.resourcesCount": "عدد الموارد",
|
||||
"mcp.sorts.toolsCount": "عدد الأدوات",
|
||||
"mcp.sorts.updatedAt": "تم التحديث مؤخرًا",
|
||||
"mcp.sorts.updatedAt": "تم التحديث مؤخراً",
|
||||
"mcp.title": "مجتمع MCP",
|
||||
"mcp.unvalidated.desc": "لم يتم التحقق من هذا الخادم MCP بعد",
|
||||
"mcp.unvalidated.title": "غير مُتحقق",
|
||||
"mcp.unvalidated.desc": "هذا الخادم MCP لم يتم التحقق منه بعد",
|
||||
"mcp.unvalidated.title": "غير مُحقق",
|
||||
"mcp.validated.desc": "تم التحقق من هذا الخادم MCP لضمان جودته وموثوقيته.",
|
||||
"mcp.validated.descWithDate": "تم التحقق من هذا الخادم MCP في {{date}} لضمان جودته وموثوقيته.",
|
||||
"mcp.validated.title": "تم التحقق منه",
|
||||
"mcpEmpty.description": "حاول تعديل الفلاتر أو البحث بكلمات مفتاحية مختلفة.",
|
||||
"mcp.validated.descWithDate": "تم التحقق من هذا الخادم MCP بتاريخ {{date}} لضمان جودته وموثوقيته.",
|
||||
"mcp.validated.title": "تم التحقق",
|
||||
"mcpEmpty.description": "حاول تعديل معايير التصفية أو البحث باستخدام كلمات مفتاحية",
|
||||
"mcpEmpty.search": "لم يتم العثور على خوادم MCP مطابقة",
|
||||
"mcpEmpty.title": "لا توجد خوادم MCP",
|
||||
"mcpEmpty.title": "لا توجد خوادم MCP حالياً",
|
||||
"models.abilities": "قدرات النموذج",
|
||||
"models.chat": "بدء محادثة",
|
||||
"models.contentLength": "الحد الأقصى لطول السياق",
|
||||
"models.chat": "بدء المحادثة",
|
||||
"models.contentLength": "أقصى طول للسياق",
|
||||
"models.details.overview.title": "نظرة عامة",
|
||||
"models.details.related.listTitle": "نماذج ذات صلة",
|
||||
"models.details.related.listTitle": "النماذج ذات الصلة",
|
||||
"models.details.related.more": "عرض المزيد",
|
||||
"models.details.related.title": "توصيات ذات صلة",
|
||||
"models.empty.description": "حاول تعديل الفلاتر لرؤية المزيد من النماذج",
|
||||
"models.details.related.title": "اقتراحات ذات صلة",
|
||||
"models.empty.description": "حاول تعديل معايير التصفية لرؤية المزيد من النماذج",
|
||||
"models.empty.search": "لم يتم العثور على نماذج مطابقة",
|
||||
"models.empty.title": "لا توجد نماذج متاحة",
|
||||
"models.empty.title": "لا توجد نماذج حالياً",
|
||||
"models.free": "مجاني",
|
||||
"models.guide": "دليل الإعداد",
|
||||
"models.list": "قائمة النماذج",
|
||||
"models.more": "المزيد",
|
||||
"models.parameterList.defaultValue": "القيمة الافتراضية",
|
||||
"models.parameterList.docs": "عرض التوثيق",
|
||||
"models.parameterList.frequency_penalty.desc": "تتحكم هذه الإعدادات في تكرار استخدام المفردات التي ظهرت مسبقًا في الإدخال. القيم الأعلى تقلل من التكرار، بينما القيم السالبة تشجع على إعادة الاستخدام.",
|
||||
"models.parameterList.docs": "عرض الوثائق",
|
||||
"models.parameterList.frequency_penalty.desc": "تقوم هذه الإعدادات بتعديل تكرار استخدام النموذج لكلمات معينة ظهرت بالفعل في المدخلات. القيم الأعلى تقلل من احتمال تكرار هذه الكلمات، بينما القيم السلبية تعزز استخدامها. عقوبة الكلمات لا تزداد مع زيادة عدد مرات الظهور. القيم السلبية ستشجع على تكرار الكلمات.",
|
||||
"models.parameterList.frequency_penalty.title": "عقوبة التكرار",
|
||||
"models.parameterList.max_tokens.desc": "يحدد هذا الإعداد الحد الأقصى لطول الرد الذي يمكن أن يولده النموذج. القيم الأعلى تسمح بردود أطول، بينما القيم الأقل تجعل الردود أكثر إيجازًا.",
|
||||
"models.parameterList.max_tokens.desc": "تحدد هذه الإعدادات الحد الأقصى لطول النص الذي يمكن أن ينتجه النموذج في رد واحد. يسمح تعيين قيمة أعلى للنموذج بإنتاج ردود أطول، بينما تحدد القيمة المنخفضة طول الردود، مما يجعلها أكثر اختصارًا. يمكن أن يساعد ضبط هذه القيمة بشكل معقول وفقًا لمختلف سيناريوهات الاستخدام في تحقيق الطول والتفاصيل المتوقعة للرد.",
|
||||
"models.parameterList.max_tokens.title": "حد الرد الواحد",
|
||||
"models.parameterList.presence_penalty.desc": "يتحكم هذا الإعداد في استخدام المفردات بناءً على تكرارها في الإدخال. القيم الأعلى تقلل من استخدام الكلمات المتكررة، بينما القيم السالبة تشجع على إعادة استخدامها.",
|
||||
"models.parameterList.presence_penalty.title": "تجديد الموضوع",
|
||||
"models.parameterList.range": "النطاق",
|
||||
"models.parameterList.reasoning_effort.desc": "يتحكم هذا الإعداد في مستوى التفكير الذي يستخدمه النموذج قبل توليد الرد. القيم الأعلى توفر استدلالًا أعمق ولكنها أبطأ، بينما القيم الأقل أسرع ولكنها أقل دقة.",
|
||||
"models.parameterList.reasoning_effort.title": "شدة الاستدلال",
|
||||
"models.parameterList.temperature.desc": "يؤثر هذا الإعداد على تنوع الردود. القيم المنخفضة تؤدي إلى ردود أكثر توقعًا، بينما القيم الأعلى تنتج ردودًا أكثر تنوعًا.",
|
||||
"models.parameterList.temperature.title": "العشوائية",
|
||||
"models.parameterList.presence_penalty.desc": "تهدف هذه الإعدادات إلى التحكم في تكرار استخدام الكلمات بناءً على تكرار ظهورها في المدخلات. تحاول تقليل استخدام الكلمات التي ظهرت كثيرًا في المدخلات، حيث يتناسب تكرار استخدامها مع تكرار ظهورها. عقوبة الكلمات تزداد مع عدد مرات الظهور. القيم السلبية ستشجع على تكرار الكلمات.",
|
||||
"models.parameterList.presence_penalty.title": "جدة الموضوع",
|
||||
"models.parameterList.range": "نطاق",
|
||||
"models.parameterList.reasoning_effort.desc": "تُستخدم هذه الإعدادات للتحكم في شدة التفكير التي يقوم بها النموذج قبل توليد الإجابات. الشدة المنخفضة تعطي الأولوية لسرعة الاستجابة وتوفر الرموز، بينما الشدة العالية توفر تفكيرًا أكثر اكتمالًا ولكنها تستهلك المزيد من الرموز وتقلل من سرعة الاستجابة. القيمة الافتراضية هي متوسطة، مما يوازن بين دقة التفكير وسرعة الاستجابة.",
|
||||
"models.parameterList.reasoning_effort.title": "شدة التفكير",
|
||||
"models.parameterList.temperature.desc": "تؤثر هذه الإعدادات على تنوع استجابة النموذج. القيم المنخفضة تؤدي إلى استجابات أكثر توقعًا ونمطية، بينما القيم الأعلى تشجع على استجابات أكثر تنوعًا وغير شائعة. عندما تكون القيمة 0، يعطي النموذج نفس الاستجابة دائمًا لنفس المدخل.",
|
||||
"models.parameterList.temperature.title": "عشوائية",
|
||||
"models.parameterList.title": "معلمات النموذج",
|
||||
"models.parameterList.top_p.desc": "يحدد هذا الإعداد نسبة الكلمات الأكثر احتمالًا التي يمكن للنموذج اختيارها. القيم المنخفضة تجعل الردود أكثر قابلية للتنبؤ.",
|
||||
"models.parameterList.top_p.title": "اختيار النواة",
|
||||
"models.parameterList.type": "النوع",
|
||||
"models.providerInfo.apiTooltip": "يدعم LobeHub استخدام مفتاح API مخصص لهذا المزود.",
|
||||
"models.parameterList.top_p.desc": "تحدد هذه الإعدادات اختيار النموذج للكلمات ذات الاحتمالية الأعلى فقط: اختيار الكلمات التي تصل احتمالاتها التراكمية إلى P. القيم المنخفضة تجعل استجابات النموذج أكثر توقعًا، بينما الإعداد الافتراضي يسمح للنموذج بالاختيار من جميع نطاق الكلمات.",
|
||||
"models.parameterList.top_p.title": "عينات النواة",
|
||||
"models.parameterList.type": "نوع",
|
||||
"models.providerInfo.apiTooltip": "يدعم LobeChat استخدام مفتاح API مخصص لهذا المزود.",
|
||||
"models.providerInfo.input": "سعر الإدخال",
|
||||
"models.providerInfo.inputTooltip": "التكلفة لكل مليون رمز",
|
||||
"models.providerInfo.latency": "الكمون",
|
||||
"models.providerInfo.latencyTooltip": "متوسط وقت الاستجابة لإرسال أول رمز",
|
||||
"models.providerInfo.maxOutput": "الحد الأقصى لطول الإخراج",
|
||||
"models.providerInfo.maxOutputTooltip": "أقصى عدد من الرموز يمكن أن يولدها هذا الطرف",
|
||||
"models.providerInfo.officialTooltip": "خدمة LobeHub الرسمية",
|
||||
"models.providerInfo.inputTooltip": "تكلفة لكل مليون Token",
|
||||
"models.providerInfo.latency": "زمن الاستجابة",
|
||||
"models.providerInfo.latencyTooltip": "متوسط زمن استجابة المزود لإرسال أول Token",
|
||||
"models.providerInfo.maxOutput": "أقصى طول للإخراج",
|
||||
"models.providerInfo.maxOutputTooltip": "عدد Tokens الأقصى الذي يمكن أن ينتجه هذا النقطة",
|
||||
"models.providerInfo.officialTooltip": "خدمة رسمية من LobeHub",
|
||||
"models.providerInfo.output": "سعر الإخراج",
|
||||
"models.providerInfo.outputTooltip": "التكلفة لكل مليون رمز",
|
||||
"models.providerInfo.streamCancellationTooltip": "يدعم هذا المزود إلغاء البث.",
|
||||
"models.providerInfo.outputTooltip": "تكلفة لكل مليون Token",
|
||||
"models.providerInfo.streamCancellationTooltip": "يدعم هذا المزود ميزة إلغاء التدفق.",
|
||||
"models.providerInfo.throughput": "معدل النقل",
|
||||
"models.providerInfo.throughputTooltip": "متوسط عدد الرموز المنقولة في الثانية لطلبات البث",
|
||||
"models.providerInfo.throughputTooltip": "متوسط عدد Tokens المنقولة في الطلبات المتدفقة في الثانية",
|
||||
"models.sorts.contextWindowTokens": "طول السياق",
|
||||
"models.sorts.identifier": "معرف النموذج",
|
||||
"models.sorts.inputPrice": "سعر الإدخال",
|
||||
"models.sorts.outputPrice": "سعر الإخراج",
|
||||
"models.sorts.providerCount": "عدد المزودين",
|
||||
"models.sorts.releasedAt": "تم الإصدار مؤخرًا",
|
||||
"models.sorts.releasedAt": "تم النشر مؤخراً",
|
||||
"models.suggestions": "نماذج ذات صلة",
|
||||
"models.supportedProviders": "المزودون الداعمون لهذا النموذج",
|
||||
"plugins.builtinTag": "مضمن",
|
||||
"plugins.community": "مهارات المجتمع",
|
||||
"plugins.details.settings.title": "إعدادات المهارة",
|
||||
"plugins.details.summary.title": "ماذا يمكنك أن تفعل بهذه المهارة؟",
|
||||
"plugins.details.tools.title": "أدوات المهارة",
|
||||
"plugins.install": "تثبيت المهارة",
|
||||
"plugins.installed": "مثبت",
|
||||
"plugins.legacyTag": "قديم",
|
||||
"plugins.list": "قائمة المهارات",
|
||||
"plugins.meta.description": "الوصف",
|
||||
"plugins.meta.parameter": "المعلمة",
|
||||
"plugins.meta.title": "معلمات الأداة",
|
||||
"plugins.meta.type": "النوع",
|
||||
"models.supportedProviders": "مزودو الخدمة المدعومون لهذا النموذج",
|
||||
"plugins.builtinTag": "الملحقات المدمجة",
|
||||
"plugins.community": "إضافات المجتمع",
|
||||
"plugins.details.settings.title": "إعدادات الإضافة",
|
||||
"plugins.details.summary.title": "ما الذي يمكنك فعله باستخدام هذه الإضافة؟",
|
||||
"plugins.details.tools.title": "أدوات الإضافة",
|
||||
"plugins.install": "تثبيت الإضافة",
|
||||
"plugins.installed": "تم التثبيت",
|
||||
"plugins.legacyTag": "الملحقات القديمة",
|
||||
"plugins.list": "قائمة الإضافات",
|
||||
"plugins.meta.description": "وصف",
|
||||
"plugins.meta.parameter": "معامل",
|
||||
"plugins.meta.title": "معامل الأداة",
|
||||
"plugins.meta.type": "نوع",
|
||||
"plugins.more": "المزيد",
|
||||
"plugins.official": "مهارات رسمية",
|
||||
"plugins.recentSubmits": "تم التحديث مؤخرًا",
|
||||
"plugins.sorts.createdAt": "تم النشر مؤخرًا",
|
||||
"plugins.sorts.identifier": "معرف المهارة",
|
||||
"plugins.sorts.title": "اسم المهارة",
|
||||
"plugins.suggestions": "توصيات ذات صلة",
|
||||
"providers.config": "إعداد المزود",
|
||||
"providers.details.guide.title": "دليل التكامل",
|
||||
"plugins.official": "إضافات رسمية",
|
||||
"plugins.recentSubmits": "آخر التحديثات",
|
||||
"plugins.sorts.createdAt": "تم النشر مؤخراً",
|
||||
"plugins.sorts.identifier": "معرف الإضافة",
|
||||
"plugins.sorts.title": "اسم الإضافة",
|
||||
"plugins.suggestions": "اقتراحات ذات صلة",
|
||||
"providers.config": "تكوين مزود الخدمة",
|
||||
"providers.details.guide.title": "دليل الاندماج",
|
||||
"providers.details.overview.title": "نظرة عامة",
|
||||
"providers.details.related.listTitle": "مزودون ذوو صلة",
|
||||
"providers.details.related.listTitle": "مزودو الخدمة ذات الصلة",
|
||||
"providers.details.related.more": "عرض المزيد",
|
||||
"providers.details.related.title": "توصيات ذات صلة",
|
||||
"providers.empty.description": "حاول تعديل الفلاتر لرؤية المزيد من المزودين.",
|
||||
"providers.details.related.title": "اقتراحات ذات صلة",
|
||||
"providers.empty.description": "حاول تعديل معايير التصفية لرؤية المزيد من المزودين",
|
||||
"providers.empty.search": "لم يتم العثور على مزودين مطابقين",
|
||||
"providers.empty.title": "لا يوجد مزودون",
|
||||
"providers.list": "قائمة المزودين",
|
||||
"providers.empty.title": "لا يوجد مزودون حالياً",
|
||||
"providers.list": "قائمة مزودي النماذج",
|
||||
"providers.modelCount": "{{count}} نموذج",
|
||||
"providers.modelName": "اسم النموذج",
|
||||
"providers.modelSite": "توثيق النموذج",
|
||||
"providers.modelSite": "وثائق النموذج",
|
||||
"providers.more": "المزيد",
|
||||
"providers.officialSite": "الموقع الرسمي",
|
||||
"providers.showAllModels": "عرض جميع النماذج",
|
||||
"providers.sorts.default": "الافتراضي",
|
||||
"providers.sorts.default": "الترتيب الافتراضي",
|
||||
"providers.sorts.identifier": "معرف المزود",
|
||||
"providers.sorts.modelCount": "عدد النماذج",
|
||||
"providers.suggestions": "مزودون ذوو صلة",
|
||||
"providers.suggestions": "مزودو الخدمة ذوو الصلة",
|
||||
"providers.supportedModels": "النماذج المدعومة",
|
||||
"publishedTime": "تاريخ النشر",
|
||||
"search.placeholder": "ابحث بالاسم أو الوصف أو الكلمات المفتاحية...",
|
||||
"search.result": "{{count}} نتيجة حول <highlight>{{keyword}}</highlight>",
|
||||
"publishedTime": "نشر في",
|
||||
"search.placeholder": "ابحث عن اسم أو كلمة مفتاحية...",
|
||||
"search.result": "{{count}} نتيجة بحث حول <highlight>{{keyword}}</highlight>",
|
||||
"search.searching": "جارٍ البحث...",
|
||||
"tab.assistant": "الوكيل",
|
||||
"tab.home": "الرئيسية",
|
||||
"tab.assistant": "المساعد",
|
||||
"tab.home": "الصفحة الرئيسية",
|
||||
"tab.model": "النموذج",
|
||||
"tab.plugin": "المهارة",
|
||||
"tab.provider": "المزود",
|
||||
"tab.plugin": "الإضافة",
|
||||
"tab.provider": "مزود النموذج",
|
||||
"tab.user": "المستخدم",
|
||||
"user.agents": "الوكلاء",
|
||||
"user.agents": "المساعدون",
|
||||
"user.downloads": "التنزيلات",
|
||||
"user.editProfile": "تعديل الملف الشخصي",
|
||||
"user.favoriteAgents": "الوكلاء المحفوظون",
|
||||
"user.favoritePlugins": "المهارات المحفوظة",
|
||||
"user.favoriteAgents": "المساعدون المفضلون",
|
||||
"user.favoritePlugins": "الإضافات المفضلة",
|
||||
"user.follow": "متابعة",
|
||||
"user.followers": "المتابعون",
|
||||
"user.following": "يتابع",
|
||||
"user.following": "المتابَعون",
|
||||
"user.login": "كن منشئًا",
|
||||
"user.logout": "تسجيل الخروج",
|
||||
"user.myProfile": "ملفي الشخصي",
|
||||
"user.noAgents": "لم ينشر هذا المستخدم أي وكلاء بعد",
|
||||
"user.noFavoriteAgents": "لا يوجد وكلاء محفوظون بعد",
|
||||
"user.noFavoritePlugins": "لا توجد مهارات محفوظة بعد",
|
||||
"user.publishedAgents": "الوكلاء المنشؤون",
|
||||
"user.myProfile": "صفحتي الشخصية",
|
||||
"user.noAgents": "لم يقم هذا المستخدم بنشر أي مساعدين بعد",
|
||||
"user.noFavoriteAgents": "لا يوجد مساعدون مفضلون حاليًا",
|
||||
"user.noFavoritePlugins": "لا توجد إضافات مفضلة حاليًا",
|
||||
"user.publishedAgents": "المساعدون الذين أنشأتهم",
|
||||
"user.tabs.favorites": "المفضلة",
|
||||
"user.tabs.publishedAgents": "تم الإنشاء",
|
||||
"user.unfavorite": "إلغاء الحفظ",
|
||||
"user.unfavoriteFailed": "فشل في إلغاء الحفظ",
|
||||
"user.unfavoriteSuccess": "تم إلغاء الحفظ",
|
||||
"user.tabs.publishedAgents": "الإبداعات",
|
||||
"user.unfavorite": "إزالة من المفضلة",
|
||||
"user.unfavoriteFailed": "فشل في الإزالة من المفضلة",
|
||||
"user.unfavoriteSuccess": "تمت الإزالة من المفضلة",
|
||||
"user.unfollow": "إلغاء المتابعة",
|
||||
"user.website": "الموقع الإلكتروني"
|
||||
"user.website": "الموقع الشخصي"
|
||||
}
|
||||
|
||||
+26
-34
@@ -1,20 +1,12 @@
|
||||
{
|
||||
"actions.expand.off": "طي",
|
||||
"actions.expand.on": "توسيع",
|
||||
"actions.typobar.off": "إخفاء شريط تنسيق النص",
|
||||
"actions.typobar.on": "إظهار شريط تنسيق النص",
|
||||
"autoSave.latest": "تم تحميل أحدث نسخة",
|
||||
"actions.typobar.off": "إخفاء شريط أدوات التنسيق",
|
||||
"actions.typobar.on": "إظهار شريط أدوات التنسيق",
|
||||
"autoSave.latest": "تم تحميل أحدث إصدار",
|
||||
"autoSave.saved": "تم الحفظ",
|
||||
"autoSave.saving": "يتم الحفظ تلقائيًا...",
|
||||
"cancel": "إلغاء",
|
||||
"codemirror.copyFailed": "فشل النسخ",
|
||||
"codemirror.copySuccess": "تم نسخ الكود إلى الحافظة",
|
||||
"codemirror.selectLanguage": "اختر اللغة",
|
||||
"codemirror.selectTheme": "اختر السمة",
|
||||
"codemirror.showLineNumbers": "إظهار أرقام الأسطر",
|
||||
"codemirror.tabSize": "حجم التبويب",
|
||||
"codemirror.theme": "السمة",
|
||||
"codemirror.useTabs": "استخدام التبويبات",
|
||||
"confirm": "تأكيد",
|
||||
"file.error": "خطأ: {{message}}",
|
||||
"file.uploading": "جاري رفع الملف...",
|
||||
@@ -23,44 +15,44 @@
|
||||
"link.editLinkTitle": "الرابط",
|
||||
"link.editTextTitle": "العنوان",
|
||||
"link.open": "فتح الرابط",
|
||||
"link.placeholder": "أدخل عنوان الرابط",
|
||||
"link.placeholder": "أدخل عنوان URL للرابط",
|
||||
"link.unlink": "إزالة الرابط",
|
||||
"markdown.cancel": "إلغاء",
|
||||
"markdown.confirm": "تحويل",
|
||||
"markdown.parseMessage": "سيتم التحويل إلى تنسيق Markdown. سيتم استبدال المحتوى الحالي. هل أنت متأكد؟ (سيُغلق تلقائيًا خلال 5 ثوانٍ)",
|
||||
"markdown.parseTitle": "تنسيق كـ Markdown",
|
||||
"math.placeholder": "يرجى إدخال صيغة TeX",
|
||||
"modifier.accept": "الاحتفاظ",
|
||||
"modifier.acceptAll": "الاحتفاظ بالجميع",
|
||||
"modifier.reject": "تراجع",
|
||||
"modifier.rejectAll": "تراجع عن الكل",
|
||||
"slash.h1": "عنوان 1",
|
||||
"slash.h2": "عنوان 2",
|
||||
"slash.h3": "عنوان 3",
|
||||
"slash.hr": "فاصل",
|
||||
"markdown.parseMessage": "سيتم تحويل المحتوى إلى تنسيق Markdown، وسيتم استبدال المحتوى الحالي. هل ترغب في المتابعة؟ (سيُغلق تلقائيًا بعد 5 ثوانٍ)",
|
||||
"markdown.parseTitle": "تنسيق Markdown",
|
||||
"math.placeholder": "يرجى إدخال معادلة TeX",
|
||||
"modifier.accept": "احتفاظ",
|
||||
"modifier.acceptAll": "قبول الكل",
|
||||
"modifier.reject": "إلغاء",
|
||||
"modifier.rejectAll": "إلغاء الكل",
|
||||
"slash.h1": "عنوان رئيسي من المستوى الأول",
|
||||
"slash.h2": "عنوان فرعي من المستوى الثاني",
|
||||
"slash.h3": "عنوان فرعي من المستوى الثالث",
|
||||
"slash.hr": "خط فاصل",
|
||||
"slash.table": "جدول",
|
||||
"slash.tex": "صيغة TeX",
|
||||
"slash.tex": "معادلة TeX",
|
||||
"table.delete": "حذف الجدول",
|
||||
"table.deleteColumn": "حذف العمود",
|
||||
"table.deleteRow": "حذف الصف",
|
||||
"table.insertColumnLeft": "إدراج {{count}} عمود إلى اليسار",
|
||||
"table.insertColumnRight": "إدراج {{count}} عمود إلى اليمين",
|
||||
"table.insertRowAbove": "إدراج {{count}} صف أعلى",
|
||||
"table.insertRowBelow": "إدراج {{count}} صف أسفل",
|
||||
"table.insertColumnLeft": "إدراج {{count}} عمودًا إلى اليسار",
|
||||
"table.insertColumnRight": "إدراج {{count}} عمودًا إلى اليمين",
|
||||
"table.insertRowAbove": "إدراج {{count}} صفًا في الأعلى",
|
||||
"table.insertRowBelow": "إدراج {{count}} صفًا في الأسفل",
|
||||
"typobar.blockquote": "اقتباس",
|
||||
"typobar.bold": "عريض",
|
||||
"typobar.bold": "غامق",
|
||||
"typobar.bulletList": "قائمة نقطية",
|
||||
"typobar.code": "كود مضمّن",
|
||||
"typobar.code": "كود مضمن",
|
||||
"typobar.codeblock": "كتلة كود",
|
||||
"typobar.image": "صورة",
|
||||
"typobar.italic": "مائل",
|
||||
"typobar.link": "رابط",
|
||||
"typobar.numberList": "قائمة مرقمة",
|
||||
"typobar.redo": "إعادة",
|
||||
"typobar.strikethrough": "يتوسطه خط",
|
||||
"typobar.strikethrough": "شطب",
|
||||
"typobar.table": "جدول",
|
||||
"typobar.taskList": "قائمة مهام",
|
||||
"typobar.tex": "صيغة TeX",
|
||||
"typobar.underline": "تحته خط",
|
||||
"typobar.taskList": "قائمة المهام",
|
||||
"typobar.tex": "معادلة TeX",
|
||||
"typobar.underline": "تسطير",
|
||||
"typobar.undo": "تراجع"
|
||||
}
|
||||
|
||||
+53
-53
@@ -1,92 +1,92 @@
|
||||
{
|
||||
"notification.finishChatGeneration": "اكتمل توليد الرسالة بواسطة الذكاء الاصطناعي",
|
||||
"notification.finishChatGeneration": "تم إنشاء رسالة الذكاء الاصطناعي بنجاح",
|
||||
"proxy.auth": "يتطلب المصادقة",
|
||||
"proxy.authDesc": "إذا كان خادم البروكسي يتطلب اسم مستخدم وكلمة مرور",
|
||||
"proxy.authDesc": "إذا كان خادم الوكيل يتطلب اسم مستخدم وكلمة مرور",
|
||||
"proxy.authSettings": "إعدادات المصادقة",
|
||||
"proxy.basicSettings": "إعدادات البروكسي",
|
||||
"proxy.basicSettingsDesc": "قم بتكوين معلمات الاتصال لخادم البروكسي",
|
||||
"proxy.bypass": "العناوين التي لا تستخدم البروكسي",
|
||||
"proxy.basicSettings": "إعدادات الوكيل",
|
||||
"proxy.basicSettingsDesc": "تكوين معلمات اتصال خادم الوكيل",
|
||||
"proxy.bypass": "العناوين التي لا تستخدم الوكيل",
|
||||
"proxy.connectionTest": "اختبار الاتصال",
|
||||
"proxy.enable": "تفعيل البروكسي",
|
||||
"proxy.enableDesc": "عند التفعيل، سيتم توجيه الوصول إلى الشبكة عبر خادم البروكسي",
|
||||
"proxy.enable": "تفعيل الوكيل",
|
||||
"proxy.enableDesc": "عند التفعيل، سيتم الوصول إلى الشبكة عبر خادم الوكيل",
|
||||
"proxy.password": "كلمة المرور",
|
||||
"proxy.password_placeholder": "يرجى إدخال كلمة المرور",
|
||||
"proxy.password_placeholder": "الرجاء إدخال كلمة المرور",
|
||||
"proxy.port": "المنفذ",
|
||||
"proxy.resetButton": "إعادة تعيين",
|
||||
"proxy.saveButton": "حفظ",
|
||||
"proxy.saveFailed": "فشل الحفظ: {{error}}",
|
||||
"proxy.saveSuccess": "تم حفظ إعدادات البروكسي بنجاح",
|
||||
"proxy.saveSuccess": "تم حفظ إعدادات الوكيل بنجاح",
|
||||
"proxy.server": "عنوان الخادم",
|
||||
"proxy.testButton": "اختبار الاتصال",
|
||||
"proxy.testDescription": "اختبر الاتصال باستخدام إعدادات البروكسي الحالية للتحقق من عمله بشكل صحيح",
|
||||
"proxy.testDescription": "اختبر الاتصال باستخدام إعدادات الوكيل الحالية للتحقق من صحة التكوين",
|
||||
"proxy.testFailed": "فشل الاتصال",
|
||||
"proxy.testSuccessWithTime": "نجح اختبار الاتصال، استغرق {{time}} مللي ثانية",
|
||||
"proxy.testUrl": "رابط الاختبار",
|
||||
"proxy.testUrlPlaceholder": "يرجى إدخال الرابط للاختبار",
|
||||
"proxy.testSuccessWithTime": "تم اختبار الاتصال بنجاح، استغرق {{time}} مللي ثانية",
|
||||
"proxy.testUrl": "عنوان الاختبار",
|
||||
"proxy.testUrlPlaceholder": "الرجاء إدخال عنوان URL للاختبار",
|
||||
"proxy.testing": "جارٍ اختبار الاتصال...",
|
||||
"proxy.type": "نوع البروكسي",
|
||||
"proxy.type": "نوع الوكيل",
|
||||
"proxy.unsavedChanges": "لديك تغييرات غير محفوظة",
|
||||
"proxy.username": "اسم المستخدم",
|
||||
"proxy.username_placeholder": "يرجى إدخال اسم المستخدم",
|
||||
"proxy.username_placeholder": "الرجاء إدخال اسم المستخدم",
|
||||
"proxy.validation.passwordRequired": "كلمة المرور مطلوبة عند تفعيل المصادقة",
|
||||
"proxy.validation.portInvalid": "يجب أن يكون المنفذ رقماً بين 1 و65535",
|
||||
"proxy.validation.portRequired": "المنفذ مطلوب عند تفعيل البروكسي",
|
||||
"proxy.validation.portInvalid": "يجب أن يكون المنفذ رقمًا بين 1 و 65535",
|
||||
"proxy.validation.portRequired": "المنفذ مطلوب عند تفعيل الوكيل",
|
||||
"proxy.validation.serverInvalid": "يرجى إدخال عنوان خادم صالح (IP أو اسم نطاق)",
|
||||
"proxy.validation.serverRequired": "عنوان الخادم مطلوب عند تفعيل البروكسي",
|
||||
"proxy.validation.typeRequired": "نوع البروكسي مطلوب عند تفعيل البروكسي",
|
||||
"proxy.validation.serverRequired": "عنوان الخادم مطلوب عند تفعيل الوكيل",
|
||||
"proxy.validation.typeRequired": "نوع الوكيل مطلوب عند تفعيل الوكيل",
|
||||
"proxy.validation.usernameRequired": "اسم المستخدم مطلوب عند تفعيل المصادقة",
|
||||
"remoteServer.authError": "فشل التفويض: {{error}}",
|
||||
"remoteServer.authPending": "يرجى إكمال التفويض في المتصفح",
|
||||
"remoteServer.configDesc": "اتصل بخادم LobeHub البعيد لتمكين مزامنة البيانات",
|
||||
"remoteServer.configDesc": "الاتصال بخادم LobeChat البعيد، تمكين مزامنة البيانات",
|
||||
"remoteServer.configError": "خطأ في التكوين",
|
||||
"remoteServer.configTitle": "تكوين المزامنة السحابية",
|
||||
"remoteServer.connect": "اتصل وفعّل التفويض",
|
||||
"remoteServer.connect": "الاتصال والتفويض",
|
||||
"remoteServer.connected": "متصل",
|
||||
"remoteServer.disconnect": "قطع الاتصال",
|
||||
"remoteServer.disconnectError": "فشل في قطع الاتصال",
|
||||
"remoteServer.disconnected": "غير متصل",
|
||||
"remoteServer.fetchError": "فشل في جلب التكوين",
|
||||
"remoteServer.invalidUrl": "يرجى إدخال رابط صالح",
|
||||
"remoteServer.invalidUrl": "يرجى إدخال عنوان URL صالح",
|
||||
"remoteServer.serverUrl": "عنوان الخادم",
|
||||
"remoteServer.statusConnected": "متصل",
|
||||
"remoteServer.statusDisconnected": "غير متصل",
|
||||
"remoteServer.urlRequired": "يرجى إدخال عنوان الخادم",
|
||||
"sync.continue": "متابعة",
|
||||
"sync.inCloud": "يتم استخدام المزامنة السحابية حالياً",
|
||||
"sync.inLocalStorage": "يتم استخدام التخزين المحلي حالياً",
|
||||
"sync.continue": "استمر",
|
||||
"sync.inCloud": "تستخدم حاليًا المزامنة السحابية",
|
||||
"sync.inLocalStorage": "تستخدم حاليًا التخزين المحلي",
|
||||
"sync.isIniting": "جارٍ التهيئة...",
|
||||
"sync.lobehubCloud.description": "الإصدار السحابي الرسمي المقدم",
|
||||
"sync.lobehubCloud.title": "سحابة LobeHub",
|
||||
"sync.local.description": "يستخدم قاعدة بيانات محلية، متاح بالكامل دون اتصال",
|
||||
"sync.local.title": "قاعدة البيانات المحلية",
|
||||
"sync.lobehubCloud.description": "الإصدار السحابي المقدم رسميًا",
|
||||
"sync.lobehubCloud.title": "LobeHub Cloud",
|
||||
"sync.local.description": "استخدام قاعدة بيانات محلية، متاحة بالكامل دون اتصال",
|
||||
"sync.local.title": "قاعدة بيانات محلية",
|
||||
"sync.mode.cloudSync": "مزامنة سحابية",
|
||||
"sync.mode.localStorage": "تخزين محلي",
|
||||
"sync.mode.title": "اختر وضع الاتصال",
|
||||
"sync.mode.useSelfHosted": "هل تريد استخدام نسخة مستضافة ذاتياً؟",
|
||||
"sync.selfHosted.description": "نسخة المجتمع التي يمكنك نشرها بنفسك",
|
||||
"sync.selfHosted.title": "نسخة مستضافة ذاتياً",
|
||||
"updater.checkingUpdate": "جارٍ التحقق من التحديثات",
|
||||
"updater.checkingUpdateDesc": "جارٍ جلب معلومات الإصدار...",
|
||||
"updater.downloadNewVersion": "تحميل الإصدار الجديد",
|
||||
"updater.downloadingUpdate": "جارٍ تحميل التحديث",
|
||||
"updater.downloadingUpdateDesc": "جارٍ تحميل التحديث، يرجى الانتظار...",
|
||||
"updater.installLater": "تثبيت التحديث عند التشغيل التالي",
|
||||
"updater.isLatestVersion": "أنت تستخدم أحدث إصدار",
|
||||
"updater.isLatestVersionDesc": "رائع! الإصدار {{version}} الذي تستخدمه هو الأحدث المتاح.",
|
||||
"updater.later": "لاحقاً",
|
||||
"updater.newVersionAvailable": "إصدار جديد متاح",
|
||||
"updater.newVersionAvailableDesc": "تم العثور على إصدار جديد {{version}}، هل ترغب في تحميله الآن؟",
|
||||
"updater.restartAndInstall": "تثبيت التحديثات وإعادة التشغيل",
|
||||
"sync.mode.title": "اختر وضع الاتصال الخاص بك",
|
||||
"sync.mode.useSelfHosted": "استخدام نسخة مستضافة ذاتيًا؟",
|
||||
"sync.selfHosted.description": "نسخة المجتمع التي تم نشرها ذاتيًا",
|
||||
"sync.selfHosted.title": "نسخة مستضافة ذاتيًا",
|
||||
"updater.checkingUpdate": "التحقق من وجود تحديثات",
|
||||
"updater.checkingUpdateDesc": "جارٍ الحصول على معلومات الإصدار...",
|
||||
"updater.downloadNewVersion": "تحميل إصدار جديد",
|
||||
"updater.downloadingUpdate": "جارٍ تنزيل التحديث",
|
||||
"updater.downloadingUpdateDesc": "يتم تنزيل التحديث، يرجى الانتظار...",
|
||||
"updater.installLater": "تحديث عند بدء التشغيل التالي",
|
||||
"updater.isLatestVersion": "الإصدار الحالي هو الأحدث",
|
||||
"updater.isLatestVersionDesc": "رائع، الإصدار {{version}} الذي تستخدمه هو أحدث إصدار متاح.",
|
||||
"updater.later": "لاحقًا",
|
||||
"updater.newVersionAvailable": "يتوفر إصدار جديد",
|
||||
"updater.newVersionAvailableDesc": "تم العثور على إصدار جديد {{version}}، هل ترغب في التنزيل الآن؟",
|
||||
"updater.restartAndInstall": "تثبيت التحديث وإعادة التشغيل",
|
||||
"updater.updateError": "خطأ في التحديث",
|
||||
"updater.updateReady": "إصدار جديد متاح",
|
||||
"updater.updateReadyDesc": "تم تحميل الإصدار الجديد {{version}}. أعد تشغيل التطبيق لإكمال التثبيت.",
|
||||
"updater.updateReady": "يتوفر إصدار جديد",
|
||||
"updater.updateReadyDesc": "تم تنزيل الإصدار الجديد {{version}}، يمكنك إكمال التثبيت بعد إعادة تشغيل التطبيق.",
|
||||
"updater.upgradeNow": "تحديث الآن",
|
||||
"updater.willInstallLater": "سيتم تثبيت التحديث عند التشغيل التالي",
|
||||
"updater.willInstallLater": "سيتم تثبيت التحديث عند بدء التشغيل التالي",
|
||||
"waitingOAuth.cancel": "إلغاء",
|
||||
"waitingOAuth.description": "تم فتح صفحة التفويض في المتصفح، يرجى إكمال التفويض هناك",
|
||||
"waitingOAuth.description": "تم فتح صفحة التفويض في المتصفح، يرجى إكمال التفويض في المتصفح",
|
||||
"waitingOAuth.error": "فشل التفويض: {{error}}",
|
||||
"waitingOAuth.errorTitle": "فشل الاتصال بالتفويض",
|
||||
"waitingOAuth.helpText": "إذا لم يفتح المتصفح تلقائياً، يرجى النقر على إلغاء والمحاولة مرة أخرى",
|
||||
"waitingOAuth.retry": "إعادة المحاولة",
|
||||
"waitingOAuth.title": "في انتظار الاتصال بالتفويض"
|
||||
"waitingOAuth.errorTitle": "فشل في الاتصال بالتفويض",
|
||||
"waitingOAuth.helpText": "إذا لم يفتح المتصفح تلقائيًا، يرجى النقر على إلغاء ثم المحاولة مرة أخرى",
|
||||
"waitingOAuth.retry": "أعد المحاولة",
|
||||
"waitingOAuth.title": "انتظار الاتصال بالتفويض"
|
||||
}
|
||||
|
||||
+127
-128
@@ -1,148 +1,147 @@
|
||||
{
|
||||
"clerkAuth.loginSuccess.action": "متابعة الجلسة",
|
||||
"clerkAuth.loginSuccess.desc": "{{greeting}}، يسعدنا الاستمرار في خدمتك. لنكمل من حيث توقفنا.",
|
||||
"clerkAuth.loginSuccess.action": "استمر في الجلسة",
|
||||
"clerkAuth.loginSuccess.desc": "{{greeting}}، يسعدني أن أواصل خدمتك. دعنا نواصل الحديث عن الموضوع الذي تحدثنا عنه مؤخرًا",
|
||||
"clerkAuth.loginSuccess.title": "مرحبًا بعودتك، {{nickName}}",
|
||||
"error.backHome": "العودة إلى الصفحة الرئيسية",
|
||||
"error.desc": "حاول مرة أخرى لاحقًا، أو عد إلى العالم المعروف.",
|
||||
"error.desc": "حاول مرة أخرى في وقت لاحق، أو عد إلى العالم المألوف",
|
||||
"error.retry": "إعادة التحميل",
|
||||
"error.title": "عذرًا، حدث خطأ ما..",
|
||||
"error.title": "واجهت الصفحة مشكلة ما..",
|
||||
"fetchError.detail": "تفاصيل الخطأ",
|
||||
"fetchError.title": "فشل الطلب",
|
||||
"import.importConfigFile.description": "سبب الخطأ: {{reason}}",
|
||||
"import.importConfigFile.title": "فشل الاستيراد",
|
||||
"import.incompatible.description": "تم تصدير هذا الملف من إصدار أحدث. يرجى الترقية إلى أحدث إصدار ثم إعادة الاستيراد.",
|
||||
"import.incompatible.description": "تم تصدير هذا الملف من إصدار أعلى، يرجى محاولة الترقية إلى أحدث إصدار ثم إعادة الاستيراد",
|
||||
"import.incompatible.title": "التطبيق الحالي لا يدعم استيراد هذا الملف",
|
||||
"loginRequired.desc": "سيتم تحويلك إلى صفحة تسجيل الدخول قريبًا",
|
||||
"loginRequired.desc": "سيتم التحويل تلقائيًا إلى صفحة تسجيل الدخول",
|
||||
"loginRequired.title": "يرجى تسجيل الدخول لاستخدام هذه الميزة",
|
||||
"notFound.backHome": "العودة إلى الصفحة الرئيسية",
|
||||
"notFound.check": "يرجى التحقق من صحة عنوان URL.",
|
||||
"notFound.desc": "لم نتمكن من العثور على الصفحة التي تبحث عنها.",
|
||||
"notFound.title": "هل دخلت منطقة غير معروفة؟",
|
||||
"pluginSettings.desc": "أكمل الإعدادات التالية لبدء استخدام هذه المهارة",
|
||||
"pluginSettings.title": "إعدادات مهارة {{name}}",
|
||||
"response.400": "عذرًا، الخادم لا يفهم طلبك. يرجى التأكد من صحة معلمات الطلب.",
|
||||
"response.401": "عذرًا، تم رفض طلبك من قبل الخادم، ربما بسبب عدم كفاية الصلاحيات أو فشل التوثيق.",
|
||||
"response.403": "عذرًا، تم رفض طلبك. ليس لديك إذن للوصول إلى هذا المحتوى.",
|
||||
"response.404": "عذرًا، لم يتم العثور على الصفحة أو المورد المطلوب. يرجى التأكد من صحة عنوان URL.",
|
||||
"response.405": "عذرًا، لا يدعم الخادم طريقة الطلب المستخدمة. يرجى التأكد من صحة طريقة الطلب.",
|
||||
"response.406": "عذرًا، لا يمكن للخادم إكمال الطلب بناءً على خصائص المحتوى المطلوب.",
|
||||
"response.407": "عذرًا، تحتاج إلى توثيق الوكيل قبل متابعة هذا الطلب.",
|
||||
"response.408": "عذرًا، انتهت مهلة الخادم أثناء انتظار الطلب. يرجى التحقق من اتصالك بالشبكة والمحاولة مرة أخرى.",
|
||||
"response.409": "عذرًا، لا يمكن معالجة الطلب بسبب تعارض، ربما بسبب حالة المورد غير المتوافقة مع الطلب.",
|
||||
"response.410": "عذرًا، تم حذف المورد المطلوب بشكل دائم ولا يمكن العثور عليه.",
|
||||
"response.411": "عذرًا، لا يمكن للخادم معالجة الطلب بدون طول محتوى صالح.",
|
||||
"response.412": "عذرًا، لا يستوفي طلبك شروط الخادم ولا يمكن إكماله.",
|
||||
"response.413": "عذرًا، بيانات الطلب كبيرة جدًا ولا يمكن معالجتها من قبل الخادم.",
|
||||
"response.414": "عذرًا، عنوان URI الخاص بطلبك طويل جدًا ولا يمكن معالجته.",
|
||||
"response.415": "عذرًا، لا يمكن للخادم معالجة تنسيق الوسائط المرفق بالطلب.",
|
||||
"response.416": "عذرًا، لا يمكن للخادم تلبية نطاق طلبك.",
|
||||
"response.417": "عذرًا، لا يمكن للخادم تلبية توقعاتك.",
|
||||
"response.422": "عذرًا، تنسيق الطلب صحيح، ولكن لا يمكن الرد عليه بسبب أخطاء دلالية.",
|
||||
"response.423": "عذرًا، المورد المطلوب مقفل.",
|
||||
"response.424": "عذرًا، لا يمكن إكمال الطلب الحالي بسبب فشل في طلب سابق.",
|
||||
"response.426": "عذرًا، يتطلب الخادم ترقية إصدار البروتوكول المستخدم.",
|
||||
"response.428": "عذرًا، يتطلب الخادم شرطًا مسبقًا، ويجب أن يحتوي طلبك على ترويسة شرطية صحيحة.",
|
||||
"response.429": "عذرًا، طلباتك متكررة جدًا والخادم مرهق. يرجى المحاولة لاحقًا.",
|
||||
"response.431": "عذرًا، حقول الترويسة في طلبك كبيرة جدًا ولا يمكن معالجتها.",
|
||||
"response.451": "عذرًا، يرفض الخادم توفير هذا المورد لأسباب قانونية.",
|
||||
"response.499": "نعتذر، تم قطع طلبك بشكل غير متوقع أثناء معالجته من قبل الخادم، ربما بسبب إلغاء العملية أو ضعف الاتصال. يرجى التحقق من الشبكة والمحاولة مجددًا.",
|
||||
"response.500": "عذرًا، يبدو أن الخادم يواجه صعوبات مؤقتة ولا يمكنه إكمال طلبك. يرجى المحاولة لاحقًا.",
|
||||
"response.501": "عذرًا، لا يعرف الخادم كيفية معالجة هذا الطلب بعد. يرجى التأكد من صحة العملية.",
|
||||
"response.502": "عذرًا، يبدو أن الخادم غير متصل مؤقتًا ولا يمكنه تقديم الخدمة. يرجى المحاولة لاحقًا.",
|
||||
"response.503": "عذرًا، لا يمكن للخادم حاليًا معالجة طلبك، ربما بسبب الحمل الزائد أو الصيانة. يرجى المحاولة لاحقًا.",
|
||||
"response.504": "عذرًا، لم يتلق الخادم ردًا من الخادم العلوي. يرجى المحاولة لاحقًا.",
|
||||
"response.505": "عذرًا، لا يدعم الخادم إصدار HTTP الذي تستخدمه. يرجى التحديث والمحاولة مجددًا.",
|
||||
"response.506": "عذرًا، هناك مشكلة في إعدادات الخادم. يرجى التواصل مع المسؤول لحل المشكلة.",
|
||||
"response.507": "عذرًا، لا توجد مساحة تخزين كافية على الخادم لمعالجة طلبك. يرجى المحاولة لاحقًا.",
|
||||
"response.509": "عذرًا، تم استهلاك عرض النطاق الترددي للخادم. يرجى المحاولة لاحقًا.",
|
||||
"response.510": "عذرًا، لا يدعم الخادم الامتداد المطلوب. يرجى التواصل مع المسؤول.",
|
||||
"response.520": "نعتذر، واجه الخادم مشكلة غير متوقعة منعته من إكمال طلبك. يرجى المحاولة لاحقًا، نحن نعمل على حل المشكلة.",
|
||||
"response.522": "نعتذر، انتهت مهلة الاتصال بالخادم ولم يتمكن من الرد في الوقت المناسب. قد يكون السبب ضعف الشبكة أو تعذر الوصول المؤقت. يرجى المحاولة لاحقًا.",
|
||||
"response.524": "نعتذر، انتهت مهلة الخادم أثناء انتظار الرد، ربما بسبب بطء الاستجابة. يرجى المحاولة لاحقًا.",
|
||||
"response.AgentRuntimeError": "حدث خطأ أثناء تنفيذ نموذج Lobe. يرجى التحقق أو إعادة المحاولة بناءً على المعلومات التالية.",
|
||||
"response.ComfyUIBizError": "حدث خطأ أثناء طلب خدمة ComfyUI. يرجى التحقق من المعلومات أدناه أو إعادة المحاولة.",
|
||||
"response.ComfyUIEmptyResult": "لم يتم إنشاء أي صورة بواسطة ComfyUI. يرجى التحقق من إعدادات النموذج أو إعادة المحاولة.",
|
||||
"response.ComfyUIModelError": "فشل تحميل نموذج ComfyUI. يرجى التأكد من وجود ملف النموذج.",
|
||||
"response.ComfyUIServiceUnavailable": "فشل الاتصال بخدمة ComfyUI. يرجى التأكد من أنها تعمل بشكل صحيح وأن عنوان الخدمة مضبوط بشكل صحيح.",
|
||||
"response.ComfyUIUploadFailed": "فشل تحميل الصورة إلى ComfyUI. يرجى التحقق من الاتصال بالخادم أو إعادة المحاولة.",
|
||||
"response.ComfyUIWorkflowError": "فشل تنفيذ سير عمل ComfyUI. يرجى التحقق من إعدادات سير العمل.",
|
||||
"response.ConnectionCheckFailed": "الطلب أعاد نتيجة فارغة. يرجى التحقق من أن عنوان وكيل API لا ينتهي بـ `/v1`.",
|
||||
"response.CreateMessageError": "عذرًا، لم يتم إرسال الرسالة بنجاح. يرجى نسخ المحتوى والمحاولة مرة أخرى. لن يتم الاحتفاظ بهذه الرسالة بعد تحديث الصفحة.",
|
||||
"response.ExceededContextWindow": "يتجاوز محتوى الطلب الحالي الحد الأقصى الذي يمكن للنموذج معالجته. يرجى تقليل المحتوى والمحاولة مجددًا.",
|
||||
"response.FreePlanLimit": "أنت تستخدم الخطة المجانية حاليًا ولا يمكنك استخدام هذه الميزة. يرجى الترقية إلى خطة مدفوعة للمتابعة.",
|
||||
"response.GoogleAIBlockReason.BLOCKLIST": "يحتوي المحتوى الخاص بك على مصطلحات محظورة. يرجى مراجعة مدخلاتك وتعديلها ثم المحاولة مجددًا.",
|
||||
"response.GoogleAIBlockReason.IMAGE_SAFETY": "تم حظر الصورة المُولدة لأسباب تتعلق بالسلامة. يرجى تعديل طلب الصورة.",
|
||||
"response.GoogleAIBlockReason.LANGUAGE": "اللغة المستخدمة غير مدعومة. يرجى المحاولة باللغة الإنجليزية أو بلغة مدعومة أخرى.",
|
||||
"response.GoogleAIBlockReason.OTHER": "تم حظر المحتوى لسبب غير معروف. يرجى إعادة صياغة الطلب والمحاولة مجددًا.",
|
||||
"response.GoogleAIBlockReason.PROHIBITED_CONTENT": "قد يحتوي طلبك على محتوى محظور. يرجى تعديل الطلب ليتوافق مع إرشادات الاستخدام.",
|
||||
"response.GoogleAIBlockReason.RECITATION": "تم حظر المحتوى بسبب مخاوف تتعلق بحقوق النشر. يرجى استخدام محتوى أصلي أو إعادة صياغة الطلب.",
|
||||
"response.GoogleAIBlockReason.SAFETY": "تم حظر المحتوى لأسباب تتعلق بسياسة السلامة. يرجى تعديل الطلب لتجنب المحتوى الضار أو غير المناسب.",
|
||||
"response.GoogleAIBlockReason.SPII": "قد يحتوي المحتوى الخاص بك على معلومات تعريف شخصية حساسة. لحماية الخصوصية، يرجى إزالة التفاصيل الحساسة والمحاولة مجددًا.",
|
||||
"response.GoogleAIBlockReason.default": "تم حظر المحتوى: {{blockReason}}. يرجى تعديل الطلب والمحاولة مجددًا.",
|
||||
"response.InsufficientQuota": "عذرًا، تم استهلاك الحصة المخصصة لهذا المفتاح. يرجى التحقق من رصيد حسابك أو زيادة الحصة والمحاولة مجددًا.",
|
||||
"response.InvalidAccessCode": "رمز الوصول غير صالح أو فارغ. يرجى إدخال رمز الوصول الصحيح أو إضافة مفتاح API مخصص.",
|
||||
"response.InvalidBedrockCredentials": "فشل التوثيق مع Bedrock. يرجى التحقق من AccessKeyId/SecretAccessKey والمحاولة مجددًا.",
|
||||
"response.InvalidClerkUser": "عذرًا، لم تقم بتسجيل الدخول حاليًا. يرجى تسجيل الدخول أو إنشاء حساب للمتابعة.",
|
||||
"response.InvalidComfyUIArgs": "إعدادات ComfyUI غير صالحة. يرجى التحقق من الإعدادات والمحاولة مجددًا.",
|
||||
"response.InvalidGithubToken": "رمز GitHub الشخصي غير صحيح أو فارغ. يرجى التحقق من الرمز والمحاولة مجددًا.",
|
||||
"response.InvalidOllamaArgs": "إعدادات Ollama غير صالحة، يرجى التحقق منها والمحاولة مجددًا.",
|
||||
"response.InvalidProviderAPIKey": "مفتاح API الخاص بـ {{provider}} غير صحيح أو فارغ، يرجى التحقق منه والمحاولة مجددًا.",
|
||||
"response.InvalidVertexCredentials": "فشل التوثيق مع Vertex. يرجى التحقق من بيانات الاعتماد والمحاولة مجددًا.",
|
||||
"response.LocationNotSupportError": "نعتذر، لا يدعم موقعك الحالي هذه الخدمة. قد يكون ذلك بسبب قيود إقليمية أو عدم توفر الخدمة. يرجى التأكد من دعم الموقع الحالي أو المحاولة من موقع مختلف.",
|
||||
"response.ModelNotFound": "عذرًا، لم يتم العثور على النموذج المطلوب. قد لا يكون موجودًا أو ليس لديك صلاحية الوصول. يرجى المحاولة بعد تغيير مفتاح API أو تعديل الصلاحيات.",
|
||||
"response.NoOpenAIAPIKey": "مفتاح OpenAI API فارغ، يرجى إضافة مفتاح API مخصص.",
|
||||
"response.OllamaBizError": "حدث خطأ أثناء طلب خدمة Ollama، يرجى التحقق أو إعادة المحاولة بناءً على المعلومات التالية.",
|
||||
"response.OllamaServiceUnavailable": "خدمة Ollama غير متوفرة. يرجى التحقق من تشغيلها بشكل صحيح أو إعدادات التكوين.",
|
||||
"response.PermissionDenied": "عذرًا، لا تملك صلاحية الوصول إلى هذه الخدمة. يرجى التحقق من صلاحيات المفتاح.",
|
||||
"response.PluginApiNotFound": "عذرًا، لم يتم العثور على API في ملف تعريف المهارة. يرجى التحقق من تطابق طريقة الطلب مع API المعرفة.",
|
||||
"response.PluginApiParamsError": "عذرًا، فشل التحقق من معلمات الطلب للمهارة. يرجى التحقق من تطابق المعلمات مع وصف API.",
|
||||
"response.PluginFailToTransformArguments": "عذرًا، فشلت المهارة في تحليل المعلمات. يرجى إعادة إنشاء رسالة الوكيل أو استخدام نموذج AI أقوى يدعم استدعاء الأدوات.",
|
||||
"response.PluginGatewayError": "عذرًا، حدث خطأ في بوابة المهارة. يرجى التحقق من إعدادات البوابة.",
|
||||
"response.PluginManifestInvalid": "عذرًا، فشل التحقق من ملف تعريف المهارة. يرجى التحقق من صحة التنسيق.",
|
||||
"response.PluginManifestNotFound": "عذرًا، لم يتم العثور على ملف تعريف المهارة (manifest.json). يرجى التحقق من العنوان.",
|
||||
"response.PluginMarketIndexInvalid": "عذرًا، فشل التحقق من فهرس المهارة. يرجى التحقق من تنسيق الملف.",
|
||||
"response.PluginMarketIndexNotFound": "عذرًا، لم يتم العثور على فهرس المهارة. يرجى التحقق من العنوان.",
|
||||
"response.PluginMetaInvalid": "عذرًا، فشل التحقق من بيانات المهارة. يرجى التحقق من التنسيق.",
|
||||
"response.PluginMetaNotFound": "عذرًا، لم يتم العثور على المهارة في الفهرس. يرجى التحقق من إعدادات المهارة.",
|
||||
"response.PluginOpenApiInitError": "عذرًا، فشل تهيئة عميل OpenAPI. يرجى التحقق من إعدادات OpenAPI.",
|
||||
"response.PluginServerError": "أعاد خادم المهارة خطأ. يرجى التحقق من ملف تعريف المهارة أو إعدادات الخادم.",
|
||||
"response.PluginSettingsInvalid": "تتطلب هذه المهارة إعدادًا صحيحًا قبل الاستخدام. يرجى التحقق من الإعدادات.",
|
||||
"response.ProviderBizError": "حدث خطأ أثناء طلب خدمة {{provider}}، يرجى التحقق أو إعادة المحاولة.",
|
||||
"response.QuotaLimitReached": "عذرًا، تم الوصول إلى الحد الأقصى لاستخدام الرموز أو عدد الطلبات لهذا المفتاح. يرجى زيادة الحصة أو المحاولة لاحقًا.",
|
||||
"response.ServerAgentRuntimeError": "عذرًا، خدمة الوكيل غير متوفرة حاليًا. يرجى المحاولة لاحقًا أو التواصل معنا عبر البريد الإلكتروني.",
|
||||
"response.StreamChunkError": "حدث خطأ أثناء تحليل جزء الرسالة من الطلب المتدفق. يرجى التحقق من توافق واجهة API أو التواصل مع مزود الخدمة.",
|
||||
"response.SubscriptionKeyMismatch": "نعتذر عن الإزعاج. بسبب خلل مؤقت في النظام، اشتراكك غير نشط حاليًا. يرجى النقر على الزر أدناه لاستعادته أو التواصل معنا عبر البريد الإلكتروني.",
|
||||
"response.SubscriptionPlanLimit": "تم استنفاد نقاط اشتراكك، ولا يمكنك استخدام هذه الميزة. يرجى الترقية إلى خطة أعلى أو إعداد API مخصص.",
|
||||
"response.SubscriptionPlanLimitUltimate": "تم استنفاد نقاط اشتراكك، ولا يمكنك استخدام هذه الميزة. يرجى شحن الرصيد أو إعداد API مخصص.",
|
||||
"response.SystemTimeNotMatchError": "عذرًا، لا يتطابق وقت نظامك مع الخادم. يرجى التحقق من الوقت والمحاولة مجددًا.",
|
||||
"response.UnknownChatFetchError": "عذرًا، حدث خطأ غير معروف في الطلب. يرجى التحقق من المعلومات أدناه أو إعادة المحاولة.",
|
||||
"stt.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة.",
|
||||
"supervisor.decisionFailed": "المضيف الجماعي غير قادر على العمل. يرجى التحقق من إعدادات المضيف والتأكد من صحة النموذج ومفتاح API ونقطة النهاية.",
|
||||
"notFound.check": "يرجى التحقق من صحة عنوان URL الخاص بك",
|
||||
"notFound.desc": "لم نتمكن من العثور على الصفحة التي تبحث عنها",
|
||||
"notFound.title": "هل دخلت إلى مجال غير معروف؟",
|
||||
"pluginSettings.desc": "أكمل الإعدادات التالية لبدء استخدام هذا المكون الإضافي",
|
||||
"pluginSettings.title": "تكوين مكون الإضافة {{name}}",
|
||||
"response.400": "عذرًا، الخادم غير قادر على فهم طلبك، يرجى التحقق من صحة معلمات الطلب الخاصة بك",
|
||||
"response.401": "عذرًا، رفض الخادم طلبك، قد يكون بسبب صلاحياتك غير الكافية أو عدم تقديم التحقق من الهوية الصالحة",
|
||||
"response.403": "عذرًا، رفض الخادم طلبك، ليس لديك إذن للوصول إلى هذا المحتوى",
|
||||
"response.404": "عذرًا، الخادم لا يمكنه العثور على الصفحة أو المورد المطلوب، يرجى التحقق من صحة عنوان URL الخاص بك",
|
||||
"response.405": "عذرًا، الخادم لا يدعم طريقة الطلب المستخدمة، يرجى التحقق من صحة طريقة الطلب الخاصة بك",
|
||||
"response.406": "عذرًا، الخادم غير قادر على استكمال الطلب وفقًا لخصائص المحتوى التي طلبتها",
|
||||
"response.407": "عذرًا، تحتاج إلى مصادقة الوكيل لمتابعة هذا الطلب",
|
||||
"response.408": "عذرًا، تجاوز الخادم الوقت المحدد في انتظار الطلب، يرجى التحقق من اتصالك بالشبكة والمحاولة مرة أخرى",
|
||||
"response.409": "عذرًا، يوجد تضارب في الطلب الذي لا يمكن معالجته، قد يكون بسبب عدم توافق حالة المورد مع الطلب",
|
||||
"response.410": "عذرًا، تمت إزالة المورد الذي طلبته بشكل دائم ولا يمكن العثور عليه",
|
||||
"response.411": "عذرًا، الخادم غير قادر على معالجة الطلب الذي لا يحتوي على طول محتوى صالح",
|
||||
"response.412": "عذرًا، لم يتم تلبية شروط الخادم الجانبية لطلبك ولا يمكن استكمال الطلب",
|
||||
"response.413": "عذرًا، حجم بيانات طلبك كبير جدًا والخادم غير قادر على معالجته",
|
||||
"response.414": "عذرًا، طول عنوان URI الخاص بطلبك كبير جدًا والخادم غير قادر على معالجته",
|
||||
"response.415": "عذرًا، الخادم غير قادر على معالجة تنسيق الوسائط المرفقة بالطلب",
|
||||
"response.416": "عذرًا، الخادم غير قادر على تلبية نطاق الطلب الذي قدمته",
|
||||
"response.417": "عذرًا، الخادم غير قادر على تلبية قيم توقعاتك",
|
||||
"response.422": "عذرًا، الطلب لديه تنسيق صحيح، ولكن بسبب وجود أخطاء دلالية، لا يمكن الاستجابة",
|
||||
"response.423": "عذرًا، تم قفل المورد الذي طلبته",
|
||||
"response.424": "عذرًا، بسبب فشل الطلب السابق، لا يمكن استكمال الطلب الحالي",
|
||||
"response.426": "عذرًا، يتطلب الخادم ترقية عميلك إلى إصدار بروتوكول أعلى",
|
||||
"response.428": "عذرًا، يتطلب الخادم شروطًا مسبقة، ويجب أن يحتوي طلبك على رؤوس الشروط الصحيحة",
|
||||
"response.429": "عذرًا، طلبك كثير جدًا والخادم متعب قليلاً، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"response.431": "عذرًا، حقول رأس الطلب الخاصة بك كبيرة جدًا والخادم غير قادر على معالجتها",
|
||||
"response.451": "عذرًا، بسبب الأسباب القانونية، يرفض الخادم توفير هذا المورد",
|
||||
"response.499": "نعتذر، تم قطع طلبك بشكل غير متوقع أثناء معالجته على الخادم، قد يكون ذلك بسبب إلغاء العملية من قبلك أو بسبب عدم استقرار الاتصال بالشبكة. يرجى التحقق من حالة الشبكة ثم إعادة المحاولة.",
|
||||
"response.500": "عذرًا، يبدو أن الخادم واجه بعض الصعوبات ولا يمكنه حاليًا استكمال طلبك، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"response.501": "عذرًا، لا يعرف الخادم كيفية معالجة هذا الطلب، يرجى التأكد من صحة العملية الخاصة بك",
|
||||
"response.502": "عذرًا، يبدو أن الخادم قد ضل الطريق ولا يمكنه حاليًا تقديم الخدمة، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"response.503": "عذرًا، الخادم غير قادر حاليًا على معالجة طلبك، قد يكون بسبب الحمل الزائد أو الصيانة الجارية، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"response.504": "عذرًا، الخادم لم ينتظر ردًا من الخادم الأصلي، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"response.505": "عذرًا، لا يدعم الخادم إصدار HTTP الذي تستخدمه، يرجى التحديث والمحاولة مرة أخرى",
|
||||
"response.506": "عذرًا، هناك مشكلة في تكوين الخادم، يرجى الاتصال بالمسؤول لحلها",
|
||||
"response.507": "عذرًا، لا يوجد مساحة تخزين كافية على الخادم لمعالجة طلبك، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"response.509": "عذرًا، لقد استنفد الخادم النطاق الترددي، يرجى المحاولة مرة أخرى لاحقًا",
|
||||
"response.510": "عذرًا، لا يدعم الخادم الوظائف الإضافية المطلوبة، يرجى الاتصال بالمسؤول",
|
||||
"response.520": "نعتذر، واجه الخادم مشكلة غير متوقعة، مما أدى إلى عدم القدرة على إكمال طلبك. يرجى المحاولة لاحقًا، نحن نعمل على حل هذه المشكلة.",
|
||||
"response.522": "نعتذر، انتهت مهلة الاتصال بالخادم، ولم يتمكن من الاستجابة لطلبك في الوقت المناسب. قد يكون ذلك بسبب عدم استقرار الشبكة أو أن الخادم غير متاح مؤقتًا. يرجى المحاولة لاحقًا، نحن نبذل جهدًا لاستعادة الخدمة.",
|
||||
"response.524": "نعتذر، انتهت مهلة الخادم أثناء انتظار الرد، قد يكون ذلك بسبب بطء الاستجابة، يرجى المحاولة لاحقًا.",
|
||||
"response.AgentRuntimeError": "حدث خطأ في تشغيل نموذج Lobe اللغوي، يرجى التحقق من المعلومات التالية أو إعادة المحاولة",
|
||||
"response.ComfyUIBizError": "حدث خطأ أثناء طلب خدمة ComfyUI، يرجى التحقق من المعلومات التالية أو المحاولة مرة أخرى",
|
||||
"response.ComfyUIEmptyResult": "لم يتم إنشاء أي صورة من قبل ComfyUI، يرجى التحقق من إعدادات النموذج أو المحاولة مرة أخرى",
|
||||
"response.ComfyUIModelError": "فشل تحميل نموذج ComfyUI، يرجى التحقق من وجود ملف النموذج",
|
||||
"response.ComfyUIServiceUnavailable": "فشل الاتصال بخدمة ComfyUI، يرجى التأكد من أن ComfyUI يعمل بشكل صحيح أو التحقق من صحة عنوان الخدمة",
|
||||
"response.ComfyUIUploadFailed": "فشل تحميل الصورة إلى ComfyUI، يرجى التحقق من الاتصال بالخادم أو المحاولة مرة أخرى",
|
||||
"response.ComfyUIWorkflowError": "فشل تنفيذ سير العمل في ComfyUI، يرجى التحقق من إعدادات سير العمل",
|
||||
"response.ConnectionCheckFailed": "الاستجابة فارغة، يرجى التحقق من أن عنوان وكيل الـ API لا ينتهي بـ `/v1`",
|
||||
"response.CreateMessageError": "عذرًا، لم يتم إرسال الرسالة بشكل صحيح، يرجى نسخ المحتوى وإعادة إرساله، بعد تحديث الصفحة لن يتم الاحتفاظ بهذه الرسالة",
|
||||
"response.ExceededContextWindow": "المحتوى المطلوب الحالي يتجاوز الطول الذي يمكن للنموذج معالجته، يرجى تقليل كمية المحتوى ثم إعادة المحاولة",
|
||||
"response.FreePlanLimit": "أنت حاليًا مستخدم مجاني، لا يمكنك استخدام هذه الوظيفة، يرجى الترقية إلى خطة مدفوعة للمتابعة",
|
||||
"response.GoogleAIBlockReason.BLOCKLIST": "يحتوي المحتوى الذي أرسلته على كلمات محظورة. يرجى مراجعته وتعديل مدخلاتك ثم المحاولة مرة أخرى.",
|
||||
"response.GoogleAIBlockReason.IMAGE_SAFETY": "تم حظر المحتوى الصوري الناتج لأسباب تتعلق بالأمان. يرجى محاولة تعديل طلب توليد الصورة.",
|
||||
"response.GoogleAIBlockReason.LANGUAGE": "اللغة التي تستخدمها غير مدعومة مؤقتًا. يرجى المحاولة باللغة الإنجليزية أو بلغة أخرى مدعومة.",
|
||||
"response.GoogleAIBlockReason.OTHER": "تم حظر المحتوى لسبب غير معروف. يرجى محاولة إعادة صياغة طلبك.",
|
||||
"response.GoogleAIBlockReason.PROHIBITED_CONTENT": "قد يحتوي طلبك على محتوى محظور. يرجى تعديل طلبك لضمان توافقه مع سياسات الاستخدام.",
|
||||
"response.GoogleAIBlockReason.RECITATION": "تم حظر محتواك لكونه قد ينتهك حقوق النشر. يرجى محاولة استخدام محتوى أصلي أو إعادة صياغة طلبك.",
|
||||
"response.GoogleAIBlockReason.SAFETY": "تم حظر المحتوى بسبب سياسات السلامة. يرجى تعديل طلبك لتجنب أي محتوى ضار أو غير مناسب.",
|
||||
"response.GoogleAIBlockReason.SPII": "قد يحتوي المحتوى على معلومات شخصية حساسة. لحماية الخصوصية، يرجى إزالة المعلومات الحساسة ثم المحاولة مرة أخرى.",
|
||||
"response.GoogleAIBlockReason.default": "تم حظر المحتوى: {{blockReason}}. يرجى تعديل طلبك ثم المحاولة مرة أخرى.",
|
||||
"response.InsufficientQuota": "عذرًا، لقد تم الوصول إلى الحد الأقصى لحصة المفتاح (quota). يرجى التحقق من رصيد الحساب أو زيادة حصة المفتاح ثم المحاولة مرة أخرى.",
|
||||
"response.InvalidAccessCode": "كلمة المرور غير صحيحة أو فارغة، يرجى إدخال كلمة مرور الوصول الصحيحة أو إضافة مفتاح API مخصص",
|
||||
"response.InvalidBedrockCredentials": "فشلت مصادقة Bedrock، يرجى التحقق من AccessKeyId/SecretAccessKey وإعادة المحاولة",
|
||||
"response.InvalidClerkUser": "عذرًا، لم تقم بتسجيل الدخول بعد، يرجى تسجيل الدخول أو التسجيل للمتابعة",
|
||||
"response.InvalidComfyUIArgs": "تكوين ComfyUI غير صحيح، يرجى التحقق من إعدادات ComfyUI ثم المحاولة مرة أخرى",
|
||||
"response.InvalidGithubToken": "رمز وصول شخصية GitHub غير صحيح أو فارغ، يرجى التحقق من رمز وصول GitHub الشخصي والمحاولة مرة أخرى",
|
||||
"response.InvalidOllamaArgs": "تكوين Ollama غير صحيح، يرجى التحقق من تكوين Ollama وإعادة المحاولة",
|
||||
"response.InvalidProviderAPIKey": "{{provider}} مفتاح API غير صحيح أو فارغ، يرجى التحقق من مفتاح API {{provider}} الخاص بك وحاول مرة أخرى",
|
||||
"response.InvalidVertexCredentials": "فشل التحقق من بيانات اعتماد Vertex، يرجى التحقق من بيانات الاعتماد وإعادة المحاولة",
|
||||
"response.LocationNotSupportError": "عذرًا، لا يدعم موقعك الحالي خدمة هذا النموذج، قد يكون ذلك بسبب قيود المنطقة أو عدم توفر الخدمة. يرجى التحقق مما إذا كان الموقع الحالي يدعم استخدام هذه الخدمة، أو محاولة استخدام معلومات الموقع الأخرى.",
|
||||
"response.ModelNotFound": "عذرًا، لا يمكن طلب النموذج المطلوب، قد يكون النموذج غير موجود أو أن الوصول غير مصرح به، يرجى تغيير مفتاح API أو تعديل أذونات الوصول ثم إعادة المحاولة",
|
||||
"response.NoOpenAIAPIKey": "مفتاح API الخاص بـ OpenAI فارغ، يرجى إضافة مفتاح API الخاص بـ OpenAI",
|
||||
"response.OllamaBizError": "خطأ في طلب خدمة Ollama، يرجى التحقق من المعلومات التالية أو إعادة المحاولة",
|
||||
"response.OllamaServiceUnavailable": "خدمة Ollama غير متوفرة، يرجى التحقق من تشغيل Ollama بشكل صحيح أو إعدادات الـ Ollama للاتصال عبر النطاقات",
|
||||
"response.PermissionDenied": "عذرًا، ليس لديك إذن للوصول إلى هذه الخدمة، يرجى التحقق مما إذا كانت مفاتيحك تمتلك إذن الوصول",
|
||||
"response.PluginApiNotFound": "عذرًا، لا يوجد API للإضافة في وصف الإضافة، يرجى التحقق من تطابق طريقة الطلب الخاصة بك مع API الوصف",
|
||||
"response.PluginApiParamsError": "عذرًا، فشلت التحقق من صحة معلمات الطلب للإضافة، يرجى التحقق من تطابق المعلمات مع معلومات الوصف",
|
||||
"response.PluginFailToTransformArguments": "عذرًا، فشل تحويل معلمات استدعاء الإضافة، يرجى محاولة إعادة إنشاء رسالة المساعد أو تجربة نموذج AI ذو قدرات استدعاء أقوى",
|
||||
"response.PluginGatewayError": "عذرًا، حدث خطأ في بوابة الإضافة، يرجى التحقق من تكوين بوابة الإضافة",
|
||||
"response.PluginManifestInvalid": "عذرًا، فشلت التحقق من صحة وصف الإضافة، يرجى التحقق من تنسيق وصف الإضافة",
|
||||
"response.PluginManifestNotFound": "عذرًا، لم يتم العثور على وصف الإضافة (manifest.json) في الخادم، يرجى التحقق من صحة عنوان ملف وصف الإضافة",
|
||||
"response.PluginMarketIndexInvalid": "عذرًا، فشلت التحقق من صحة فهرس الإضافات، يرجى التحقق من تنسيق ملف الفهرس",
|
||||
"response.PluginMarketIndexNotFound": "عذرًا، لم يتم العثور على فهرس الإضافات في الخادم، يرجى التحقق من صحة عنوان الفهرس",
|
||||
"response.PluginMetaInvalid": "عذرًا، فشلت التحقق من صحة بيانات الإضافة، يرجى التحقق من تنسيق بيانات الإضافة",
|
||||
"response.PluginMetaNotFound": "عذرًا، لم يتم العثور على معلومات تكوين الإضافة في الفهرس",
|
||||
"response.PluginOpenApiInitError": "عذرًا، فشل تهيئة عميل OpenAPI، يرجى التحقق من معلومات تكوين OpenAPI",
|
||||
"response.PluginServerError": "خطأ في استجابة الخادم لطلب الإضافة، يرجى التحقق من ملف وصف الإضافة وتكوين الإضافة وتنفيذ الخادم وفقًا لمعلومات الخطأ أدناه",
|
||||
"response.PluginSettingsInvalid": "تحتاج هذه الإضافة إلى تكوين صحيح قبل الاستخدام، يرجى التحقق من صحة تكوينك",
|
||||
"response.ProviderBizError": "طلب خدمة {{provider}} خاطئ، يرجى التحقق من المعلومات التالية أو إعادة المحاولة",
|
||||
"response.QuotaLimitReached": "عذرًا، لقد تم الوصول إلى الحد الأقصى لاستخدام الرموز (Token) أو عدد الطلبات لهذا المفتاح. يرجى زيادة حصة المفتاح أو المحاولة لاحقًا.",
|
||||
"response.ServerAgentRuntimeError": "عذرًا، خدمة الوكيل غير متاحة حاليًا. يرجى المحاولة لاحقًا أو التواصل معنا عبر البريد الإلكتروني للحصول على الدعم.",
|
||||
"response.StreamChunkError": "خطأ في تحليل كتلة الرسالة لطلب التدفق، يرجى التحقق مما إذا كانت واجهة برمجة التطبيقات الحالية تتوافق مع المعايير، أو الاتصال بمزود واجهة برمجة التطبيقات الخاصة بك للاستفسار.",
|
||||
"response.SubscriptionKeyMismatch": "نعتذر، بسبب عطل عرضي في النظام، فإن استخدام الاشتراك الحالي غير فعال مؤقتًا. يرجى النقر على الزر أدناه لاستعادة الاشتراك، أو مراسلتنا عبر البريد الإلكتروني للحصول على الدعم.",
|
||||
"response.SubscriptionPlanLimit": "لقد استنفدت نقاط اشتراكك، ولا يمكنك استخدام هذه الميزة. يرجى الترقية إلى خطة أعلى، أو تكوين واجهة برمجة التطبيقات للنموذج المخصص للاستمرار في الاستخدام",
|
||||
"response.SystemTimeNotMatchError": "عذرًا، وقت النظام لديك لا يتطابق مع الخادم، يرجى التحقق من وقت النظام لديك ثم إعادة المحاولة",
|
||||
"response.UnknownChatFetchError": "عذرًا، حدث خطأ غير معروف في الطلب، يرجى التحقق من المعلومات التالية أو المحاولة مرة أخرى",
|
||||
"stt.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة",
|
||||
"supervisor.decisionFailed": "تعذر على مشرف المجموعة العمل. يرجى التحقق من إعدادات المشرف الخاصة بك، والتأكد من تكوين النموذج الصحيح، ومفتاح API، وعنوان API.",
|
||||
"testConnectionFailed": "فشل اختبار الاتصال: {{error}}",
|
||||
"tts.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة.",
|
||||
"tts.responseError": "فشل طلب الخدمة، يرجى التحقق من الإعدادات أو إعادة المحاولة",
|
||||
"unlock.addProxyUrl": "إضافة عنوان وكيل OpenAI (اختياري)",
|
||||
"unlock.apiKey.description": "أدخل مفتاح API الخاص بـ {{name}} لبدء الجلسة",
|
||||
"unlock.apiKey.imageGenerationDescription": "أدخل مفتاح API الخاص بـ {{name}} لبدء التوليد",
|
||||
"unlock.apiKey.title": "استخدام مفتاح API مخصص لـ {{name}}",
|
||||
"unlock.apiKey.description": "يمكنك بدء الجلسة عن طريق إدخال مفتاح API {{name}} الخاص بك",
|
||||
"unlock.apiKey.imageGenerationDescription": "أدخل مفتاح API الخاص بـ {{name}} للبدء في التوليد",
|
||||
"unlock.apiKey.title": "استخدام مفتاح API {{name}} المخصص",
|
||||
"unlock.closeMessage": "إغلاق الرسالة",
|
||||
"unlock.comfyui.description": "أدخل بيانات اعتماد {{name}} الصالحة لبدء توليد الصور.",
|
||||
"unlock.comfyui.modifyBaseUrl": "تعديل عنوان خدمة ComfyUI",
|
||||
"unlock.comfyui.title": "تحقق من بيانات اعتماد {{name}}",
|
||||
"unlock.comfyui.description": "يرجى إدخال معلومات المصادقة الصحيحة لـ {{name}} للبدء في إنشاء الصور",
|
||||
"unlock.comfyui.modifyBaseUrl": "تعديل عنوان خدمة Comfy UI",
|
||||
"unlock.comfyui.title": "تأكيد معلومات المصادقة الخاصة بـ {{name}}",
|
||||
"unlock.confirm": "تأكيد وإعادة المحاولة",
|
||||
"unlock.goToSettings": "الذهاب إلى الإعدادات",
|
||||
"unlock.oauth.description": "قام المسؤول بتمكين تسجيل الدخول الموحد. انقر على الزر أدناه لتسجيل الدخول وفتح التطبيق.",
|
||||
"unlock.goToSettings": "الانتقال إلى الإعدادات",
|
||||
"unlock.oauth.description": "فتح المسؤول توثيق تسجيل الدخول الموحد، انقر فوق الزر أدناه لتسجيل الدخول وفتح التطبيق",
|
||||
"unlock.oauth.success": "تم تسجيل الدخول بنجاح",
|
||||
"unlock.oauth.title": "تسجيل الدخول إلى حسابك",
|
||||
"unlock.oauth.welcome": "مرحبًا بك!",
|
||||
"unlock.password.description": "تم تفعيل تشفير التطبيق من قبل المسؤول. أدخل كلمة مرور التطبيق لفتحه. لا حاجة لإدخالها مرة أخرى.",
|
||||
"unlock.password.placeholder": "يرجى إدخال كلمة المرور",
|
||||
"unlock.password.title": "أدخل كلمة المرور لفتح التطبيق",
|
||||
"unlock.tabs.apiKey": "مفتاح API مخصص",
|
||||
"unlock.oauth.title": "تسجيل الدخول إلى الحساب",
|
||||
"unlock.oauth.welcome": "مرحبا بك!",
|
||||
"unlock.password.description": "قام المسؤول بتشفير التطبيق، قم بإدخال كلمة مرور التطبيق لفتح التطبيق. يتعين إدخال كلمة المرور مرة واحدة فقط",
|
||||
"unlock.password.placeholder": "الرجاء إدخال كلمة المرور",
|
||||
"unlock.password.title": "إدخال كلمة المرور لفتح التطبيق",
|
||||
"unlock.tabs.apiKey": "مفتاح واجهة برمجة التطبيقات المخصص",
|
||||
"unlock.tabs.password": "كلمة المرور",
|
||||
"upload.desc": "التفاصيل: {{detail}}",
|
||||
"upload.fileOnlySupportInServerMode": "وضع النشر الحالي لا يدعم تحميل الملفات غير الصورية. لتحميل ملفات بصيغة {{ext}}، يرجى التبديل إلى وضع قاعدة بيانات الخادم أو استخدام خدمة {{cloud}}.",
|
||||
"upload.networkError": "يرجى التحقق من اتصال الشبكة والتأكد من صحة إعدادات CORS لخدمة تخزين الملفات.",
|
||||
"upload.title": "فشل تحميل الملف. يرجى التحقق من الاتصال أو المحاولة لاحقًا.",
|
||||
"upload.fileOnlySupportInServerMode": "وضع النشر الحالي لا يدعم تحميل ملفات غير الصور. إذا كنت بحاجة إلى تحميل تنسيق {{ext}}، يرجى التبديل إلى نشر قاعدة البيانات على الخادم أو استخدام خدمة {{cloud}}.",
|
||||
"upload.networkError": "يرجى التأكد من أن اتصال الشبكة لديك يعمل بشكل صحيح، والتحقق من إعدادات تكوين خدمة تخزين الملفات عبر النطاق.",
|
||||
"upload.title": "فشل تحميل الملف، يرجى التحقق من الاتصال بالشبكة أو المحاولة لاحقًا",
|
||||
"upload.unknownError": "سبب الخطأ: {{reason}}",
|
||||
"upload.uploadFailed": "فشل تحميل الملف."
|
||||
"upload.uploadFailed": "فشل تحميل الملف"
|
||||
}
|
||||
|
||||
+85
-91
@@ -1,134 +1,128 @@
|
||||
{
|
||||
"addFolder": "إنشاء مجلد",
|
||||
"addLibrary": "إضافة",
|
||||
"addPage": "إنشاء صفحة",
|
||||
"detail.basic.createdAt": "وقت الإنشاء",
|
||||
"addPage": "إنشاء مستند",
|
||||
"detail.basic.createdAt": "تاريخ الإنشاء",
|
||||
"detail.basic.filename": "اسم الملف",
|
||||
"detail.basic.size": "حجم الملف",
|
||||
"detail.basic.title": "معلومات أساسية",
|
||||
"detail.basic.type": "التنسيق",
|
||||
"detail.basic.updatedAt": "وقت التحديث",
|
||||
"detail.basic.type": "الصيغة",
|
||||
"detail.basic.updatedAt": "تاريخ التحديث",
|
||||
"detail.data.chunkCount": "عدد الأجزاء",
|
||||
"detail.data.embedding.default": "غير مضمّن",
|
||||
"detail.data.embedding.default": "لم يتم تحويله إلى متجهات بعد",
|
||||
"detail.data.embedding.error": "فشل",
|
||||
"detail.data.embedding.pending": "بانتظار البدء",
|
||||
"detail.data.embedding.processing": "قيد المعالجة",
|
||||
"detail.data.embedding.pending": "في انتظار البدء",
|
||||
"detail.data.embedding.processing": "جارٍ المعالجة",
|
||||
"detail.data.embedding.success": "اكتمل",
|
||||
"detail.data.embeddingStatus": "التضمين",
|
||||
"empty": "لم يتم تحميل أي ملفات أو مجلدات بعد.",
|
||||
"header.actions.builtInBlockList.filtered": "{{ignored}} ملف تم تصفيته (من أصل {{total}})",
|
||||
"detail.data.embeddingStatus": "تحويل إلى متجهات",
|
||||
"empty": "لا توجد ملفات/مجلدات تم تحميلها بعد",
|
||||
"header.actions.builtInBlockList.filtered": "تم تصفية {{ignored}} ملفًا من أصل {{total}} ملف",
|
||||
"header.actions.connect": "اتصال...",
|
||||
"header.actions.gitignore.apply": "تطبيق القواعد",
|
||||
"header.actions.gitignore.cancel": "تجاهل القواعد",
|
||||
"header.actions.gitignore.content": "تم اكتشاف ملف .gitignore ({{count}} ملفًا إجمالاً). هل ترغب في تطبيق قواعد التجاهل؟",
|
||||
"header.actions.gitignore.filtered": "{{ignored}} ملف تم تجاهله (من أصل {{total}})",
|
||||
"header.actions.gitignore.title": "تم اكتشاف .gitignore",
|
||||
"header.actions.newFolder": "مجلد جديد",
|
||||
"header.actions.newPage": "صفحة جديدة",
|
||||
"header.actions.notion.error": "فشل في استيراد ملفات Notion",
|
||||
"header.actions.gitignore.content": "تم اكتشاف ملف .gitignore (عدد {{count}} من الملفات)، هل ترغب في تطبيق قواعد التجاهل؟",
|
||||
"header.actions.gitignore.filtered": "{{ignored}} ملفًا تم تجاهله من أصل {{total}} ملفًا",
|
||||
"header.actions.gitignore.title": "تم اكتشاف .gitignore",
|
||||
"header.actions.newFolder": "إنشاء مجلد جديد",
|
||||
"header.actions.newPage": "مستند جديد",
|
||||
"header.actions.notion.error": "فشل في استيراد ملف Notion",
|
||||
"header.actions.notion.foundFiles": "تم العثور على {{count}} ملف",
|
||||
"header.actions.notion.importing": "جارٍ استيراد محتوى Notion...",
|
||||
"header.actions.notion.noMarkdownFiles": "لم يتم العثور على ملفات Markdown في الأرشيف المضغوط",
|
||||
"header.actions.notion.partial": "تم استيراد {{success}} ملف بنجاح، وفشل {{failed}}",
|
||||
"header.actions.notion.success": "تم استيراد {{count}} ملف بنجاح",
|
||||
"header.actions.notionGuide.cancel": "ليس الآن",
|
||||
"header.actions.notionGuide.desc": "أولاً، قم بتصدير المحتوى من Notion كملف Markdown (ZIP). ثم انقر على متابعة لتحديد ملف ZIP واستيراد جميع الصفحات.",
|
||||
"header.actions.notionGuide.ok": "تحديد ملف ZIP من Notion",
|
||||
"header.actions.notionGuide.title": "الاستيراد من Notion",
|
||||
"header.actions.uploadFile": "تحميل ملف",
|
||||
"header.actions.uploadFolder": "تحميل مجلد",
|
||||
"header.newPageButton": "صفحة جديدة",
|
||||
"header.uploadButton": "تحميل",
|
||||
"header.actions.notion.importing": "جارٍ استيراد ملفات Notion...",
|
||||
"header.actions.notion.noMarkdownFiles": "لم يتم العثور على ملفات Markdown في ملف ZIP",
|
||||
"header.actions.notion.partial": "تم استيراد {{success}} ملفًا بنجاح، وفشل {{failed}} ملفًا",
|
||||
"header.actions.notion.success": "تم استيراد {{count}} ملفًا بنجاح",
|
||||
"header.actions.notionGuide.cancel": "إلغاء الاستيراد الآن",
|
||||
"header.actions.notionGuide.desc": "يرجى أولاً تصدير ملفات Markdown (بصيغة ZIP) من Notion، ثم النقر على متابعة لاختيار ملف الضغط واستيراد جميع الصفحات.",
|
||||
"header.actions.notionGuide.ok": "اختر ملف ZIP من Notion",
|
||||
"header.actions.notionGuide.title": "استيراد محتوى Notion",
|
||||
"header.actions.uploadFile": "رفع ملف",
|
||||
"header.actions.uploadFolder": "رفع مجلد",
|
||||
"header.newPageButton": "إنشاء مستند جديد",
|
||||
"header.uploadButton": "رفع",
|
||||
"home.getStarted": "ابدأ الآن",
|
||||
"home.greeting": "ابدأ الآن",
|
||||
"home.greeting": "ابدأ",
|
||||
"home.quickActions": "إجراءات سريعة",
|
||||
"home.recentFiles": "الملفات الحديثة",
|
||||
"home.recentPages": "الصفحات الحديثة",
|
||||
"home.uploadEntries.files.title": "تحميل ملفات",
|
||||
"home.uploadEntries.folder.title": "تحميل مجلد",
|
||||
"home.recentFiles": "الملفات الأخيرة",
|
||||
"home.recentPages": "الصفحات الأخيرة",
|
||||
"home.subtitle": "مرحبًا بك في مركز الموارد، ابدأ من هنا لإدارة مستنداتك وملفاتك.",
|
||||
"home.uploadEntries.files.title": "رفع ملفات",
|
||||
"home.uploadEntries.folder.title": "رفع مجلد",
|
||||
"home.uploadEntries.library.title": "إنشاء مكتبة جديدة",
|
||||
"home.uploadEntries.newPage.title": "صفحة جديدة",
|
||||
"library.list.confirmRemoveLibrary": "أنت على وشك حذف هذه المكتبة. لن يتم حذف الملفات الموجودة بداخلها، بل سيتم نقلها إلى جميع الملفات. لا يمكن التراجع عن هذا الإجراء، لذا يرجى المتابعة بحذر.",
|
||||
"library.list.empty": "انقر <1>+</1> لإنشاء مكتبة جديدة",
|
||||
"library.new": "مكتبة جديدة",
|
||||
"home.uploadEntries.newPage.title": "إنشاء مستند جديد",
|
||||
"library.list.confirmRemoveLibrary": "سيتم حذف هذه المكتبة، لكن الملفات بداخلها لن تُحذف، بل سيتم نقلها إلى جميع الملفات. لا يمكن استعادة المكتبة بعد حذفها، يرجى الحذر.",
|
||||
"library.list.empty": "انقر <1>+</1> لبدء إنشاء مكتبة",
|
||||
"library.new": "إنشاء مكتبة جديدة",
|
||||
"library.title": "المكتبة",
|
||||
"loadMore": "تحميل المزيد",
|
||||
"menu.allFiles": "جميع الملفات",
|
||||
"menu.allPages": "جميع الصفحات",
|
||||
"networkError": "فشل في استرداد المكتبات. يرجى التحقق من اتصال الشبكة والمحاولة مرة أخرى.",
|
||||
"notSupportGuide.desc": "وضع النشر الحالي لا يدعم إدارة الملفات. قم بالتبديل إلى <1>وضع قاعدة بيانات الخادم</1>، أو استخدم <3>LobeHub Cloud</3>.",
|
||||
"notSupportGuide.features.allKind.desc": "يدعم أنواع الملفات الشائعة، بما في ذلك تنسيقات الصفحات مثل Word وPPT وExcel وPDF وTXT، بالإضافة إلى ملفات البرمجة مثل JS وPython.",
|
||||
"notSupportGuide.features.allKind.title": "تحليل أنواع ملفات متعددة",
|
||||
"notSupportGuide.features.embeddings.desc": "يستخدم نماذج متجهات عالية الأداء لتحويل أجزاء النص إلى متجهات، مما يتيح البحث الدلالي في محتوى الملفات.",
|
||||
"notSupportGuide.features.embeddings.title": "الدلالات المتجهة",
|
||||
"notSupportGuide.features.libraries.desc": "أنشئ مكتبات وأضف ملفات لبناء مكتبتك الخاصة.",
|
||||
"menu.allPages": "جميع المستندات",
|
||||
"networkError": "فشل في تحميل المكتبة، يرجى التحقق من اتصال الشبكة والمحاولة مرة أخرى",
|
||||
"notSupportGuide.desc": "الوضع الحالي للنشر هو وضع قاعدة بيانات العميل، ولا يمكن استخدام وظيفة إدارة الملفات. يرجى التبديل إلى <1>وضع نشر قاعدة بيانات الخادم</1>، أو استخدام <3>LobeChat Cloud</3> مباشرة.",
|
||||
"notSupportGuide.features.allKind.desc": "يدعم أنواع الملفات الشائعة، بما في ذلك تنسيقات المستندات الشائعة مثل Word وPPT وExcel وPDF وTXT، بالإضافة إلى ملفات الشيفرة الشائعة مثل JS وPython.",
|
||||
"notSupportGuide.features.allKind.title": "تحليل أنواع متعددة من الملفات",
|
||||
"notSupportGuide.features.embeddings.desc": "استخدام نماذج متجهات عالية الأداء لتحويل النصوص إلى متجهات، مما يتيح البحث الدلالي في محتوى الملفات.",
|
||||
"notSupportGuide.features.embeddings.title": "تحويل دلالي إلى متجهات",
|
||||
"notSupportGuide.features.libraries.desc": "يدعم إنشاء مكتبات ويسمح بإضافة أنواع مختلفة من الملفات لبناء مواردك المتخصصة",
|
||||
"notSupportGuide.features.libraries.title": "المكتبة",
|
||||
"notSupportGuide.title": "وضع النشر الحالي لا يدعم إدارة الملفات",
|
||||
"notSupportGuide.title": "الوضع الحالي للنشر لا يدعم إدارة الملفات",
|
||||
"pageEditor.addIcon": "إضافة أيقونة",
|
||||
"pageEditor.autoSaveMessage": "يتم حفظ صفحتك تلقائيًا. لا حاجة للحفظ يدويًا.",
|
||||
"pageEditor.autoSaveMessage": "يتم حفظ المستند تلقائيًا، لا حاجة للحفظ اليدوي",
|
||||
"pageEditor.chooseIcon": "اختر أيقونة",
|
||||
"pageEditor.deleteConfirm.content": "سيتم حذف هذه الصفحة ولا يمكن استعادتها. يرجى المتابعة بحذر.",
|
||||
"pageEditor.deleteConfirm.title": "حذف الصفحة",
|
||||
"pageEditor.deleteError": "فشل في حذف الصفحة",
|
||||
"pageEditor.deleteSuccess": "تم حذف الصفحة بنجاح",
|
||||
"pageEditor.duplicateError": "فشل في تكرار الصفحة",
|
||||
"pageEditor.duplicateSuccess": "تم تكرار الصفحة بنجاح",
|
||||
"pageEditor.deleteConfirm.content": "سيتم حذف هذا المستند، ولا يمكن استعادته بعد الحذف. يرجى توخي الحذر.",
|
||||
"pageEditor.deleteConfirm.title": "حذف المستند",
|
||||
"pageEditor.deleteError": "فشل في حذف المستند",
|
||||
"pageEditor.deleteSuccess": "تم حذف المستند بنجاح",
|
||||
"pageEditor.editedAt": "آخر تعديل في {{time}}",
|
||||
"pageEditor.editedBy": "آخر تعديل بواسطة {{name}}",
|
||||
"pageEditor.editorPlaceholder": "ابدأ بكتابة صفحتك. اضغط / لفتح قائمة الأوامر",
|
||||
"pageEditor.empty.createNewDocument": "إنشاء صفحة جديدة",
|
||||
"pageEditor.empty.importNotion": "الاستيراد من Notion",
|
||||
"pageEditor.empty.title": "اختر صفحة للبدء",
|
||||
"pageEditor.empty.uploadFiles": "تحميل ملفات",
|
||||
"pageEditor.exportError": "فشل في تصدير الصفحة",
|
||||
"pageEditor.exportSuccess": "تم تصدير الصفحة بنجاح",
|
||||
"pageEditor.editedBy": "آخر من عدّل: {{name}}",
|
||||
"pageEditor.editorPlaceholder": "أدخل محتوى المستند، اضغط / لفتح قائمة الأوامر",
|
||||
"pageEditor.empty.createNewDocument": "إنشاء مستند جديد",
|
||||
"pageEditor.empty.title": "اختر مستندًا للبدء",
|
||||
"pageEditor.empty.uploadMarkdown": "رفع ملف Markdown",
|
||||
"pageEditor.linkCopied": "تم نسخ الرابط",
|
||||
"pageEditor.menu.copyLink": "نسخ الرابط",
|
||||
"pageEditor.menu.export": "تصدير",
|
||||
"pageEditor.menu.export.markdown": "Markdown",
|
||||
"pageEditor.menu.exportDocument": "تصدير الصفحة",
|
||||
"pageEditor.menu.importDocument": "استيراد صفحة",
|
||||
"pageEditor.menu.pin": "تثبيت الصفحة",
|
||||
"pageEditor.menu.exportDocument": "تصدير المستند",
|
||||
"pageEditor.menu.importDocument": "استيراد مستند",
|
||||
"pageEditor.menu.pin": "تثبيت المستند",
|
||||
"pageEditor.saving": "جارٍ الحفظ...",
|
||||
"pageEditor.titlePlaceholder": "بدون عنوان",
|
||||
"pageEditor.wordCount": "{{wordCount}} كلمة",
|
||||
"pageList.copyContent": "نسخ النص الكامل",
|
||||
"pageList.duplicate": "تكرار",
|
||||
"pageList.empty": "لا توجد صفحات بعد. انقر على الزر أعلاه لإنشاء أول صفحة.",
|
||||
"pageList.copyContent": "نسخ المحتوى الكامل",
|
||||
"pageList.duplicate": "إنشاء نسخة",
|
||||
"pageList.empty": "لا توجد مستندات حاليًا، انقر على الزر أعلاه لإنشاء أول مستند لك",
|
||||
"pageList.filter.all": "الكل",
|
||||
"pageList.filter.onlyInPages": "في الصفحات فقط",
|
||||
"pageList.noResults": "لم يتم العثور على صفحات مطابقة",
|
||||
"pageList.pageCount": "إجمالي {{count}} صفحة",
|
||||
"pageList.filter.onlyInPages": "فقط في المستندات",
|
||||
"pageList.noResults": "لم يتم العثور على مستندات مطابقة",
|
||||
"pageList.pageCount": "عدد المستندات: {{count}}",
|
||||
"pageList.pageSizeItem": "{{count}} عنصر",
|
||||
"pageList.title": "الصفحات",
|
||||
"pageList.selectNote": "اختر مستندًا للبدء في التحرير",
|
||||
"pageList.title": "المستندات",
|
||||
"pageList.untitled": "بدون عنوان",
|
||||
"portal.openInPageEditor": "تحرير في الصفحة",
|
||||
"preview.downloadFile": "تنزيل الملف",
|
||||
"preview.unsupportedFileAndContact": "تنسيق هذا الملف غير مدعوم حاليًا للمعاينة عبر الإنترنت. إذا كان لديك طلب للمعاينة، لا تتردد في <1>الاتصال بنا</1>.",
|
||||
"searchFilePlaceholder": "البحث في الملفات",
|
||||
"searchPagePlaceholder": "البحث في الصفحات",
|
||||
"portal.openInPageEditor": "تحرير في المستند",
|
||||
"preview.downloadFile": "تحميل الملف",
|
||||
"preview.unsupportedFileAndContact": "هذا التنسيق من الملفات غير مدعوم للمعاينة عبر الإنترنت، إذا كان لديك طلب للمعاينة، فلا تتردد في <1>إبلاغنا</1>",
|
||||
"searchFilePlaceholder": "بحث عن ملف",
|
||||
"searchPagePlaceholder": "ابحث في المستندات",
|
||||
"tab.all": "الكل",
|
||||
"tab.audios": "الصوتيات",
|
||||
"tab.documents": "المستندات",
|
||||
"tab.home": "الرئيسية",
|
||||
"tab.images": "الصور",
|
||||
"tab.moreTypes": "أنواع أخرى",
|
||||
"tab.pages": "الصفحات",
|
||||
"tab.pages": "المستندات",
|
||||
"tab.videos": "الفيديوهات",
|
||||
"tab.websites": "المواقع",
|
||||
"title": "الموارد",
|
||||
"toggleLeftPanel": "إظهار/إخفاء اللوحة الجانبية",
|
||||
"toggleLeftPanel": "إظهار/إخفاء اللوحة الجانبية اليسرى",
|
||||
"uploadDock.body.collapse": "طي",
|
||||
"uploadDock.body.item.done": "تم التحميل",
|
||||
"uploadDock.body.item.error": "فشل في التحميل، يرجى المحاولة مرة أخرى",
|
||||
"uploadDock.body.item.pending": "جارٍ التحضير للتحميل...",
|
||||
"uploadDock.body.item.done": "تم الرفع",
|
||||
"uploadDock.body.item.error": "فشل الرفع، يرجى المحاولة مرة أخرى",
|
||||
"uploadDock.body.item.pending": "جاهز للرفع...",
|
||||
"uploadDock.body.item.processing": "جارٍ معالجة الملف...",
|
||||
"uploadDock.body.item.restTime": "المتبقي {{time}}",
|
||||
"uploadDock.fileQueueInfo": "يتم تحميل أول {{count}} ملف، {{remaining}} في الانتظار",
|
||||
"uploadDock.body.item.restTime": "الوقت المتبقي {{time}}",
|
||||
"uploadDock.fileQueueInfo": "يتم حاليًا تحميل {{count}} ملفًا، وسيتم وضع {{remaining}} ملفًا في قائمة الانتظار للتحميل",
|
||||
"uploadDock.totalCount": "إجمالي {{count}} عنصر",
|
||||
"uploadDock.uploadStatus.error": "خطأ في التحميل",
|
||||
"uploadDock.uploadStatus.pending": "بانتظار التحميل",
|
||||
"uploadDock.uploadStatus.processing": "جارٍ التحميل",
|
||||
"uploadDock.uploadStatus.success": "تم التحميل بنجاح",
|
||||
"uploadDock.uploadStatus.uploading": "جارٍ التحميل"
|
||||
"uploadDock.uploadStatus.error": "حدث خطأ أثناء الرفع",
|
||||
"uploadDock.uploadStatus.pending": "في انتظار الرفع",
|
||||
"uploadDock.uploadStatus.processing": "جارٍ الرفع",
|
||||
"uploadDock.uploadStatus.success": "اكتمل الرفع",
|
||||
"uploadDock.uploadStatus.uploading": "جارٍ الرفع"
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{
|
||||
"agentSelection.empty": "لا يوجد وكلاء متاحون",
|
||||
"agentSelection.noAvailable": "لا يمكن إضافة أي وكلاء في الوقت الحالي",
|
||||
"agentSelection.noSelected": "لم يتم اختيار أي وكلاء",
|
||||
"agentSelection.search": "لم يتم العثور على وكلاء مطابقين",
|
||||
"project.create": "مشروع جديد",
|
||||
"project.deleteConfirm": "سيتم حذف هذا المشروع ولا يمكن استعادته. يرجى التأكيد للمتابعة.",
|
||||
"starter.createAgent": "إنشاء وكيل",
|
||||
"agentSelection.empty": "لا يوجد مساعدون متاحون حاليًا",
|
||||
"agentSelection.noAvailable": "لا يوجد مساعدون يمكن إضافتهم في الوقت الحالي",
|
||||
"agentSelection.noSelected": "لم يتم اختيار أي مساعد بعد",
|
||||
"agentSelection.search": "لم يتم العثور على مساعد مطابق",
|
||||
"project.create": "إنشاء مشروع جديد",
|
||||
"project.deleteConfirm": "سيتم حذف هذا المشروع، ولن يكون بالإمكان استعادته بعد الحذف. يرجى تأكيد الإجراء.",
|
||||
"starter.createAgent": "إنشاء مساعد",
|
||||
"starter.createGroup": "إنشاء مجموعة",
|
||||
"starter.deepResearch": "بحث معمق",
|
||||
"starter.developing": "قريبًا",
|
||||
"starter.image": "صورة",
|
||||
"starter.developing": "قيد التطوير",
|
||||
"starter.image": "رسم",
|
||||
"starter.write": "كتابة"
|
||||
}
|
||||
|
||||
+25
-25
@@ -1,42 +1,42 @@
|
||||
{
|
||||
"addUserMessage.desc": "أضف الإدخال الحالي كرسالة مستخدم دون بدء التوليد",
|
||||
"addUserMessage.desc": "إضافة المحتوى الحالي كرسالة مستخدم دون تفعيل التوليد",
|
||||
"addUserMessage.title": "إضافة رسالة مستخدم",
|
||||
"clearCurrentMessages.desc": "مسح الرسائل والملفات المرفوعة من المحادثة الحالية",
|
||||
"clearCurrentMessages.desc": "مسح الرسائل والملفات المرفوعة في المحادثة الحالية",
|
||||
"clearCurrentMessages.title": "مسح رسائل المحادثة",
|
||||
"commandPalette.desc": "افتح لوحة الأوامر العامة للوصول السريع إلى الميزات",
|
||||
"commandPalette.title": "لوحة الأوامر",
|
||||
"deleteAndRegenerateMessage.desc": "حذف الرسالة الأخيرة وإعادة توليدها",
|
||||
"deleteAndRegenerateMessage.title": "حذف وإعادة توليد",
|
||||
"deleteAndRegenerateMessage.desc": "حذف الرسالة الأخيرة وإعادة إنشائها",
|
||||
"deleteAndRegenerateMessage.title": "حذف وإعادة إنشاء",
|
||||
"deleteLastMessage.desc": "حذف الرسالة الأخيرة",
|
||||
"deleteLastMessage.title": "حذف الرسالة الأخيرة",
|
||||
"desktop.openSettings.desc": "افتح صفحة إعدادات التطبيق",
|
||||
"desktop.openSettings.title": "إعدادات التطبيق",
|
||||
"desktop.showApp.desc": "تبديل ظهور النافذة الرئيسية باستخدام اختصار عام",
|
||||
"desktop.showApp.desc": "مفتاح اختصار عام لإظهار أو إخفاء النافذة الرئيسية",
|
||||
"desktop.showApp.title": "إظهار/إخفاء النافذة الرئيسية",
|
||||
"editMessage.desc": "ادخل وضع التعديل بالضغط على Alt والنقر المزدوج على الرسالة",
|
||||
"editMessage.title": "تعديل الرسالة",
|
||||
"navigateToChat.desc": "الانتقال إلى تبويب الدردشة والدخول إلى Lobe AI",
|
||||
"navigateToChat.title": "الانتقال إلى الدردشة الافتراضية",
|
||||
"editMessage.desc": "الدخول إلى وضع التحرير عن طريق الضغط على مفتاح Alt والنقر المزدوج على الرسالة",
|
||||
"editMessage.title": "تحرير الرسالة",
|
||||
"navigateToChat.desc": "التبديل إلى علامة تبويب المحادثة والدخول إلى Lobe AI",
|
||||
"navigateToChat.title": "التبديل إلى المحادثة الافتراضية",
|
||||
"openChatSettings.desc": "عرض وتعديل إعدادات المحادثة الحالية",
|
||||
"openChatSettings.title": "فتح إعدادات المحادثة",
|
||||
"openHotkeyHelper.desc": "عرض تعليمات جميع اختصارات لوحة المفاتيح",
|
||||
"openHotkeyHelper.title": "فتح تعليمات الاختصارات",
|
||||
"regenerateMessage.desc": "إعادة توليد الرسالة الأخيرة",
|
||||
"openHotkeyHelper.desc": "عرض جميع تعليمات استخدام الاختصارات",
|
||||
"openHotkeyHelper.title": "فتح مساعدة الاختصارات",
|
||||
"regenerateMessage.desc": "إعادة توليد آخر رسالة",
|
||||
"regenerateMessage.title": "إعادة توليد الرسالة",
|
||||
"saveDocument.desc": "حفظ جميع التغييرات على الصفحة الحالية فورًا",
|
||||
"saveDocument.title": "حفظ الصفحة",
|
||||
"saveDocument.desc": "احفظ جميع التغييرات التي أُجريت على المستند الحالي فورًا",
|
||||
"saveDocument.title": "حفظ المستند",
|
||||
"saveTopic.desc": "حفظ الموضوع الحالي وفتح موضوع جديد",
|
||||
"saveTopic.title": "بدء موضوع جديد",
|
||||
"search.desc": "تفعيل مربع البحث الرئيسي في الصفحة الحالية",
|
||||
"saveTopic.title": "فتح موضوع جديد",
|
||||
"search.desc": "استدعاء مربع البحث الرئيسي في الصفحة الحالية",
|
||||
"search.title": "بحث",
|
||||
"showApp.desc": "فتح نافذة التطبيق الرئيسية بسرعة",
|
||||
"showApp.title": "إظهار النافذة الرئيسية",
|
||||
"switchAgent.desc": "التبديل بين الوكلاء المثبتين في الشريط الجانبي بالضغط على Ctrl مع الأرقام من 0 إلى 9",
|
||||
"switchAgent.title": "تبديل سريع للوكلاء",
|
||||
"toggleLeftPanel.desc": "إظهار أو إخفاء اللوحة اليسرى",
|
||||
"toggleLeftPanel.title": "تبديل اللوحة اليسرى",
|
||||
"toggleRightPanel.desc": "إظهار أو إخفاء اللوحة اليمنى",
|
||||
"toggleRightPanel.title": "تبديل اللوحة اليمنى",
|
||||
"toggleZenMode.desc": "في وضع التركيز، عرض المحادثة الحالية فقط وإخفاء عناصر الواجهة الأخرى",
|
||||
"showApp.desc": "استدعاء نافذة التطبيق الرئيسية بسرعة",
|
||||
"showApp.title": "عرض النافذة الرئيسية",
|
||||
"switchAgent.desc": "تبديل المساعد المثبت في الشريط الجانبي عن طريق الضغط على Ctrl مع الأرقام من 0 إلى 9",
|
||||
"switchAgent.title": "تبديل المساعد بسرعة",
|
||||
"toggleLeftPanel.desc": "إظهار أو إخفاء اللوحة الجانبية اليسرى",
|
||||
"toggleLeftPanel.title": "إظهار/إخفاء اللوحة الجانبية اليسرى",
|
||||
"toggleRightPanel.desc": "إظهار أو إخفاء اللوحة الجانبية اليمنى",
|
||||
"toggleRightPanel.title": "إظهار/إخفاء اللوحة الجانبية اليمنى",
|
||||
"toggleZenMode.desc": "في وضع التركيز، عرض المحادثة الحالية فقط، وإخفاء واجهة المستخدم الأخرى",
|
||||
"toggleZenMode.title": "تبديل وضع التركيز"
|
||||
}
|
||||
|
||||
+28
-28
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"config.aspectRatio.label": "نسبة العرض إلى الارتفاع",
|
||||
"config.aspectRatio.label": "النسبة",
|
||||
"config.aspectRatio.lock": "قفل نسبة العرض إلى الارتفاع",
|
||||
"config.aspectRatio.unlock": "فتح نسبة العرض إلى الارتفاع",
|
||||
"config.aspectRatio.unlock": "إلغاء قفل نسبة العرض إلى الارتفاع",
|
||||
"config.cfg.label": "شدة التوجيه",
|
||||
"config.header.desc": "وصف موجز، أنشئ فورًا",
|
||||
"config.header.title": "رسم",
|
||||
"config.header.desc": "وصف بسيط، ابتكر فورًا",
|
||||
"config.header.title": "الرسم",
|
||||
"config.height.label": "الارتفاع",
|
||||
"config.imageNum.label": "عدد الصور",
|
||||
"config.imageUrl.label": "صورة مرجعية",
|
||||
"config.imageUrls.label": "صور مرجعية",
|
||||
"config.model.label": "النموذج",
|
||||
"config.prompt.placeholder": "صف ما ترغب في إنشائه",
|
||||
"config.prompt.placeholder": "وصف المحتوى الذي ترغب في إنشائه",
|
||||
"config.quality.label": "جودة الصورة",
|
||||
"config.quality.options.hd": "عالية الدقة",
|
||||
"config.quality.options.standard": "قياسية",
|
||||
"config.quality.options.hd": "عالي الدقة",
|
||||
"config.quality.options.standard": "عادي",
|
||||
"config.resolution.label": "الدقة",
|
||||
"config.resolution.options.1K": "1K",
|
||||
"config.resolution.options.2K": "2K",
|
||||
@@ -21,42 +21,42 @@
|
||||
"config.seed.label": "البذرة",
|
||||
"config.seed.random": "بذرة عشوائية",
|
||||
"config.size.label": "الحجم",
|
||||
"config.steps.label": "الخطوات",
|
||||
"config.title": "صورة بالذكاء الاصطناعي",
|
||||
"config.steps.label": "عدد الخطوات",
|
||||
"config.title": "الرسم بالذكاء الاصطناعي",
|
||||
"config.width.label": "العرض",
|
||||
"generation.actions.applySeed": "تطبيق البذرة",
|
||||
"generation.actions.copyError": "نسخ رسالة الخطأ",
|
||||
"generation.actions.copyPrompt": "نسخ الوصف",
|
||||
"generation.actions.copyPrompt": "نسخ العبارة التحفيزية",
|
||||
"generation.actions.copySeed": "نسخ البذرة",
|
||||
"generation.actions.delete": "حذف",
|
||||
"generation.actions.deleteBatch": "حذف الدفعة",
|
||||
"generation.actions.download": "تنزيل",
|
||||
"generation.actions.downloadFailed": "فشل في تنزيل الصورة. يرجى التحقق من اتصال الشبكة أو إعدادات CORS لتخزين S3.",
|
||||
"generation.actions.downloadFailed": "فشل تنزيل الصورة",
|
||||
"generation.actions.errorCopied": "تم نسخ رسالة الخطأ إلى الحافظة",
|
||||
"generation.actions.errorCopyFailed": "فشل في نسخ رسالة الخطأ",
|
||||
"generation.actions.errorCopyFailed": "فشل نسخ رسالة الخطأ",
|
||||
"generation.actions.generate": "إنشاء",
|
||||
"generation.actions.promptCopied": "تم نسخ الوصف إلى الحافظة",
|
||||
"generation.actions.promptCopyFailed": "فشل في نسخ الوصف",
|
||||
"generation.actions.promptCopied": "تم نسخ النص التوجيهي إلى الحافظة",
|
||||
"generation.actions.promptCopyFailed": "فشل نسخ النص التوجيهي",
|
||||
"generation.actions.reuseSettings": "إعادة استخدام الإعدادات",
|
||||
"generation.actions.seedApplied": "تم تطبيق البذرة على الإعدادات",
|
||||
"generation.actions.seedApplyFailed": "فشل في تطبيق البذرة",
|
||||
"generation.actions.seedCopied": "تم نسخ البذرة إلى الحافظة",
|
||||
"generation.actions.seedCopyFailed": "فشل في نسخ البذرة",
|
||||
"generation.actions.seedCopyFailed": "فشل نسخ البذرة",
|
||||
"generation.metadata.count": "{{count}} صورة",
|
||||
"generation.status.failed": "فشل في الإنشاء",
|
||||
"generation.status.generating": "جارٍ الإنشاء...",
|
||||
"notSupportGuide.desc": "وضع النشر الحالي لا يدعم إنشاء الصور بالذكاء الاصطناعي. قم بالتبديل إلى <1>وضع نشر قاعدة بيانات الخادم</1>، أو استخدم <3>LobeHub Cloud</3>.",
|
||||
"notSupportGuide.features.fileIntegration.desc": "تكامل عميق مع نظام إدارة الملفات؛ يتم حفظ الصور المُنشأة تلقائيًا في نظام الملفات لإدارة وتنظيم موحد.",
|
||||
"notSupportGuide.features.fileIntegration.title": "تكامل مع نظام الملفات",
|
||||
"notSupportGuide.features.llmAssisted.desc": "يجمع بين قدرات نماذج اللغة الكبيرة لتحسين وتوسيع الأوصاف بذكاء، مما يعزز جودة إنشاء الصور (قريبًا).",
|
||||
"notSupportGuide.features.llmAssisted.title": "إنشاء صور بمساعدة LLM",
|
||||
"notSupportGuide.features.multiProviders.desc": "يدعم عدة مزودي خدمات لإنشاء الصور بالذكاء الاصطناعي، بما في ذلك OpenAI gpt-image-1 وGoogle Imagen وFAL.ai والمزيد، مما يوفر مجموعة واسعة من النماذج.",
|
||||
"notSupportGuide.features.multiProviders.title": "دعم متعدد المزودين",
|
||||
"notSupportGuide.title": "وضع النشر الحالي لا يدعم إنشاء الصور بالذكاء الاصطناعي",
|
||||
"topic.createNew": "موضوع جديد",
|
||||
"topic.deleteConfirm": "حذف موضوع الإنشاء",
|
||||
"topic.deleteConfirmDesc": "أنت على وشك حذف موضوع الإنشاء هذا. لا يمكن التراجع عن هذا الإجراء، يرجى المتابعة بحذر.",
|
||||
"topic.empty": "لا توجد مواضيع إنشاء",
|
||||
"notSupportGuide.desc": "الوحدة الحالية تعمل بنمط قاعدة بيانات العميل، ولا تدعم ميزة إنشاء الصور بالذكاء الاصطناعي. يرجى التبديل إلى <1>نمط نشر قاعدة بيانات الخادم</1>، أو استخدام <3>سحابة LobeChat</3> مباشرةً",
|
||||
"notSupportGuide.features.fileIntegration.desc": "تكامل عميق مع نظام إدارة الملفات، حيث تُحفظ الصور المُنشأة تلقائيًا في نظام الملفات، مع دعم الإدارة والتنظيم الموحد",
|
||||
"notSupportGuide.features.fileIntegration.title": "تكامل نظام الملفات",
|
||||
"notSupportGuide.features.llmAssisted.desc": "يجمع بين قدرات نماذج اللغة الكبيرة لتحسين وتوسيع النصوص التوجيهية بذكاء، مما يعزز جودة إنشاء الصور (قريبًا)",
|
||||
"notSupportGuide.features.llmAssisted.title": "مساعدة نموذج اللغة الكبير",
|
||||
"notSupportGuide.features.multiProviders.desc": "يدعم عدة مزودي خدمات رسم بالذكاء الاصطناعي، بما في ذلك OpenAI gpt-image-1، Google Imagen، FAL.ai وغيرها، لتوفير خيارات نماذج متنوعة",
|
||||
"notSupportGuide.features.multiProviders.title": "دعم مزودين متعددين",
|
||||
"notSupportGuide.title": "نمط النشر الحالي لا يدعم الرسم بالذكاء الاصطناعي",
|
||||
"topic.createNew": "إنشاء موضوع جديد",
|
||||
"topic.deleteConfirm": "تأكيد حذف الموضوع",
|
||||
"topic.deleteConfirmDesc": "سيتم حذف هذا الموضوع نهائيًا ولن يمكن استعادته، يرجى توخي الحذر.",
|
||||
"topic.empty": "لا توجد مواضيع تم إنشاؤها",
|
||||
"topic.title": "موضوع الرسم",
|
||||
"topic.untitled": "موضوع افتراضي"
|
||||
"topic.untitled": "الموضوع الافتراضي"
|
||||
}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
{
|
||||
"addToKnowledgeBase.addSuccess": "تمت إضافة الملف بنجاح، <1>عرض الآن</1>",
|
||||
"addToKnowledgeBase.addSuccess": "تم إضافة الملف بنجاح، <1>عرض الآن</1>",
|
||||
"addToKnowledgeBase.confirm": "إضافة",
|
||||
"addToKnowledgeBase.error": "فشل في إضافة الملف إلى المكتبة",
|
||||
"addToKnowledgeBase.id.placeholder": "يرجى اختيار مكتبة للإضافة إليها",
|
||||
"addToKnowledgeBase.id.required": "يرجى اختيار مكتبة",
|
||||
"addToKnowledgeBase.id.title": "المكتبة المستهدفة",
|
||||
"addToKnowledgeBase.title": "إضافة إلى المكتبة",
|
||||
"addToKnowledgeBase.totalFiles": "{{count}} ملف/ملفات محددة",
|
||||
"addToKnowledgeBase.error": "فشل في إضافة الملف إلى قاعدة المعرفة",
|
||||
"addToKnowledgeBase.id.placeholder": "يرجى اختيار قاعدة المعرفة المراد الإضافة إليها",
|
||||
"addToKnowledgeBase.id.required": "يرجى اختيار قاعدة المعرفة",
|
||||
"addToKnowledgeBase.id.title": "قاعدة المعرفة المستهدفة",
|
||||
"addToKnowledgeBase.title": "إضافة إلى قاعدة المعرفة",
|
||||
"addToKnowledgeBase.totalFiles": "تم اختيار {{count}} ملف",
|
||||
"createNew.confirm": "إنشاء جديد",
|
||||
"createNew.description.placeholder": "وصف المكتبة (اختياري)",
|
||||
"createNew.description.placeholder": "وصف قاعدة المعرفة (اختياري)",
|
||||
"createNew.formTitle": "المعلومات الأساسية",
|
||||
"createNew.name.placeholder": "اسم المكتبة",
|
||||
"createNew.name.required": "يرجى إدخال اسم المكتبة",
|
||||
"createNew.title": "إنشاء مكتبة جديدة",
|
||||
"tab.evals": "التقييمات",
|
||||
"tab.files": "الملفات",
|
||||
"createNew.name.placeholder": "اسم قاعدة المعرفة",
|
||||
"createNew.name.required": "يرجى إدخال اسم قاعدة المعرفة",
|
||||
"createNew.title": "إنشاء قاعدة معرفة جديدة",
|
||||
"tab.evals": "تقييمات",
|
||||
"tab.files": "المستندات",
|
||||
"tab.settings": "الإعدادات",
|
||||
"tab.testing": "اختبار الاسترجاع",
|
||||
"title": "المكتبة"
|
||||
"title": "قاعدة المعرفة"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"desc": "ستجد هنا تحديثات عرضية حول الميزات الجديدة التي نستكشفها — لا تتردد في تجربتها!",
|
||||
"features.assistantMessageGroup.desc": "تجميع رسائل الوكيل ونتائج استدعاء الأدوات معًا للعرض",
|
||||
"features.assistantMessageGroup.title": "تجميع رسائل الوكيل",
|
||||
"features.groupChat.desc": "تمكين تنسيق الدردشة الجماعية متعددة الوكلاء.",
|
||||
"desc": "سنقوم بتحديث الميزات الجديدة التي نستكشفها من وقت لآخر، ندعوك لتجربتها!",
|
||||
"features.assistantMessageGroup.desc": "تجميع رسائل المساعد ونتائج استدعاء الأدوات في مجموعة واحدة للعرض",
|
||||
"features.assistantMessageGroup.title": "تجميع رسائل المساعد",
|
||||
"features.groupChat.desc": "تفعيل إمكانية تنسيق المحادثات الجماعية متعددة الوكلاء.",
|
||||
"features.groupChat.title": "دردشة جماعية (متعددة الوكلاء)",
|
||||
"features.inputMarkdown.desc": "عرض Markdown في منطقة الإدخال في الوقت الفعلي (نص عريض، كتل الشيفرة، جداول، إلخ).",
|
||||
"features.inputMarkdown.title": "عرض Markdown في الإدخال",
|
||||
"title": "المختبرات"
|
||||
"features.inputMarkdown.desc": "عرض Markdown في منطقة الإدخال بشكل فوري (مثل النص العريض، كتل الشيفرة، الجداول، وغيرها).",
|
||||
"features.inputMarkdown.title": "عرض Markdown في حقل الإدخال",
|
||||
"title": "المختبر"
|
||||
}
|
||||
|
||||
+42
-42
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"authorize.cancel": "ليس الآن",
|
||||
"authorize.cancel": "إلغاء",
|
||||
"authorize.confirm": "أنشئ ملفك الشخصي",
|
||||
"authorize.description": "ملفك الشخصي في المجتمع منفصل عن حساب المستخدم الخاص بك في {{appName}}.",
|
||||
"authorize.footer.agreement": "بالمتابعة، فإنك تؤكد أنك قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>.",
|
||||
"authorize.description": "ملفك الشخصي في المجتمع مستقل عن حساب المستخدم في {{appName}}.",
|
||||
"authorize.footer.agreement": "بمتابعتك، فإنك تؤكد أنك قد قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>",
|
||||
"authorize.footer.privacy": "سياسة الخصوصية",
|
||||
"authorize.footer.terms": "شروط الخدمة",
|
||||
"authorize.subtitle": "أنشئ ملفًا شخصيًا في المجتمع لتتمكن من إرسال وإدارة القوائم داخل المجتمع.",
|
||||
"authorize.subtitle": "أنشئ ملفًا شخصيًا في المجتمع لتتمكن من تقديم وإدارة معلومات النشر.",
|
||||
"authorize.title": "إنشاء ملف المجتمع الشخصي",
|
||||
"callback.buttons.close": "إغلاق النافذة",
|
||||
"callback.messages.authFailed": "فشل التفويض: {{error}}",
|
||||
@@ -14,60 +14,60 @@
|
||||
"callback.messages.successWithCountdown": "{{message}} سيتم إغلاق النافذة تلقائيًا خلال {{countdown}} ثانية",
|
||||
"callback.messages.successWithRedirect": "تم التفويض بنجاح! جارٍ إعادة التوجيه...",
|
||||
"callback.titles.error": "فشل التفويض",
|
||||
"callback.titles.loading": "تفويض سوق LobeHub",
|
||||
"callback.titles.loading": "تفويض LobeHub Market",
|
||||
"callback.titles.success": "تم التفويض بنجاح",
|
||||
"errors.authorizationFailed": "فشل التفويض، يرجى المحاولة مرة أخرى.",
|
||||
"errors.browserOnly": "يمكن بدء عملية التفويض فقط من خلال المتصفح.",
|
||||
"errors.codeConsumed": "تم استخدام رمز التفويض بالفعل. يرجى المحاولة مرة أخرى.",
|
||||
"errors.codeVerifierMissing": "جلسة التفويض غير صالحة. يرجى إعادة بدء عملية تسجيل الدخول.",
|
||||
"errors.general": "حدث خطأ أثناء التفويض. يرجى المحاولة مرة أخرى.",
|
||||
"errors.handoffFailed": "فشل في استرداد نتيجة التفويض. يرجى المحاولة مرة أخرى.",
|
||||
"errors.handoffTimeout": "انتهت مهلة التفويض. يرجى إكمال العملية في المتصفح والمحاولة مرة أخرى.",
|
||||
"errors.oidcNotReady": "خدمة التفويض غير جاهزة. يرجى المحاولة لاحقًا.",
|
||||
"errors.openBrowserFailed": "فشل في فتح متصفح النظام. يرجى المحاولة مرة أخرى.",
|
||||
"errors.openPopupFailed": "فشل في فتح نافذة التفويض المنبثقة. يرجى التحقق من إعدادات حظر النوافذ المنبثقة في المتصفح.",
|
||||
"errors.popupClosed": "تم إغلاق نافذة التفويض قبل إكمال العملية.",
|
||||
"errors.sessionExpired": "انتهت صلاحية جلسة التفويض. يرجى تسجيل الدخول مرة أخرى.",
|
||||
"errors.stateMismatch": "عدم تطابق حالة التفويض. يرجى المحاولة مرة أخرى.",
|
||||
"errors.stateMissing": "لم يتم العثور على حالة التفويض. يرجى المحاولة مرة أخرى.",
|
||||
"messages.authorizationFailed": "حدثت مشكلة أثناء التفويض. أعد المحاولة، أو تحقق مما إذا كنت قد أكملت تسجيل الدخول في المتصفح.",
|
||||
"errors.browserOnly": "يمكن بدء عملية التفويض من خلال المتصفح فقط.",
|
||||
"errors.codeConsumed": "تم استخدام رمز التفويض، يرجى المحاولة مرة أخرى.",
|
||||
"errors.codeVerifierMissing": "جلسة التفويض غير صالحة، يرجى إعادة تسجيل الدخول.",
|
||||
"errors.general": "حدث خطأ أثناء التفويض، يرجى المحاولة مرة أخرى.",
|
||||
"errors.handoffFailed": "تعذر الحصول على نتيجة التفويض، يرجى المحاولة مرة أخرى.",
|
||||
"errors.handoffTimeout": "انتهت مهلة التفويض، يرجى إكمال العملية في المتصفح ثم المحاولة مرة أخرى.",
|
||||
"errors.oidcNotReady": "خدمة التفويض غير جاهزة بعد، يرجى المحاولة لاحقًا.",
|
||||
"errors.openBrowserFailed": "تعذر فتح متصفح النظام، يرجى المحاولة مرة أخرى.",
|
||||
"errors.openPopupFailed": "تعذر فتح نافذة التفويض، يرجى التحقق من إعدادات حظر النوافذ المنبثقة في المتصفح.",
|
||||
"errors.popupClosed": "تم إغلاق نافذة التفويض قبل إتمام العملية.",
|
||||
"errors.sessionExpired": "انتهت صلاحية جلسة التفويض، يرجى تسجيل الدخول مرة أخرى.",
|
||||
"errors.stateMismatch": "حالة التفويض غير متطابقة، يرجى المحاولة مرة أخرى.",
|
||||
"errors.stateMissing": "لم يتم العثور على حالة التفويض، يرجى المحاولة مرة أخرى.",
|
||||
"messages.authorizationFailed": "حدثت مشكلة في التفويض. يمكنك المحاولة مرة أخرى أو التحقق مما إذا كنت قد سجلت الدخول في المتصفح.",
|
||||
"messages.authorized": "تم تفويض خدمة LobeHub بنجاح",
|
||||
"messages.handoffTimeout": "انتهت مهلة التفويض. أكمل العملية في المتصفح ثم أعد المحاولة.",
|
||||
"messages.handoffTimeout": "انتهت مهلة انتظار التفويض. يرجى العودة إلى المتصفح لإكمال العملية ثم المحاولة مرة أخرى.",
|
||||
"messages.loading": "جارٍ بدء عملية التفويض...",
|
||||
"messages.success.cloudMcpInstall": "تم التفويض بنجاح! يمكنك الآن تثبيت مهارة Cloud MCP.",
|
||||
"messages.success.submit": "تم التفويض بنجاح! يمكنك الآن نشر وكيلك.",
|
||||
"messages.success.cloudMcpInstall": "تم التفويض بنجاح! يمكنك الآن تثبيت إضافة Cloud MCP.",
|
||||
"messages.success.submit": "تم التفويض بنجاح! يمكنك الآن نشر المساعد.",
|
||||
"messages.success.upload": "تم التفويض بنجاح! يمكنك الآن نشر إصدار جديد.",
|
||||
"profileSetup.cancel": "إلغاء",
|
||||
"profileSetup.descriptionEdit": "قم بتحديث معلومات ملفك الشخصي في المجتمع.",
|
||||
"profileSetup.descriptionFirstTime": "قم بإعداد ملفك لإكمال ملفك الشخصي في المجتمع.",
|
||||
"profileSetup.descriptionEdit": "حدّث معلومات ملفك الشخصي في المجتمع.",
|
||||
"profileSetup.descriptionFirstTime": "قم بإعداد ملفك الشخصي لإكمال إنشاء ملف المجتمع.",
|
||||
"profileSetup.errors.fileTooLarge": "حجم الملف لا يمكن أن يتجاوز 2 ميغابايت",
|
||||
"profileSetup.errors.notAuthenticated": "يرجى تسجيل الدخول أولاً",
|
||||
"profileSetup.errors.updateFailed": "فشل في تحديث الملف الشخصي. يرجى المحاولة مرة أخرى",
|
||||
"profileSetup.errors.uploadFailed": "فشل في التحميل. يرجى المحاولة مرة أخرى",
|
||||
"profileSetup.errors.usernameTaken": "معرّف المستخدم هذا مستخدم بالفعل. يرجى اختيار آخر",
|
||||
"profileSetup.fields.avatar.label": "الصورة الرمزية",
|
||||
"profileSetup.errors.notAuthenticated": "يرجى تسجيل الدخول أولاً قبل المتابعة",
|
||||
"profileSetup.errors.updateFailed": "فشل في تحديث الملف الشخصي، يرجى المحاولة مرة أخرى",
|
||||
"profileSetup.errors.uploadFailed": "فشل التحميل، يرجى المحاولة مرة أخرى",
|
||||
"profileSetup.errors.usernameTaken": "معرّف المستخدم هذا مستخدم بالفعل، يرجى اختيار معرّف آخر",
|
||||
"profileSetup.fields.avatar.label": "الصورة الشخصية",
|
||||
"profileSetup.fields.bannerUrl.clickToUpload": "انقر لتحميل صورة الغلاف",
|
||||
"profileSetup.fields.bannerUrl.label": "صورة الغلاف",
|
||||
"profileSetup.fields.bannerUrl.remove": "إزالة الغلاف",
|
||||
"profileSetup.fields.bannerUrl.tooltip": "ستظهر صورة الغلاف في أعلى صفحة ملفك الشخصي (نسبة 16:9 موصى بها)",
|
||||
"profileSetup.fields.bannerUrl.remove": "إزالة صورة الغلاف",
|
||||
"profileSetup.fields.bannerUrl.tooltip": "ستظهر صورة الغلاف في أعلى صفحتك الشخصية (النسبة الموصى بها 16:9)",
|
||||
"profileSetup.fields.bannerUrl.uploading": "جارٍ التحميل...",
|
||||
"profileSetup.fields.description.label": "نبذة",
|
||||
"profileSetup.fields.description.maxLength": "يجب ألا تتجاوز النبذة 200 حرف",
|
||||
"profileSetup.fields.description.placeholder": "أخبرنا عن نفسك...",
|
||||
"profileSetup.fields.displayName.label": "الاسم المعروض",
|
||||
"profileSetup.fields.displayName.maxLength": "يجب ألا يتجاوز الاسم المعروض 50 حرفًا",
|
||||
"profileSetup.fields.displayName.placeholder": "أدخل الاسم المعروض",
|
||||
"profileSetup.fields.displayName.required": "يرجى إدخال الاسم المعروض",
|
||||
"profileSetup.fields.description.label": "نبذة شخصية",
|
||||
"profileSetup.fields.description.maxLength": "النبذة الشخصية يجب ألا تتجاوز 200 حرف",
|
||||
"profileSetup.fields.description.placeholder": "قدّم نفسك بإيجاز...",
|
||||
"profileSetup.fields.displayName.label": "الاسم الظاهر",
|
||||
"profileSetup.fields.displayName.maxLength": "الاسم الظاهر يجب ألا يتجاوز 50 حرفًا",
|
||||
"profileSetup.fields.displayName.placeholder": "أدخل اسمك الظاهر",
|
||||
"profileSetup.fields.displayName.required": "يرجى إدخال الاسم الظاهر",
|
||||
"profileSetup.fields.github.placeholder": "اسم مستخدم GitHub",
|
||||
"profileSetup.fields.twitter.placeholder": "اسم مستخدم X (تويتر)",
|
||||
"profileSetup.fields.userName.label": "معرّف المستخدم",
|
||||
"profileSetup.fields.userName.maxLength": "يجب ألا يتجاوز معرّف المستخدم 32 حرفًا",
|
||||
"profileSetup.fields.userName.minLength": "يجب ألا يقل معرّف المستخدم عن 3 أحرف",
|
||||
"profileSetup.fields.userName.maxLength": "معرّف المستخدم يجب ألا يتجاوز 32 حرفًا",
|
||||
"profileSetup.fields.userName.minLength": "معرّف المستخدم يجب أن لا يقل عن 3 أحرف",
|
||||
"profileSetup.fields.userName.pattern": "يمكن أن يحتوي معرّف المستخدم على أحرف وأرقام وشرطات سفلية وشرطات فقط",
|
||||
"profileSetup.fields.userName.placeholder": "أدخل معرّف المستخدم الخاص بك",
|
||||
"profileSetup.fields.userName.required": "يرجى إدخال معرّف المستخدم",
|
||||
"profileSetup.fields.userName.tooltip": "معرّف المستخدم هو معرفك الفريد وسيُستخدم في عنوان URL لصفحة ملفك الشخصي",
|
||||
"profileSetup.fields.website.invalidUrl": "يرجى إدخال رابط URL صالح",
|
||||
"profileSetup.fields.userName.tooltip": "معرّف المستخدم هو معرفك الفريد وسيُستخدم في رابط صفحتك الشخصية",
|
||||
"profileSetup.fields.website.invalidUrl": "يرجى إدخال رابط صالح",
|
||||
"profileSetup.fields.website.placeholder": "رابط الموقع الشخصي",
|
||||
"profileSetup.getStarted": "ابدأ الآن",
|
||||
"profileSetup.save": "حفظ",
|
||||
|
||||
+24
-24
@@ -2,44 +2,44 @@
|
||||
"context.actions.delete": "حذف",
|
||||
"context.actions.edit": "تعديل",
|
||||
"context.defaultType": "سياق",
|
||||
"context.deleteConfirm": "هل أنت متأكد أنك تريد حذف هذه الذاكرة السياقية؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"context.deleteConfirm": "هل أنت متأكد من أنك تريد حذف هذه الذاكرة السياقية؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"context.deleteTitle": "حذف الذاكرة السياقية",
|
||||
"context.description": "الوصف",
|
||||
"context.empty": "لا توجد ذكريات سياقية متاحة",
|
||||
"context.empty": "لا توجد ذكريات سياقية حالياً",
|
||||
"context.source": "المصدر",
|
||||
"empty.description": "استرجاع الذكريات هو عملية تدريجية. يرجى التفاعل أكثر لإثراء المحتوى المتاح للاسترجاع. حاول إجراء محادثات أعمق مع الوكيل لالتقاط وتخزين معلومات أكثر قيمة.",
|
||||
"empty.description": "استخراج الذكريات هو عملية تدريجية، يُرجى التفاعل في مواضيع أكثر لتغذية محتوى الذكريات المستخرجة. حاول إجراء محادثات أعمق مع المساعد لالتقاط وتخزين معلومات ذات قيمة بشكل أفضل.",
|
||||
"empty.search": "لم يتم العثور على ذكريات مطابقة",
|
||||
"empty.title": "لا توجد ذكريات بعد",
|
||||
"empty.title": "لا توجد ذكريات حالياً",
|
||||
"experience.actions.delete": "حذف",
|
||||
"experience.actions.edit": "تعديل",
|
||||
"experience.defaultType": "تجربة",
|
||||
"experience.deleteConfirm": "هل أنت متأكد أنك تريد حذف هذه الذاكرة التجريبية؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"experience.deleteConfirm": "هل أنت متأكد من أنك تريد حذف هذه الذاكرة التجريبية؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"experience.deleteTitle": "حذف الذاكرة التجريبية",
|
||||
"experience.empty": "لا توجد ذكريات تجريبية متاحة",
|
||||
"experience.empty": "لا توجد ذكريات تجريبية حالياً",
|
||||
"experience.keyLearning": "التعلم الرئيسي",
|
||||
"experience.situation": "الموقف",
|
||||
"experience.situation": "السياق",
|
||||
"experience.source": "المصدر",
|
||||
"experience.steps.action": "الإجراء",
|
||||
"experience.steps.result": "النتيجة",
|
||||
"experience.steps.situation": "السياق",
|
||||
"experience.steps.situation": "الوضع",
|
||||
"experience.steps.task": "المهمة",
|
||||
"filter.search": "ابحث في الكلمات المفتاحية أو الأوصاف...",
|
||||
"filter.sort.createdAt": "وقت الإنشاء",
|
||||
"filter.sort.scoreConfidence": "الثقة",
|
||||
"filter.sort.scoreImpact": "التأثير",
|
||||
"filter.sort.scorePriority": "وزن التفضيل",
|
||||
"filter.sort.scoreUrgency": "الإلحاح",
|
||||
"identity.empty": "لا توجد ذكريات هوية متاحة",
|
||||
"identity.filter.search": "ابحث في الأدوار أو العلاقات أو الأوصاف...",
|
||||
"filter.search": "ابحث عن كلمات مفتاحية أو وصف للذاكرة...",
|
||||
"filter.sort.createdAt": "تاريخ الإنشاء",
|
||||
"filter.sort.scoreConfidence": "درجة الثقة",
|
||||
"filter.sort.scoreImpact": "الأهمية",
|
||||
"filter.sort.scorePriority": "أولوية التفضيل",
|
||||
"filter.sort.scoreUrgency": "درجة الإلحاح",
|
||||
"identity.empty": "لا توجد ذاكرة هوية حالياً",
|
||||
"identity.filter.search": "ابحث عن دور أو علاقة أو وصف...",
|
||||
"identity.filter.type.all": "الكل",
|
||||
"identity.filter.type.demographic": "البيانات الديموغرافية",
|
||||
"identity.filter.type.demographic": "السمات",
|
||||
"identity.filter.type.personal": "الدور",
|
||||
"identity.filter.type.professional": "المهني",
|
||||
"identity.filter.type.professional": "مهني",
|
||||
"identity.list.confirmDelete": "تأكيد الحذف",
|
||||
"identity.list.deleteCancel": "إلغاء",
|
||||
"identity.list.deleteContent": "هل أنت متأكد أنك تريد حذف هذه الذاكرة المتعلقة بالهوية؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"identity.list.deleteContent": "هل أنت متأكد من أنك تريد حذف ذاكرة الهوية هذه؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"identity.list.deleteOk": "حذف",
|
||||
"identity.list.noResults": "لم يتم العثور على ذكريات هوية مطابقة",
|
||||
"identity.list.noResults": "لم يتم العثور على أي ذاكرة هوية مطابقة",
|
||||
"identity.list.updated": "تم التحديث",
|
||||
"identity.roleCloud.collapse": "إخفاء",
|
||||
"identity.roleCloud.expand": "عرض المزيد",
|
||||
@@ -50,17 +50,17 @@
|
||||
"preference.actions.edit": "تعديل",
|
||||
"preference.conclusionDirectives": "توجيهات الاستنتاج",
|
||||
"preference.defaultType": "تفضيل",
|
||||
"preference.deleteConfirm": "هل أنت متأكد أنك تريد حذف هذه الذاكرة التفضيلية؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"preference.deleteConfirm": "هل أنت متأكد من أنك تريد حذف هذه الذاكرة التفضيلية؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"preference.deleteTitle": "حذف الذاكرة التفضيلية",
|
||||
"preference.empty": "لا توجد ذكريات تفضيل متاحة",
|
||||
"preference.empty": "لا توجد ذكريات تفضيلية حالياً",
|
||||
"preference.source": "المصدر",
|
||||
"preference.suggestions": "الإجراءات التي قد يتخذها الوكيل",
|
||||
"preference.suggestions": "الإجراءات التي قد يتخذها المساعد",
|
||||
"tab.contexts": "السياقات",
|
||||
"tab.experiences": "التجارب",
|
||||
"tab.home": "الرئيسية",
|
||||
"tab.identities": "الهويات",
|
||||
"tab.preferences": "التفضيلات",
|
||||
"tab.search": "بحث",
|
||||
"viewMode.masonry": "شبكة",
|
||||
"viewMode.masonry": "عرض متدرج",
|
||||
"viewMode.timeline": "الجدول الزمني"
|
||||
}
|
||||
|
||||
+20
-20
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"changelog.description": "ابقَ على اطلاع بأحدث الميزات والتحسينات في {{appName}}",
|
||||
"changelog.title": "سجل التغييرات",
|
||||
"chat.description": "{{appName}} يقدم لك أفضل تجربة واجهة مستخدم لـ ChatGPT وClaude وGemini وOLLaMA.",
|
||||
"chat.title": "{{appName}} · للوكلاء التعاونيين",
|
||||
"discover.assistants.description": "محتوى، أسئلة وأجوبة، صور، فيديو، صوت، سير عمل—تصفح وأضف وكلاء من المجتمع.",
|
||||
"discover.assistants.title": "مجتمع الوكلاء",
|
||||
"discover.description": "استكشف الوكلاء، المهارات، المزودين، النماذج، وخوادم MCP.",
|
||||
"discover.mcp.description": "ابحث، قارن، واتصل بآلاف خوادم MCP، مما يمكّن أنظمة الذكاء الاصطناعي من الوصول بسهولة إلى أنظمة الملفات، قواعد البيانات، واجهات البرمجة، وغيرها من الموارد الأساسية، لتوسيع قدراتك في الذكاء الاصطناعي بشكل شامل.",
|
||||
"changelog.description": "تابع الميزات الجديدة والتحسينات في {{appName}} باستمرار",
|
||||
"changelog.title": "سجل التحديثات",
|
||||
"chat.description": "{{appName}} يقدم لك أفضل تجربة لاستخدام ChatGPT وClaude وGemini وOLLaMA WebUI",
|
||||
"chat.title": "{{appName}}: أداة الذكاء الاصطناعي الشخصية، امنح نفسك دماغًا أكثر ذكاءً",
|
||||
"discover.assistants.description": "إنشاء المحتوى، الكتابة، الأسئلة والأجوبة، توليد الصور، توليد الفيديو، توليد الصوت، الوكلاء الذكيون، سير العمل الآلي، تخصيص مساعد الذكاء الاصطناعي / GPTs / OLLaMA الخاص بك",
|
||||
"discover.assistants.title": "مجتمع الوكلاء الذكيين",
|
||||
"discover.description": "إنشاء المحتوى، الكتابة، الأسئلة والأجوبة، توليد الصور، توليد الفيديو، توليد الصوت، الوكلاء الذكيون، سير العمل الآلي، تطبيقات الذكاء الاصطناعي المخصصة، تخصيص منصة تطبيقات الذكاء الاصطناعي الخاصة بك",
|
||||
"discover.mcp.description": "ابحث وقارن واتصل بآلاف خوادم MCP، مما يساعد أنظمة الذكاء الاصطناعي على الوصول بسهولة إلى أنظمة الملفات وقواعد البيانات وواجهات برمجة التطبيقات وغيرها من الموارد الحيوية، لتوسيع قدرات الذكاء الاصطناعي الخاصة بك بشكل شامل",
|
||||
"discover.mcp.title": "مجتمع خوادم MCP",
|
||||
"discover.models.description": "استكشف نماذج الذكاء الاصطناعي الرائدة OpenAI / GPT / Claude 3 / Gemini / Ollama / Azure / DeepSeek",
|
||||
"discover.models.description": "استكشاف نماذج الذكاء الاصطناعي الرائجة OpenAI / GPT / Claude 3 / Gemini / Ollama / Azure / DeepSeek",
|
||||
"discover.models.title": "مجتمع النماذج",
|
||||
"discover.plugins.description": "استكشف الرسوم البيانية، الأدوات الأكاديمية، توليد الصور/الفيديو/الصوت، وسير العمل—أضف مهارات إلى وكلائك.",
|
||||
"discover.plugins.title": "مجتمع المهارات",
|
||||
"discover.providers.description": "استكشف أبرز مزودي النماذج OpenAI / Qwen / Ollama / Anthropic / DeepSeek / Google Gemini / OpenRouter",
|
||||
"discover.providers.title": "مجتمع المزودين",
|
||||
"discover.plugins.description": "استكشف توليد الرسوم البيانية، والأبحاث الأكاديمية، وتوليد الصور، وتوليد الفيديو، وتوليد الصوت، وأتمتة سير العمل، ودمج قدرات إضافية غنية لمساعدتك.",
|
||||
"discover.plugins.title": "مجتمع الإضافات",
|
||||
"discover.providers.description": "استكشاف مزودي النماذج الرائجة OpenAI / Qwen / Ollama / Anthropic / DeepSeek / Google Gemini / OpenRouter",
|
||||
"discover.providers.title": "مجتمع مزودي النماذج",
|
||||
"discover.search": "بحث",
|
||||
"discover.title": "استكشاف",
|
||||
"image.description": "{{appName}} يقدم لك أفضل تجربة مع GPT Image وFlux وMidjourney وStable Diffusion",
|
||||
"image.title": "فن الذكاء الاصطناعي",
|
||||
"plugins.description": "بحث، رسوم بيانية، أدوات أكاديمية، توليد الصور/الفيديو/الصوت، سير العمل—أضف مهارات إلى وكلائك.",
|
||||
"plugins.title": "مجتمع المهارات",
|
||||
"welcome.description": "{{appName}} يقدم لك أفضل تجربة واجهة مستخدم لـ ChatGPT وClaude وGemini وOLLaMA.",
|
||||
"welcome.title": "مرحبًا بك في {{appName}} · للوكلاء التعاونيين"
|
||||
"discover.title": "اكتشاف",
|
||||
"image.description": "{{appName}} يقدم لك أفضل تجربة استخدام لـ GPT Image و Flux و Midjourney و Stable Diffusion",
|
||||
"image.title": "الرسم بالذكاء الاصطناعي",
|
||||
"plugins.description": "البحث، توليد الرسوم البيانية، الأكاديميات، توليد الصور، توليد الفيديو، توليد الصوت، سير العمل الآلي، خصص قدرات ToolCall الخاصة بـ ChatGPT / Claude",
|
||||
"plugins.title": "مجتمع الإضافات",
|
||||
"welcome.description": "{{appName}} يقدم لك أفضل تجربة لاستخدام ChatGPT وClaude وGemini وOLLaMA WebUI",
|
||||
"welcome.title": "مرحبًا بك في {{appName}}: أداة الذكاء الاصطناعي الشخصية، امنح نفسك دماغًا أكثر ذكاءً"
|
||||
}
|
||||
|
||||
+15
-15
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"dbV1.action.clearDB": "مسح البيانات المحلية",
|
||||
"dbV1.action.downloadBackup": "تنزيل نسخة احتياطية من البيانات",
|
||||
"dbV1.action.downloadBackup": "تنزيل نسخة احتياطية للبيانات",
|
||||
"dbV1.action.reUpgrade": "إعادة الترقية",
|
||||
"dbV1.action.start": "ابدأ الآن",
|
||||
"dbV1.action.upgrade": "ترقية",
|
||||
"dbV1.clear.confirm": "أنت على وشك مسح البيانات المحلية (لن تتأثر الإعدادات العامة). يرجى التأكد من أنك قمت بتنزيل نسخة احتياطية من البيانات.",
|
||||
"dbV1.description": "في الإصدار الجديد، شهد تخزين البيانات في {{appName}} تطورًا كبيرًا. لذلك، نحتاج إلى ترقية البيانات القديمة لتقديم تجربة مستخدم أفضل.",
|
||||
"dbV1.features.capability.desc": "يعتمد على تقنية IndexedDB، وقادر على تخزين رسائل محادثة تدوم مدى الحياة.",
|
||||
"dbV1.features.capability.title": "سعة تخزين كبيرة",
|
||||
"dbV1.features.performance.desc": "يقوم بفهرسة ملايين الرسائل تلقائيًا، مع استجابة فورية لطلبات البحث خلال أجزاء من الثانية.",
|
||||
"dbV1.action.start": "ابدأ الاستخدام",
|
||||
"dbV1.action.upgrade": "ترقية فورية",
|
||||
"dbV1.clear.confirm": "سيتم مسح البيانات المحلية (دون تأثير على الإعدادات العامة)، يرجى التأكد من تنزيل نسخة احتياطية للبيانات.",
|
||||
"dbV1.description": "في الإصدار الجديد، حقق تخزين بيانات {{appName}} قفزة هائلة. لذلك، نحتاج إلى ترقية البيانات القديمة لتوفير تجربة استخدام أفضل لك.",
|
||||
"dbV1.features.capability.desc": "استنادًا إلى تقنية IndexedDB، تكفي لتخزين محادثاتك مدى الحياة",
|
||||
"dbV1.features.capability.title": "سعة كبيرة",
|
||||
"dbV1.features.performance.desc": "مليون رسالة يتم فهرستها تلقائيًا، واستجابة استعلامات البحث في مللي ثانية",
|
||||
"dbV1.features.performance.title": "أداء عالي",
|
||||
"dbV1.features.use.desc": "يدعم البحث حسب العنوان والوصف والوسوم ومحتوى الرسائل وحتى النصوص المترجمة، مما يعزز كفاءة البحث اليومي بشكل كبير.",
|
||||
"dbV1.features.use.desc": "يدعم البحث عن العناوين، الأوصاف، العلامات، محتوى الرسائل وحتى نصوص الترجمة، مما يعزز كفاءة البحث اليومية بشكل كبير",
|
||||
"dbV1.features.use.title": "أسهل في الاستخدام",
|
||||
"dbV1.title": "تطور بيانات {{appName}}",
|
||||
"dbV1.upgrade.error.subTitle": "نعتذر، حدث خطأ أثناء عملية ترقية قاعدة البيانات. يرجى تجربة الحلول التالية: أ. مسح البيانات المحلية وإعادة استيراد النسخة الاحتياطية؛ ب. النقر على زر 'إعادة المحاولة'.<br><br> إذا استمرت المشكلة، يرجى <1>إرسال تقرير بالمشكلة</1> وسنقوم بمساعدتك في أقرب وقت ممكن.",
|
||||
"dbV1.upgrade.error.subTitle": "نعتذر، حدث خطأ أثناء عملية ترقية قاعدة البيانات. يرجى تجربة الحلول التالية: A. امسح البيانات المحلية ثم أعد استيراد البيانات الاحتياطية؛ B. انقر على زر «إعادة الترقية».<br><br> إذا استمرت المشكلة، يرجى <1>تقديم مشكلة</1>، وسنساعدك في حلها في أقرب وقت ممكن.",
|
||||
"dbV1.upgrade.error.title": "فشل ترقية قاعدة البيانات",
|
||||
"dbV1.upgrade.success.subTitle": "تمت ترقية قاعدة البيانات إلى أحدث إصدار. يمكنك المتابعة الآن.",
|
||||
"dbV1.upgrade.success.title": "تمت ترقية قاعدة البيانات بنجاح",
|
||||
"dbV1.upgradeTip": "ستستغرق الترقية حوالي 10 إلى 20 ثانية. يرجى عدم إغلاق {{appName}} أثناء عملية الترقية.",
|
||||
"migrateError.missVersion": "البيانات المستوردة تفتقر إلى رقم الإصدار. يرجى التحقق من الملف والمحاولة مرة أخرى.",
|
||||
"migrateError.noMigration": "لم يتم العثور على حل ترحيل للإصدار الحالي. يرجى التحقق من رقم الإصدار والمحاولة مرة أخرى. إذا استمرت المشكلة، يرجى إرسال ملاحظة دعم."
|
||||
"dbV1.upgrade.success.subTitle": "تمت ترقية قاعدة بيانات {{appName}} إلى أحدث إصدار، ابدأ التجربة الآن",
|
||||
"dbV1.upgrade.success.title": "نجاح ترقية قاعدة البيانات",
|
||||
"dbV1.upgradeTip": "تستغرق عملية الترقية حوالي 10 إلى 20 ثانية، يرجى عدم إغلاق {{appName}} أثناء الترقية",
|
||||
"migrateError.missVersion": "البيانات المستوردة تفتقد رقم الإصدار، يرجى التحقق من الملف وإعادة المحاولة",
|
||||
"migrateError.noMigration": "لم يتم العثور على خطة هجرة تتوافق مع الإصدار الحالي، يرجى التحقق من رقم الإصدار وإعادة المحاولة. إذا استمرت المشكلة، يرجى تقديم ملاحظاتك"
|
||||
}
|
||||
|
||||
+162
-162
@@ -1,102 +1,102 @@
|
||||
{
|
||||
"azure.azureApiVersion.desc": "إصدار واجهة برمجة التطبيقات لـ Azure، اتبع التنسيق YYYY-MM-DD، تحقق من [أحدث إصدار](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)",
|
||||
"azure.azureApiVersion.desc": "نسخة API الخاصة بـ Azure، والتي تتبع تنسيق YYYY-MM-DD، راجع [الإصدارات الأحدث](https://learn.microsoft.com/zh-en/azure/ai-services/openai/reference#chat-completions)",
|
||||
"azure.azureApiVersion.fetch": "جلب القائمة",
|
||||
"azure.azureApiVersion.title": "إصدار Azure API",
|
||||
"azure.empty": "يرجى إدخال معرف النموذج لإضافة النموذج الأول",
|
||||
"azure.endpoint.desc": "عند التحقق من الموارد من بوابة Azure، يمكنك العثور على هذه القيمة في قسم 'المفاتيح ونقاط النهاية'",
|
||||
"azure.azureApiVersion.title": "Azure API Version",
|
||||
"azure.empty": "الرجاء إدخال معرف النموذج لإضافة أول نموذج",
|
||||
"azure.endpoint.desc": "يمكن العثور على هذه القيمة في قسم 'المفاتيح والنقاط النهائية' عند فحص الموارد في بوابة Azure",
|
||||
"azure.endpoint.placeholder": "https://docs-test-001.openai.azure.com",
|
||||
"azure.endpoint.title": "عنوان Azure API",
|
||||
"azure.modelListPlaceholder": "اختر أو أضف نموذج OpenAI الذي قمت بنشره",
|
||||
"azure.modelListPlaceholder": "يرجى تحديد أو إضافة نموذج OpenAI الذي قمت بنشره",
|
||||
"azure.title": "Azure OpenAI",
|
||||
"azure.token.desc": "عند التحقق من الموارد من بوابة Azure، يمكنك العثور على هذه القيمة في قسم 'المفاتيح ونقاط النهاية'. يمكنك استخدام KEY1 أو KEY2",
|
||||
"azure.token.placeholder": "مفتاح Azure API",
|
||||
"azure.token.desc": "يمكن العثور على هذه القيمة في قسم 'المفاتيح والنقاط النهائية' عند فحص الموارد في بوابة Azure. يمكن استخدام KEY1 أو KEY2",
|
||||
"azure.token.placeholder": "Azure API Key",
|
||||
"azure.token.title": "مفتاح API",
|
||||
"azureai.azureApiVersion.desc": "إصدار واجهة برمجة التطبيقات لـ Azure، باتباع تنسيق YYYY-MM-DD. راجع [أحدث إصدار](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions)",
|
||||
"azureai.azureApiVersion.fetch": "جلب القائمة",
|
||||
"azureai.azureApiVersion.title": "إصدار Azure API",
|
||||
"azureai.endpoint.desc": "اعثر على نقطة نهاية استدلال نموذج Azure AI من نظرة عامة على مشروع Azure AI",
|
||||
"azureai.azureApiVersion.desc": "إصدار واجهة برمجة التطبيقات Azure، يتبع تنسيق YYYY-MM-DD، راجع [الإصدار الأحدث](https://learn.microsoft.com/zh-cn/azure/ai-services/openai/reference#chat-completions)",
|
||||
"azureai.azureApiVersion.fetch": "الحصول على القائمة",
|
||||
"azureai.azureApiVersion.title": "إصدار واجهة برمجة التطبيقات Azure",
|
||||
"azureai.endpoint.desc": "ابحث عن نقطة نهاية استدلال نموذج Azure AI من نظرة عامة على مشروع Azure AI",
|
||||
"azureai.endpoint.placeholder": "https://ai-userxxxxxxxxxx.services.ai.azure.com/models",
|
||||
"azureai.endpoint.title": "نقطة نهاية Azure AI",
|
||||
"azureai.title": "Azure OpenAI",
|
||||
"azureai.token.desc": "اعثر على مفتاح API من نظرة عامة على مشروع Azure AI",
|
||||
"azureai.token.desc": "ابحث عن مفتاح واجهة برمجة التطبيقات من نظرة عامة على مشروع Azure AI",
|
||||
"azureai.token.placeholder": "مفتاح Azure",
|
||||
"azureai.token.title": "المفتاح",
|
||||
"bedrock.accessKeyId.desc": "أدخل معرف مفتاح الوصول لـ AWS",
|
||||
"bedrock.accessKeyId.placeholder": "معرف مفتاح الوصول لـ AWS",
|
||||
"bedrock.accessKeyId.title": "معرف مفتاح الوصول لـ AWS",
|
||||
"bedrock.checker.desc": "اختبر ما إذا تم إدخال AccessKeyId / SecretAccessKey بشكل صحيح",
|
||||
"bedrock.region.desc": "أدخل منطقة AWS",
|
||||
"bedrock.region.placeholder": "منطقة AWS",
|
||||
"bedrock.region.title": "منطقة AWS",
|
||||
"bedrock.secretAccessKey.desc": "أدخل مفتاح الوصول السري لـ AWS",
|
||||
"bedrock.secretAccessKey.placeholder": "مفتاح الوصول السري لـ AWS",
|
||||
"bedrock.secretAccessKey.title": "مفتاح الوصول السري لـ AWS",
|
||||
"bedrock.sessionToken.desc": "إذا كنت تستخدم AWS SSO/STS، يرجى إدخال رمز جلسة AWS",
|
||||
"bedrock.accessKeyId.desc": "أدخل AWS Access Key Id",
|
||||
"bedrock.accessKeyId.placeholder": "AWS Access Key Id",
|
||||
"bedrock.accessKeyId.title": "AWS Access Key Id",
|
||||
"bedrock.checker.desc": "اختبر ما إذا كان AccessKeyId / SecretAccessKey مدخلاً بشكل صحيح",
|
||||
"bedrock.region.desc": "أدخل AWS Region",
|
||||
"bedrock.region.placeholder": "AWS Region",
|
||||
"bedrock.region.title": "AWS Region",
|
||||
"bedrock.secretAccessKey.desc": "أدخل AWS Secret Access Key",
|
||||
"bedrock.secretAccessKey.placeholder": "AWS Secret Access Key",
|
||||
"bedrock.secretAccessKey.title": "AWS Secret Access Key",
|
||||
"bedrock.sessionToken.desc": "إذا كنت تستخدم AWS SSO/STS، يرجى إدخال رمز جلسة AWS الخاص بك",
|
||||
"bedrock.sessionToken.placeholder": "رمز جلسة AWS",
|
||||
"bedrock.sessionToken.title": "رمز جلسة AWS (اختياري)",
|
||||
"bedrock.title": "Bedrock",
|
||||
"bedrock.unlock.customRegion": "منطقة خدمة مخصصة",
|
||||
"bedrock.unlock.customSessionToken": "رمز جلسة مخصص",
|
||||
"bedrock.unlock.description": "أدخل AccessKeyId / SecretAccessKey الخاص بك لبدء الجلسة. لن يقوم التطبيق بتخزين إعدادات المصادقة الخاصة بك",
|
||||
"bedrock.unlock.imageGenerationDescription": "أدخل AccessKeyId / SecretAccessKey الخاص بك لبدء التوليد. لن يقوم التطبيق بتخزين بيانات اعتماد المصادقة الخاصة بك.",
|
||||
"bedrock.unlock.title": "استخدام معلومات مصادقة Bedrock مخصصة",
|
||||
"cloudflare.apiKey.desc": "يرجى إدخال مفتاح Cloudflare API",
|
||||
"cloudflare.apiKey.placeholder": "مفتاح Cloudflare API",
|
||||
"cloudflare.apiKey.title": "مفتاح Cloudflare API",
|
||||
"cloudflare.baseURLOrAccountID.desc": "أدخل معرف حساب Cloudflare أو عنوان API مخصص",
|
||||
"cloudflare.baseURLOrAccountID.placeholder": "معرف حساب Cloudflare / عنوان API مخصص",
|
||||
"cloudflare.baseURLOrAccountID.title": "معرف حساب Cloudflare / عنوان API",
|
||||
"comfyui.apiKey.desc": "مفتاح API لمصادقة Bearer Token",
|
||||
"comfyui.apiKey.placeholder": "أدخل مفتاح API",
|
||||
"bedrock.unlock.customSessionToken": "رمز الجلسة المخصص",
|
||||
"bedrock.unlock.description": "أدخل معرف الوصول / مفتاح الوصول السري الخاص بك في AWS لبدء الجلسة. لن يتم تسجيل تكوين المصادقة الخاص بك من قبل التطبيق",
|
||||
"bedrock.unlock.imageGenerationDescription": "أدخل AWS AccessKeyId / SecretAccessKey الخاص بك للبدء في التوليد. التطبيق لن يقوم بتسجيل إعدادات المصادقة الخاصة بك",
|
||||
"bedrock.unlock.title": "استخدام معلومات المصادقة الخاصة بـ Bedrock المخصصة",
|
||||
"cloudflare.apiKey.desc": "يرجى ملء Cloudflare API Key",
|
||||
"cloudflare.apiKey.placeholder": "Cloudflare API Key",
|
||||
"cloudflare.apiKey.title": "Cloudflare API Key",
|
||||
"cloudflare.baseURLOrAccountID.desc": "أدخل رقم حساب Cloudflare أو عنوان URL API المخصص",
|
||||
"cloudflare.baseURLOrAccountID.placeholder": "رقم حساب Cloudflare / عنوان URL API المخصص",
|
||||
"cloudflare.baseURLOrAccountID.title": "رقم حساب Cloudflare / عنوان URL API",
|
||||
"comfyui.apiKey.desc": "مفتاح API المطلوب لمصادقة Bearer Token",
|
||||
"comfyui.apiKey.placeholder": "يرجى إدخال مفتاح API",
|
||||
"comfyui.apiKey.required": "يرجى إدخال مفتاح API",
|
||||
"comfyui.apiKey.title": "مفتاح API",
|
||||
"comfyui.authType.desc": "اختر طريقة المصادقة للاتصال بخادم ComfyUI",
|
||||
"comfyui.authType.options.basic": "مصادقة أساسية",
|
||||
"comfyui.authType.options.bearer": "رمز Bearer",
|
||||
"comfyui.authType.options.custom": "مصادقة مخصصة",
|
||||
"comfyui.authType.options.none": "بدون مصادقة",
|
||||
"comfyui.authType.desc": "اختر طريقة المصادقة مع خادم ComfyUI",
|
||||
"comfyui.authType.options.basic": "اسم المستخدم/كلمة المرور",
|
||||
"comfyui.authType.options.bearer": "Bearer (مفتاح API)",
|
||||
"comfyui.authType.options.custom": "رؤوس مخصصة",
|
||||
"comfyui.authType.options.none": "لا حاجة للمصادقة",
|
||||
"comfyui.authType.placeholder": "يرجى اختيار نوع المصادقة",
|
||||
"comfyui.authType.title": "نوع المصادقة",
|
||||
"comfyui.baseURL.desc": "عنوان الوصول إلى خادم ComfyUI، مثل http://localhost:8000",
|
||||
"comfyui.baseURL.desc": "عنوان الوصول إلى واجهة ComfyUI على الويب",
|
||||
"comfyui.baseURL.placeholder": "http://127.0.0.1:8000",
|
||||
"comfyui.baseURL.required": "يرجى إدخال عنوان خدمة ComfyUI",
|
||||
"comfyui.baseURL.title": "عنوان خدمة ComfyUI",
|
||||
"comfyui.checker.desc": "اختبر ما إذا تم تكوين الاتصال بشكل صحيح",
|
||||
"comfyui.checker.desc": "اختبار ما إذا كان الاتصال مهيأ بشكل صحيح",
|
||||
"comfyui.checker.title": "فحص الاتصال",
|
||||
"comfyui.customHeaders.addButton": "إضافة ترويسة",
|
||||
"comfyui.customHeaders.deleteTooltip": "حذف هذه الترويسة",
|
||||
"comfyui.customHeaders.desc": "ترويسات الطلب المطلوبة للمصادقة المخصصة، بتنسيق أزواج مفتاح-قيمة",
|
||||
"comfyui.customHeaders.duplicateKeyError": "لا يمكن تكرار أسماء الترويسات",
|
||||
"comfyui.customHeaders.keyPlaceholder": "المفتاح",
|
||||
"comfyui.customHeaders.required": "يرجى إدخال ترويسات الطلب المخصصة",
|
||||
"comfyui.customHeaders.title": "ترويسات مخصصة",
|
||||
"comfyui.customHeaders.addButton": "إضافة رأس طلب",
|
||||
"comfyui.customHeaders.deleteTooltip": "حذف رأس الطلب هذا",
|
||||
"comfyui.customHeaders.desc": "رؤوس الطلب المطلوبة لطريقة المصادقة المخصصة، بتنسيق زوج مفتاح-قيمة",
|
||||
"comfyui.customHeaders.duplicateKeyError": "لا يمكن تكرار أسماء رؤوس الطلب",
|
||||
"comfyui.customHeaders.keyPlaceholder": "اسم المفتاح",
|
||||
"comfyui.customHeaders.required": "يرجى إدخال رؤوس الطلب المخصصة",
|
||||
"comfyui.customHeaders.title": "رؤوس الطلب المخصصة",
|
||||
"comfyui.customHeaders.valuePlaceholder": "القيمة",
|
||||
"comfyui.password.desc": "كلمة المرور للمصادقة الأساسية",
|
||||
"comfyui.password.placeholder": "أدخل كلمة المرور",
|
||||
"comfyui.password.desc": "كلمة المرور المطلوبة للمصادقة الأساسية",
|
||||
"comfyui.password.placeholder": "يرجى إدخال كلمة المرور",
|
||||
"comfyui.password.required": "يرجى إدخال كلمة المرور",
|
||||
"comfyui.password.title": "كلمة المرور",
|
||||
"comfyui.title": "ComfyUI",
|
||||
"comfyui.username.desc": "اسم المستخدم للمصادقة الأساسية",
|
||||
"comfyui.username.placeholder": "أدخل اسم المستخدم",
|
||||
"comfyui.username.desc": "اسم المستخدم المطلوب للمصادقة الأساسية",
|
||||
"comfyui.username.placeholder": "يرجى إدخال اسم المستخدم",
|
||||
"comfyui.username.required": "يرجى إدخال اسم المستخدم",
|
||||
"comfyui.username.title": "اسم المستخدم",
|
||||
"createNewAiProvider.apiKey.placeholder": "يرجى إدخال مفتاح API الخاص بك",
|
||||
"createNewAiProvider.apiKey.title": "مفتاح API",
|
||||
"createNewAiProvider.basicTitle": "معلومات أساسية",
|
||||
"createNewAiProvider.basicTitle": "المعلومات الأساسية",
|
||||
"createNewAiProvider.configTitle": "معلومات التكوين",
|
||||
"createNewAiProvider.confirm": "إنشاء",
|
||||
"createNewAiProvider.confirm": "إنشاء جديد",
|
||||
"createNewAiProvider.createSuccess": "تم الإنشاء بنجاح",
|
||||
"createNewAiProvider.description.placeholder": "وصف المزود (اختياري)",
|
||||
"createNewAiProvider.description.title": "وصف المزود",
|
||||
"createNewAiProvider.description.placeholder": "نبذة عن مزود الخدمة (اختياري)",
|
||||
"createNewAiProvider.description.title": "نبذة عن مزود الخدمة",
|
||||
"createNewAiProvider.id.desc": "معرف فريد لمزود الخدمة، لا يمكن تعديله بعد الإنشاء",
|
||||
"createNewAiProvider.id.format": "يمكن أن يحتوي فقط على أرقام، حروف صغيرة، شرطات (-)، وشرطات سفلية (_)",
|
||||
"createNewAiProvider.id.placeholder": "يفضل أن يكون بحروف صغيرة، مثل openai، لا يمكن تعديله بعد الإنشاء",
|
||||
"createNewAiProvider.id.format": "يمكن أن يحتوي فقط على أرقام، أحرف صغيرة، شرطات (-) وشرطات سفلية (_) ",
|
||||
"createNewAiProvider.id.placeholder": "يفضل أن يكون بالكامل بحروف صغيرة، مثل openai، لن يمكن تعديله بعد الإنشاء",
|
||||
"createNewAiProvider.id.required": "يرجى إدخال معرف المزود",
|
||||
"createNewAiProvider.id.title": "معرف المزود",
|
||||
"createNewAiProvider.logo.placeholder": "https://example.com/logo.png",
|
||||
"createNewAiProvider.logo.required": "يرجى تحميل شعار مزود صالح",
|
||||
"createNewAiProvider.logo.required": "يرجى تحميل شعار المزود بشكل صحيح",
|
||||
"createNewAiProvider.logo.title": "شعار المزود",
|
||||
"createNewAiProvider.name.placeholder": "يرجى إدخال اسم العرض للمزود",
|
||||
"createNewAiProvider.name.placeholder": "يرجى إدخال اسم العرض لمزود الخدمة",
|
||||
"createNewAiProvider.name.required": "يرجى إدخال اسم المزود",
|
||||
"createNewAiProvider.name.title": "اسم المزود",
|
||||
"createNewAiProvider.proxyUrl.placeholder": "https://your-proxy-url.com/v1",
|
||||
@@ -105,183 +105,183 @@
|
||||
"createNewAiProvider.sdkType.placeholder": "openai/anthropic/azureai/ollama/...",
|
||||
"createNewAiProvider.sdkType.required": "يرجى اختيار نوع SDK",
|
||||
"createNewAiProvider.sdkType.title": "تنسيق الطلب",
|
||||
"createNewAiProvider.title": "إنشاء مزود ذكاء اصطناعي مخصص",
|
||||
"github.personalAccessToken.desc": "أدخل رمز الوصول الشخصي (PAT) الخاص بك على GitHub. انقر [هنا](https://github.com/settings/tokens) لإنشاء واحد.",
|
||||
"createNewAiProvider.title": "إنشاء مزود AI مخصص",
|
||||
"github.personalAccessToken.desc": "أدخل رمز الوصول الشخصي الخاص بك على Github، انقر [هنا](https://github.com/settings/tokens) لإنشاء واحد",
|
||||
"github.personalAccessToken.placeholder": "ghp_xxxxxx",
|
||||
"github.personalAccessToken.title": "رمز GitHub PAT",
|
||||
"github.personalAccessToken.title": "GitHub PAT",
|
||||
"huggingface.accessToken.desc": "أدخل رمز HuggingFace الخاص بك، انقر [هنا](https://huggingface.co/settings/tokens) لإنشاء واحد",
|
||||
"huggingface.accessToken.placeholder": "hf_xxxxxxxxx",
|
||||
"huggingface.accessToken.title": "رمز HuggingFace",
|
||||
"list.title.custom": "المزود المخصص غير مفعل",
|
||||
"list.title.disabled": "معطل",
|
||||
"list.title.enabled": "مفعل",
|
||||
"menu.addCustomProvider": "إضافة مزود مخصص",
|
||||
"list.title.custom": "لم يتم تفعيل مزود الخدمة المخصص",
|
||||
"list.title.disabled": "مزود الخدمة غير مفعل",
|
||||
"list.title.enabled": "مزود الخدمة مفعل",
|
||||
"menu.addCustomProvider": "إضافة مزود خدمة مخصص",
|
||||
"menu.all": "الكل",
|
||||
"menu.list.custom": "المخصص غير مفعل",
|
||||
"menu.list.disabled": "معطل",
|
||||
"menu.list.disabledActions.sort": "ترتيب حسب",
|
||||
"menu.list.disabledActions.sortAlphabetical": "ترتيب أبجدي",
|
||||
"menu.list.custom": "المزود المخصص غير مفعل",
|
||||
"menu.list.disabled": "غير مفعل",
|
||||
"menu.list.disabledActions.sort": "طريقة الترتيب",
|
||||
"menu.list.disabledActions.sortAlphabetical": "ترتيب أبجديًا",
|
||||
"menu.list.disabledActions.sortAlphabeticalDesc": "ترتيب أبجدي عكسي",
|
||||
"menu.list.disabledActions.sortDefault": "الترتيب الافتراضي",
|
||||
"menu.list.enabled": "مفعل",
|
||||
"menu.notFound": "لم يتم العثور على نتائج",
|
||||
"menu.notFound": "لم يتم العثور على نتائج البحث",
|
||||
"menu.searchProviders": "البحث عن مزودين...",
|
||||
"menu.sort": "ترتيب مخصص",
|
||||
"newapi.apiKey.desc": "مفتاح API مقدم من منصة New API",
|
||||
"newapi.apiKey.placeholder": "مفتاح New API",
|
||||
"newapi.apiKey.desc": "مفتاح API المقدم من منصة New API",
|
||||
"newapi.apiKey.placeholder": "مفتاح API الخاص بـ New API",
|
||||
"newapi.apiKey.required": "مفتاح API مطلوب",
|
||||
"newapi.apiKey.title": "مفتاح API",
|
||||
"newapi.apiUrl.desc": "نقطة النهاية لخدمة New API، عادةً ما تتضمن /v1",
|
||||
"newapi.apiUrl.title": "رابط API",
|
||||
"newapi.enabled.title": "تفعيل New API",
|
||||
"newapi.models.batchSelect": "تحديد النماذج دفعة واحدة ({{count}} عنصر)",
|
||||
"newapi.apiUrl.desc": "عنوان API لخدمة New API، غالبًا ما يحتاج إلى /v1",
|
||||
"newapi.apiUrl.title": "عنوان API",
|
||||
"newapi.enabled.title": "تمكين New API",
|
||||
"newapi.models.batchSelect": "تحديد نماذج متعددة ({{count}})",
|
||||
"newapi.models.fetch": "جلب قائمة النماذج",
|
||||
"newapi.models.selected": "النماذج المحددة",
|
||||
"newapi.models.selected": "النماذج المختارة",
|
||||
"newapi.models.title": "النماذج المتاحة",
|
||||
"newapi.title": "New API",
|
||||
"ollama.checker.desc": "اختبر ما إذا كان عنوان البروكسي مملوءًا بشكل صحيح",
|
||||
"ollama.checker.desc": "اختبر ما إذا تم إدخال عنوان الوكيل بشكل صحيح",
|
||||
"ollama.checker.title": "فحص الاتصال",
|
||||
"ollama.customModelName.desc": "أضف نماذج مخصصة، افصل بين النماذج بفواصل",
|
||||
"ollama.customModelName.placeholder": "vicuna, llava, codellama, llama2:13b-text",
|
||||
"ollama.customModelName.title": "اسم النموذج المخصص",
|
||||
"ollama.download.desc": "يقوم Ollama بتنزيل النموذج. يُفضل عدم إغلاق هذه الصفحة. سيستأنف التنزيل من حيث توقف إذا تم قطعه.",
|
||||
"ollama.download.failed": "فشل تنزيل النموذج. يرجى التحقق من الشبكة أو إعدادات Ollama والمحاولة مرة أخرى.",
|
||||
"ollama.customModelName.desc": "أضف نماذج مخصصة، استخدم الفاصلة (،) لفصل عدة نماذج",
|
||||
"ollama.customModelName.placeholder": "vicuna,llava,codellama,llama2:13b-text",
|
||||
"ollama.customModelName.title": "أسماء النماذج المخصصة",
|
||||
"ollama.download.desc": "أولاما يقوم بتنزيل هذا النموذج، يرجى عدم إغلاق هذه الصفحة إذا أمكن. سيتم استئناف التنزيل من النقطة التي تم قطعها عند إعادة التحميل",
|
||||
"ollama.download.failed": "فشل تحميل النموذج، يرجى التحقق من الشبكة أو إعدادات Ollama ثم إعادة المحاولة",
|
||||
"ollama.download.remainingTime": "الوقت المتبقي",
|
||||
"ollama.download.speed": "السرعة",
|
||||
"ollama.download.title": "جارٍ تنزيل النموذج {{model}}",
|
||||
"ollama.endpoint.desc": "يجب أن يتضمن http(s)://؛ يمكن تركه فارغًا إذا لم يتم تحديده محليًا.",
|
||||
"ollama.endpoint.title": "عنوان بروكسي الواجهة",
|
||||
"ollama.download.speed": "سرعة التنزيل",
|
||||
"ollama.download.title": "جارٍ تنزيل النموذج {{model}} ",
|
||||
"ollama.endpoint.desc": "يجب أن تحتوي على http(s)://، يمكن تركها فارغة إذا لم يتم تحديدها محليًا",
|
||||
"ollama.endpoint.title": "عنوان وكيل الواجهة",
|
||||
"ollama.title": "Ollama",
|
||||
"ollama.unlock.cancel": "إلغاء التنزيل",
|
||||
"ollama.unlock.confirm": "تنزيل",
|
||||
"ollama.unlock.description": "أدخل وسم نموذج Ollama الخاص بك لمتابعة الجلسة",
|
||||
"ollama.unlock.cancel": "Cancel Download",
|
||||
"ollama.unlock.confirm": "Download",
|
||||
"ollama.unlock.description": "Enter your Ollama model tag to continue the session",
|
||||
"ollama.unlock.downloaded": "{{completed}} / {{total}}",
|
||||
"ollama.unlock.starting": "بدء التنزيل...",
|
||||
"ollama.unlock.title": "تنزيل نموذج Ollama المحدد",
|
||||
"providerModels.batchSelect.selected": "{{count}} نموذج محدد",
|
||||
"providerModels.batchSelect.title": "تحديد جماعي",
|
||||
"providerModels.config.aesGcm": "سيتم تشفير مفتاحك وعنوان البروكسي باستخدام خوارزمية التشفير <1>AES-GCM</1>",
|
||||
"providerModels.config.apiKey.desc": "يرجى إدخال مفتاح API الخاص بـ {{name}}",
|
||||
"providerModels.config.apiKey.descWithUrl": "يرجى إدخال مفتاح API الخاص بـ {{name}}. <3>انقر هنا للحصول عليه</3>",
|
||||
"providerModels.config.apiKey.placeholder": "مفتاح API لـ {{name}}",
|
||||
"ollama.unlock.starting": "Starting download...",
|
||||
"ollama.unlock.title": "Download specified Ollama model",
|
||||
"providerModels.batchSelect.selected": "تم اختيار {{count}} نموذج",
|
||||
"providerModels.batchSelect.title": "تحديد متعدد",
|
||||
"providerModels.config.aesGcm": "سيتم استخدام خوارزمية التشفير <1>AES-GCM</1> لتشفير مفتاحك وعنوان الوكيل وما إلى ذلك",
|
||||
"providerModels.config.apiKey.desc": "يرجى إدخال مفتاح API الخاص بك {{name}}",
|
||||
"providerModels.config.apiKey.descWithUrl": "يرجى إدخال مفتاح API الخاص بـ {{name}}، <3>انقر هنا للحصول عليه</3>",
|
||||
"providerModels.config.apiKey.placeholder": "{{name}} مفتاح API",
|
||||
"providerModels.config.apiKey.title": "مفتاح API",
|
||||
"providerModels.config.baseURL.desc": "يجب أن يتضمن http(s)://",
|
||||
"providerModels.config.baseURL.desc": "يجب أن يحتوي على http(s)://",
|
||||
"providerModels.config.baseURL.invalid": "يرجى إدخال عنوان URL صالح",
|
||||
"providerModels.config.baseURL.placeholder": "https://your-proxy-url.com/v1",
|
||||
"providerModels.config.baseURL.title": "رابط بروكسي API",
|
||||
"providerModels.config.baseURL.title": "عنوان وكيل API",
|
||||
"providerModels.config.checker.button": "تحقق",
|
||||
"providerModels.config.checker.desc": "اختبر ما إذا تم ملء مفتاح API ورابط البروكسي بشكل صحيح",
|
||||
"providerModels.config.checker.desc": "اختبار ما إذا كان مفتاح API وعنوان الوكيل قد تم إدخالهما بشكل صحيح",
|
||||
"providerModels.config.checker.pass": "تم التحقق بنجاح",
|
||||
"providerModels.config.checker.title": "فحص الاتصال",
|
||||
"providerModels.config.fetchOnClient.desc": "وضع طلب العميل سيبدأ الطلبات مباشرة من المتصفح، مما قد يحسن سرعة الاستجابة",
|
||||
"providerModels.config.fetchOnClient.title": "استخدام وضع طلب العميل",
|
||||
"providerModels.config.helpDoc": "دليل الإعداد",
|
||||
"providerModels.config.responsesApi.desc": "يستخدم تنسيق الطلب الجديد من OpenAI لتمكين ميزات متقدمة مثل سلسلة التفكير (مدعومة فقط من نماذج OpenAI)",
|
||||
"providerModels.config.responsesApi.title": "استخدام مواصفات Responses API",
|
||||
"providerModels.config.waitingForMore": "يتم حاليًا <1>التخطيط لإضافة المزيد من النماذج</1>، يرجى المتابعة للبقاء على اطلاع",
|
||||
"providerModels.createNew.title": "إنشاء نموذج ذكاء اصطناعي مخصص",
|
||||
"providerModels.item.config": "إعداد النموذج",
|
||||
"providerModels.config.checker.title": "اختبار الاتصال",
|
||||
"providerModels.config.fetchOnClient.desc": "سيتم بدء طلب الجلسة مباشرة من المتصفح، مما قد يحسن سرعة الاستجابة",
|
||||
"providerModels.config.fetchOnClient.title": "استخدام وضع الطلب من العميل",
|
||||
"providerModels.config.helpDoc": "دليل التكوين",
|
||||
"providerModels.config.responsesApi.desc": "يعتمد تنسيق طلب الجيل الجديد من OpenAI، لتمكين ميزات متقدمة مثل سلسلة التفكير (مدعومة فقط من نماذج OpenAI)",
|
||||
"providerModels.config.responsesApi.title": "استخدام معيار Responses API",
|
||||
"providerModels.config.waitingForMore": "المزيد من النماذج قيد <1>التخطيط للإدماج</1>، يرجى الانتظار",
|
||||
"providerModels.createNew.title": "إنشاء نموذج AI مخصص",
|
||||
"providerModels.item.config": "تكوين النموذج",
|
||||
"providerModels.item.customModelCards.addNew": "إنشاء وإضافة نموذج {{id}}",
|
||||
"providerModels.item.customModelCards.confirmDelete": "أنت على وشك حذف هذا النموذج المخصص. لا يمكن استعادته بعد الحذف. يرجى المتابعة بحذر.",
|
||||
"providerModels.item.delete.confirm": "هل أنت متأكد أنك تريد حذف النموذج {{displayName}}؟",
|
||||
"providerModels.item.customModelCards.confirmDelete": "سيتم حذف هذا النموذج المخصص، ولن يمكن استعادته بعد الحذف، يرجى توخي الحذر.",
|
||||
"providerModels.item.delete.confirm": "هل تؤكد حذف النموذج {{displayName}}؟",
|
||||
"providerModels.item.delete.success": "تم الحذف بنجاح",
|
||||
"providerModels.item.delete.title": "حذف النموذج",
|
||||
"providerModels.item.modelConfig.azureDeployName.extra": "حقل يُستخدم للطلبات الفعلية في Azure OpenAI",
|
||||
"providerModels.item.modelConfig.azureDeployName.extra": "الحقل المطلوب في Azure OpenAI",
|
||||
"providerModels.item.modelConfig.azureDeployName.placeholder": "يرجى إدخال اسم نشر النموذج في Azure",
|
||||
"providerModels.item.modelConfig.azureDeployName.title": "اسم نشر النموذج",
|
||||
"providerModels.item.modelConfig.deployName.extra": "سيُستخدم هذا الحقل كمعرف النموذج عند إرسال الطلبات",
|
||||
"providerModels.item.modelConfig.deployName.extra": "سيتم استخدام هذا الحقل كمعرف نموذج عند إرسال الطلب",
|
||||
"providerModels.item.modelConfig.deployName.placeholder": "يرجى إدخال اسم أو معرف النشر الفعلي للنموذج",
|
||||
"providerModels.item.modelConfig.deployName.title": "اسم نشر النموذج",
|
||||
"providerModels.item.modelConfig.displayName.placeholder": "يرجى إدخال اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ.",
|
||||
"providerModels.item.modelConfig.displayName.placeholder": "يرجى إدخال اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ",
|
||||
"providerModels.item.modelConfig.displayName.title": "اسم عرض النموذج",
|
||||
"providerModels.item.modelConfig.files.extra": "تنفيذ رفع الملفات الحالي هو حل مؤقت، مخصص للتجربة الذاتية فقط. يرجى الانتظار حتى تتوفر إمكانيات رفع الملفات الكاملة في المستقبل.",
|
||||
"providerModels.item.modelConfig.files.title": "دعم رفع الملفات",
|
||||
"providerModels.item.modelConfig.functionCall.extra": "سيمكن هذا الإعداد النموذج من استخدام الأدوات، ولكن قدرة النموذج الفعلية على استخدامها تعتمد عليه بالكامل؛ يرجى الاختبار بنفسك.",
|
||||
"providerModels.item.modelConfig.files.extra": "تنفيذ تحميل الملفات الحالي هو مجرد حل Hack، يقتصر على التجربة الذاتية. يرجى الانتظار حتى يتم تنفيذ القدرة الكاملة لتحميل الملفات لاحقًا",
|
||||
"providerModels.item.modelConfig.files.title": "دعم تحميل الملفات",
|
||||
"providerModels.item.modelConfig.functionCall.extra": "هذا الإعداد سيفتح فقط قدرة النموذج على استخدام الأدوات، مما يسمح بإضافة مكونات إضافية من نوع الأدوات للنموذج. لكن ما إذا كان يمكن استخدام الأدوات فعليًا يعتمد تمامًا على النموذج نفسه، يرجى اختبار مدى قابليته للاستخدام",
|
||||
"providerModels.item.modelConfig.functionCall.title": "دعم استخدام الأدوات",
|
||||
"providerModels.item.modelConfig.id.extra": "لا يمكن تعديله بعد الإنشاء وسيُستخدم كمعرف النموذج عند استدعاء الذكاء الاصطناعي",
|
||||
"providerModels.item.modelConfig.id.extra": "لا يمكن تعديله بعد الإنشاء، سيتم استخدامه كمعرف نموذج عند استدعاء الذكاء الاصطناعي",
|
||||
"providerModels.item.modelConfig.id.placeholder": "يرجى إدخال معرف النموذج، مثل gpt-4o أو claude-3.5-sonnet",
|
||||
"providerModels.item.modelConfig.id.title": "معرف النموذج",
|
||||
"providerModels.item.modelConfig.imageOutput.extra": "يُمكّن هذا الإعداد قدرة النموذج على توليد الصور فقط. الأداء الفعلي يعتمد على النموذج نفسه. يرجى اختباره.",
|
||||
"providerModels.item.modelConfig.imageOutput.extra": "سيؤدي هذا الإعداد فقط إلى تفعيل قدرة النموذج على توليد الصور، وتعتمد النتيجة بالكامل على قدرات النموذج نفسه. يُرجى اختبار ما إذا كان النموذج يدعم توليد الصور بشكل فعّال.",
|
||||
"providerModels.item.modelConfig.imageOutput.title": "يدعم توليد الصور",
|
||||
"providerModels.item.modelConfig.modalTitle": "إعداد النموذج المخصص",
|
||||
"providerModels.item.modelConfig.reasoning.extra": "سيمكن هذا الإعداد قدرات التفكير العميق للنموذج. التأثير الفعلي يعتمد على النموذج. يرجى اختباره.",
|
||||
"providerModels.item.modelConfig.reasoning.title": "دعم التفكير العميق",
|
||||
"providerModels.item.modelConfig.search.extra": "يُمكّن هذا الإعداد قدرة البحث عبر الإنترنت المدمجة في النموذج. يعتمد الدعم على النموذج نفسه. يرجى اختباره.",
|
||||
"providerModels.item.modelConfig.modalTitle": "تكوين النموذج المخصص",
|
||||
"providerModels.item.modelConfig.reasoning.extra": "هذا الإعداد سيفتح فقط قدرة النموذج على التفكير العميق، التأثير الفعلي يعتمد بالكامل على النموذج نفسه، يرجى اختبار ما إذا كان هذا النموذج يمتلك القدرة على التفكير العميق القابل للاستخدام",
|
||||
"providerModels.item.modelConfig.reasoning.title": "يدعم التفكير العميق",
|
||||
"providerModels.item.modelConfig.search.extra": "سيؤدي هذا الإعداد فقط إلى تفعيل قدرة محرك البحث المدمج في النموذج على الاتصال بالإنترنت. تعتمد إمكانية استخدام محرك البحث المدمج على قدرات النموذج نفسه. يُرجى اختبار ما إذا كان محرك البحث المدمج في النموذج يعمل بشكل فعّال.",
|
||||
"providerModels.item.modelConfig.search.title": "يدعم البحث عبر الإنترنت",
|
||||
"providerModels.item.modelConfig.tokens.extra": "تحديد الحد الأقصى لعدد الرموز التي يدعمها النموذج",
|
||||
"providerModels.item.modelConfig.tokens.extra": "تعيين الحد الأقصى لعدد الرموز المدعومة من قبل النموذج",
|
||||
"providerModels.item.modelConfig.tokens.title": "أقصى نافذة سياق",
|
||||
"providerModels.item.modelConfig.tokens.unlimited": "غير محدود",
|
||||
"providerModels.item.modelConfig.type.extra": "أنواع النماذج المختلفة لها استخدامات وقدرات مختلفة",
|
||||
"providerModels.item.modelConfig.type.options.chat": "دردشة",
|
||||
"providerModels.item.modelConfig.type.extra": "أنواع النماذج المختلفة تمتلك سيناريوهات استخدام وقدرات مميزة",
|
||||
"providerModels.item.modelConfig.type.options.chat": "محادثة",
|
||||
"providerModels.item.modelConfig.type.options.embedding": "تضمين",
|
||||
"providerModels.item.modelConfig.type.options.image": "توليد الصور",
|
||||
"providerModels.item.modelConfig.type.options.realtime": "دردشة فورية",
|
||||
"providerModels.item.modelConfig.type.options.stt": "تحويل الكلام إلى نص",
|
||||
"providerModels.item.modelConfig.type.options.text2music": "نص إلى موسيقى",
|
||||
"providerModels.item.modelConfig.type.options.text2video": "نص إلى فيديو",
|
||||
"providerModels.item.modelConfig.type.options.realtime": "محادثة فورية",
|
||||
"providerModels.item.modelConfig.type.options.stt": "تحويل الصوت إلى نص",
|
||||
"providerModels.item.modelConfig.type.options.text2music": "تحويل النص إلى موسيقى",
|
||||
"providerModels.item.modelConfig.type.options.text2video": "تحويل النص إلى فيديو",
|
||||
"providerModels.item.modelConfig.type.options.tts": "تحويل النص إلى كلام",
|
||||
"providerModels.item.modelConfig.type.placeholder": "يرجى اختيار نوع النموذج",
|
||||
"providerModels.item.modelConfig.type.title": "نوع النموذج",
|
||||
"providerModels.item.modelConfig.video.extra": "يُمكّن هذا الإعداد تكوين التعرف على الفيديو داخل التطبيق. يعتمد الدعم على النموذج نفسه. يرجى اختباره.",
|
||||
"providerModels.item.modelConfig.video.extra": "سيؤدي هذا الإعداد فقط إلى تفعيل إعدادات التعرف على الفيديو داخل التطبيق. وتعتمد إمكانية التعرف على الفيديو بالكامل على قدرات النموذج نفسه. يُرجى اختبار ما إذا كان النموذج يدعم التعرف على الفيديو بشكل فعّال.",
|
||||
"providerModels.item.modelConfig.video.title": "يدعم التعرف على الفيديو",
|
||||
"providerModels.item.modelConfig.vision.extra": "يُمكّن هذا الإعداد فقط من رفع الصور داخل التطبيق. يعتمد دعم التعرف على الصور على النموذج نفسه. يرجى اختباره.",
|
||||
"providerModels.item.modelConfig.vision.title": "دعم الرؤية",
|
||||
"providerModels.item.modelConfig.vision.extra": "سيؤدي هذا التكوين إلى فتح إعدادات تحميل الصور في التطبيق، ما إذا كان يدعم التعرف يعتمد بالكامل على النموذج نفسه، يرجى اختبار قابلية استخدام التعرف البصري لهذا النموذج بنفسك",
|
||||
"providerModels.item.modelConfig.vision.title": "دعم التعرف البصري",
|
||||
"providerModels.item.pricing.image": "${{amount}}/صورة",
|
||||
"providerModels.item.pricing.inputCharts": "${{amount}}/مليون حرف",
|
||||
"providerModels.item.pricing.inputCharts": "${{amount}}/M حرف",
|
||||
"providerModels.item.pricing.inputMinutes": "${{amount}}/دقيقة",
|
||||
"providerModels.item.pricing.inputTokens": "المدخلات ${{amount}}/مليون",
|
||||
"providerModels.item.pricing.outputTokens": "المخرجات ${{amount}}/مليون",
|
||||
"providerModels.item.releasedAt": "تم الإصدار في {{releasedAt}}",
|
||||
"providerModels.item.pricing.inputTokens": "إدخال ${{amount}}/م",
|
||||
"providerModels.item.pricing.outputTokens": "إخراج ${{amount}}/م",
|
||||
"providerModels.item.releasedAt": "صدر في {{releasedAt}}",
|
||||
"providerModels.list.addNew": "إضافة نموذج",
|
||||
"providerModels.list.disabled": "معطل",
|
||||
"providerModels.list.disabled": "غير مفعل",
|
||||
"providerModels.list.disabledActions.showMore": "عرض الكل",
|
||||
"providerModels.list.disabledActions.sort": "ترتيب حسب",
|
||||
"providerModels.list.disabledActions.sortAlphabetical": "ترتيب أبجدي",
|
||||
"providerModels.list.disabledActions.sort": "طريقة الترتيب",
|
||||
"providerModels.list.disabledActions.sortAlphabetical": "ترتيب أبجديًا",
|
||||
"providerModels.list.disabledActions.sortAlphabeticalDesc": "ترتيب أبجدي عكسي",
|
||||
"providerModels.list.disabledActions.sortDefault": "الترتيب الافتراضي",
|
||||
"providerModels.list.disabledActions.sortReleasedAt": "ترتيب حسب أقدم تاريخ إصدار",
|
||||
"providerModels.list.disabledActions.sortReleasedAtDesc": "ترتيب حسب أحدث تاريخ إصدار",
|
||||
"providerModels.list.empty.desc": "يرجى إنشاء نموذج مخصص أو سحب نموذج للبدء.",
|
||||
"providerModels.list.empty.desc": "يرجى إنشاء نموذج مخصص أو سحب نموذج للبدء في الاستخدام",
|
||||
"providerModels.list.empty.title": "لا توجد نماذج متاحة",
|
||||
"providerModels.list.enabled": "مفعل",
|
||||
"providerModels.list.enabledActions.disableAll": "تعطيل الكل",
|
||||
"providerModels.list.enabledActions.enableAll": "تفعيل الكل",
|
||||
"providerModels.list.enabledActions.sort": "ترتيب النماذج المخصصة",
|
||||
"providerModels.list.enabledEmpty": "لا توجد نماذج مفعلة. يرجى تفعيل النماذج المفضلة من القائمة أدناه~",
|
||||
"providerModels.list.fetcher.clear": "مسح النماذج المسحوبة",
|
||||
"providerModels.list.fetcher.fetch": "جلب النماذج",
|
||||
"providerModels.list.fetcher.fetching": "جارٍ جلب قائمة النماذج...",
|
||||
"providerModels.list.enabledActions.sort": "ترتيب النموذج حسب التخصيص",
|
||||
"providerModels.list.enabledEmpty": "لا توجد نماذج مفعلة، يرجى تفعيل النماذج المفضلة لديك من القائمة أدناه~",
|
||||
"providerModels.list.fetcher.clear": "مسح النماذج المستخرجة",
|
||||
"providerModels.list.fetcher.fetch": "الحصول على قائمة النماذج",
|
||||
"providerModels.list.fetcher.fetching": "جارٍ الحصول على قائمة النماذج...",
|
||||
"providerModels.list.fetcher.latestTime": "آخر تحديث: {{time}}",
|
||||
"providerModels.list.fetcher.noLatestTime": "لم يتم جلب قائمة النماذج بعد",
|
||||
"providerModels.list.noModelsInCategory": "لا توجد نماذج مفعلة في هذه الفئة",
|
||||
"providerModels.list.resetAll.conform": "هل أنت متأكد أنك تريد إعادة تعيين جميع التعديلات على النموذج الحالي؟ بعد إعادة التعيين، ستعود قائمة النماذج إلى حالتها الافتراضية.",
|
||||
"providerModels.list.fetcher.noLatestTime": "لم يتم الحصول على القائمة بعد",
|
||||
"providerModels.list.noModelsInCategory": "لا توجد نماذج مفعلة في هذا التصنيف",
|
||||
"providerModels.list.resetAll.conform": "هل أنت متأكد من إعادة تعيين جميع التعديلات على النموذج الحالي؟ بعد إعادة التعيين، ستعود قائمة النماذج الحالية إلى الحالة الافتراضية",
|
||||
"providerModels.list.resetAll.success": "تمت إعادة التعيين بنجاح",
|
||||
"providerModels.list.resetAll.title": "إعادة تعيين جميع التعديلات",
|
||||
"providerModels.list.search": "البحث عن نماذج...",
|
||||
"providerModels.list.search": "ابحث عن نموذج...",
|
||||
"providerModels.list.searchResult": "تم العثور على {{count}} نموذج",
|
||||
"providerModels.list.title": "قائمة النماذج",
|
||||
"providerModels.list.total": "{{count}} نموذج متاح",
|
||||
"providerModels.searchNotFound": "لم يتم العثور على نتائج",
|
||||
"providerModels.list.total": "إجمالي {{count}} نموذج متاح",
|
||||
"providerModels.searchNotFound": "لم يتم العثور على نتائج البحث",
|
||||
"providerModels.tabs.all": "الكل",
|
||||
"providerModels.tabs.chat": "دردشة",
|
||||
"providerModels.tabs.embedding": "تضمين",
|
||||
"providerModels.tabs.chat": "الدردشة",
|
||||
"providerModels.tabs.embedding": "التضمين",
|
||||
"providerModels.tabs.image": "صورة",
|
||||
"providerModels.tabs.stt": "تحويل الكلام إلى نص",
|
||||
"providerModels.tabs.tts": "تحويل النص إلى كلام",
|
||||
"sortModal.success": "تم تحديث الترتيب بنجاح",
|
||||
"sortModal.title": "ترتيب مخصص",
|
||||
"sortModal.update": "تحديث",
|
||||
"updateAiProvider.confirmDelete": "أنت على وشك حذف مزود الذكاء الاصطناعي هذا. لا يمكن استعادته بعد الحذف. هل أنت متأكد من الحذف؟",
|
||||
"updateAiProvider.confirmDelete": "سيتم حذف مزود AI هذا، ولن يمكن استعادته بعد الحذف، هل تؤكد الحذف؟",
|
||||
"updateAiProvider.deleteSuccess": "تم الحذف بنجاح",
|
||||
"updateAiProvider.tooltip": "تحديث إعدادات المزود الأساسية",
|
||||
"updateAiProvider.tooltip": "تحديث التكوين الأساسي للمزود",
|
||||
"updateAiProvider.updateSuccess": "تم التحديث بنجاح",
|
||||
"updateCustomAiProvider.title": "تحديث إعدادات مزود الذكاء الاصطناعي المخصص",
|
||||
"vertexai.apiKey.desc": "أدخل مفاتيح Vertex AI الخاصة بك",
|
||||
"vertexai.apiKey.placeholder": "{ \"type\": \"service_account\", \"project_id\": \"xxx\", \"private_key_id\": ... }",
|
||||
"vertexai.apiKey.title": "مفاتيح Vertex AI",
|
||||
"vertexai.region.desc": "اختر المنطقة لخدمة Vertex AI. بعض النماذج مثل Gemini 2.5 متاحة فقط في مناطق محددة (مثل global)",
|
||||
"vertexai.region.desc": "اختر منطقة خدمة Vertex AI. بعض النماذج مثل Gemini 2.5 متاحة فقط في مناطق محددة (مثل global)",
|
||||
"vertexai.region.placeholder": "اختر المنطقة",
|
||||
"vertexai.region.title": "منطقة Vertex AI",
|
||||
"zeroone.title": "01.AI Zero One Everything",
|
||||
"zeroone.title": "01.AI الأشياء الصغرى",
|
||||
"zhipu.title": "Zhipu"
|
||||
}
|
||||
|
||||
+1217
-588
File diff suppressed because it is too large
Load Diff
+22
-22
@@ -1,36 +1,36 @@
|
||||
{
|
||||
"consent.buttons.accept": "السماح",
|
||||
"consent.buttons.accept": "موافقة",
|
||||
"consent.buttons.deny": "رفض",
|
||||
"consent.description": "يطلب التطبيق {{clientName}} إذن الوصول إلى حسابك",
|
||||
"consent.error.sessionInvalid.message": "انتهت صلاحية جلسة التفويض أو أنها غير صالحة. يرجى إعادة بدء عملية التفويض.",
|
||||
"consent.error.sessionInvalid.title": "جلسة تفويض غير صالحة",
|
||||
"consent.description": "تطبيق {{clientName}} يطلب إذن حسابك",
|
||||
"consent.error.sessionInvalid.message": "جلسة التفويض منتهية أو غير صالحة، يرجى إعادة بدء عملية التفويض.",
|
||||
"consent.error.sessionInvalid.title": "جلسة التفويض غير صالحة",
|
||||
"consent.error.title": "حدث خطأ",
|
||||
"consent.error.unknown.message": "حدث خطأ غير معروف أثناء تحميل تفاصيل التفويض.",
|
||||
"consent.error.unsupportedInteraction.message": "نوع التفاعل غير مدعوم: {{promptName}}",
|
||||
"consent.error.unknown.message": "حدث خطأ غير معروف أثناء الحصول على تفاصيل التفويض",
|
||||
"consent.error.unsupportedInteraction.message": "نوع التفاعل غير مدعوم: {promptName}",
|
||||
"consent.error.unsupportedInteraction.title": "نوع التفاعل غير مدعوم",
|
||||
"consent.permissionsTitle": "يطلب الأذونات التالية:",
|
||||
"consent.redirectUri": "سيتم إعادة التوجيه بعد إتمام التفويض بنجاح",
|
||||
"consent.permissionsTitle": "طلب الأذونات التالية:",
|
||||
"consent.redirectUri": "سيتم إعادة التوجيه إلى بعد نجاح التفويض",
|
||||
"consent.redirecting": "تم التفويض بنجاح، جارٍ إعادة التوجيه...",
|
||||
"consent.scope.email": "الوصول إلى عنوان بريدك الإلكتروني",
|
||||
"consent.scope.offline_access": "السماح للتطبيق بالوصول إلى بياناتك",
|
||||
"consent.scope.openid": "تسجيل الدخول باستخدام حساب LobeHub الخاص بك",
|
||||
"consent.scope.profile": "الوصول إلى معلومات ملفك الشخصي الأساسية (الاسم، الصورة الرمزية، إلخ)",
|
||||
"consent.scope.sync-read": "قراءة بياناتك المتزامنة",
|
||||
"consent.scope.sync-write": "كتابة وتحديث بياناتك المتزامنة",
|
||||
"consent.scope.openid": "استخدام حسابك في LobeChat للتحقق من الهوية",
|
||||
"consent.scope.profile": "الوصول إلى معلومات ملفك الشخصي الأساسية (الاسم، الصورة، إلخ)",
|
||||
"consent.scope.sync-read": "قراءة بيانات المزامنة الخاصة بك",
|
||||
"consent.scope.sync-write": "كتابة وتحديث بيانات المزامنة الخاصة بك",
|
||||
"consent.title": "تفويض {{clientName}}",
|
||||
"error.backToHome": "العودة إلى الصفحة الرئيسية",
|
||||
"error.desc": "فشل تفويض OAuth، السبب: {{reason}}",
|
||||
"error.reason.internal_error": "خطأ داخلي في الخادم",
|
||||
"error.reason.invalid_request": "معلمات الطلب غير صالحة",
|
||||
"error.desc": "فشل تفويض OAuth، سبب الفشل: {{reason}}",
|
||||
"error.reason.internal_error": "خطأ في الخادم",
|
||||
"error.reason.invalid_request": "معلمات طلب غير صالحة",
|
||||
"error.title": "فشل التفويض",
|
||||
"handoff.desc.processing": "يقوم التطبيق بمعالجة التفويض وسيتم إعادة التوجيه إلى الصفحة التالية قريبًا...",
|
||||
"handoff.desc.success": "تمت محاولة فتح التطبيق على سطح المكتب. إذا لم يتم فتحه تلقائيًا، يرجى التبديل يدويًا. يمكنك إغلاق نافذة المتصفح لاحقًا.",
|
||||
"handoff.title.processing": "جارٍ تنفيذ التفويض...",
|
||||
"handoff.title.success": "تم التفويض بنجاح",
|
||||
"handoff.desc.processing": "التطبيق يقوم بمعالجة التفويض، سيتم الانتقال إلى الصفحة التالية قريبًا...",
|
||||
"handoff.desc.success": "تمت محاولة فتح التطبيق على سطح المكتب. إذا لم يفتح التطبيق تلقائيًا، يرجى التبديل يدويًا. يمكنك إغلاق نافذة المتصفح هذه لاحقًا.",
|
||||
"handoff.title.processing": "جارٍ معالجة التفويض...",
|
||||
"handoff.title.success": "تم الانتهاء من التفويض",
|
||||
"login.button": "تأكيد تسجيل الدخول",
|
||||
"login.description": "يطلب التطبيق {{clientName}} استخدام حسابك لتسجيل الدخول",
|
||||
"login.description": "التطبيق {{clientName}} يطلب استخدام حسابك لتسجيل الدخول",
|
||||
"login.title": "تسجيل الدخول إلى {{clientName}}",
|
||||
"login.userWelcome": "مرحبًا بعودتك، ",
|
||||
"success.subTitle": "لقد قمت بتفويض التطبيق للوصول إلى حسابك بنجاح. يمكنك الآن إغلاق هذه الصفحة.",
|
||||
"login.userWelcome": "مرحبًا بعودتك،",
|
||||
"success.subTitle": "لقد قمت بتفويض التطبيق للوصول إلى حسابك بنجاح، يمكنك الآن إغلاق هذه الصفحة",
|
||||
"success.title": "تم التفويض بنجاح"
|
||||
}
|
||||
|
||||
+46
-46
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"back": "رجوع",
|
||||
"back": "الخطوة السابقة",
|
||||
"finish": "ابدأ الآن",
|
||||
"interests.area.business": "الأعمال والاستراتيجية",
|
||||
"interests.area.coding": "البرمجة والتطوير",
|
||||
@@ -8,59 +8,59 @@
|
||||
"interests.area.marketing": "التسويق والترويج",
|
||||
"interests.area.other": "مجالات أخرى",
|
||||
"interests.area.product": "المنتجات والإدارة",
|
||||
"interests.area.sales": "المبيعات وخدمة العملاء",
|
||||
"interests.area.sales": "المبيعات والعملاء",
|
||||
"interests.area.writing": "إنشاء المحتوى",
|
||||
"interests.hint": "يمكنك تغيير هذا في أي وقت من الإعدادات",
|
||||
"interests.placeholder": "أدخل اهتماماتك...",
|
||||
"interests.hint": "يمكنك تعديل هذا في الإعدادات في أي وقت",
|
||||
"interests.placeholder": "يرجى إدخال المجالات التي تهمك...",
|
||||
"interests.title": "هل يمكنك إخباري بالمجالات التي تهمك؟",
|
||||
"interests.title2": "سيساعدني هذا في تكوين انطباع أولي عنك~",
|
||||
"interests.title3": "خذ وقتك، وسأتعرف عليك أكثر فأكثر",
|
||||
"modeSelection.desc": "اختر الوضع الذي يناسبك",
|
||||
"modeSelection.hint": "يمكنك تغييره في أي وقت من الإعدادات",
|
||||
"modeSelection.lite.desc": "مثالي للمحادثات اليومية، الأسئلة والأجوبة، الإنتاجية الخفيفة، وتجربة النماذج",
|
||||
"modeSelection.lite.subtitle": "خفيف ومركّز — مثالي للتعاون الفعّال مع وكيل شامل واحد. يمكنك التبديل بين النماذج الشائعة في أي وقت للحفاظ على أفضل حالة تفكير.",
|
||||
"modeSelection.lite.title": "الوضع الخفيف",
|
||||
"modeSelection.pro.desc": "مصمم للمستخدمين الذين يركزون على سير العمل ويبحثون عن تعاون عميق وتخصيص متقدم",
|
||||
"modeSelection.pro.subtitle": "وضع الإنتاجية الاحترافية. قم بإدارة شركة فردية، وتعاون مع عدة وكلاء، وخصص النماذج وسير العمل لبناء مركز ذكي خاص بك.",
|
||||
"modeSelection.pro.title": "الوضع الاحترافي",
|
||||
"modeSelection.title": "ما هو وضع العمل الذي تفضله؟",
|
||||
"modeSelection.title2": "خفيف أم احترافي — القرار لك!",
|
||||
"modeSelection.title3": "أخبرني، لأتمكن من تخصيصه لك~",
|
||||
"next": "التالي",
|
||||
"interests.title2": "ساعدني في تكوين انطباع أولي عنك ~",
|
||||
"interests.title3": "خذ وقتك، سأفهمك أكثر مع مرور الوقت",
|
||||
"modeSelection.desc": "اختر نمط الاستخدام الذي يناسبك",
|
||||
"modeSelection.hint": "يمكنك تغييره في الإعدادات في أي وقت",
|
||||
"modeSelection.lite.desc": "مثالي للمحادثات اليومية، الأسئلة والأجوبة، والمساعدة الخفيفة في العمل وتجربة النماذج",
|
||||
"modeSelection.lite.subtitle": "خفيف ونقي، يفضل التعاون الفعال مع مساعد شامل واحد. يمكنك التبديل بين النماذج الشائعة في أي وقت للحفاظ على أفضل حالة ذهنية.",
|
||||
"modeSelection.lite.title": "Lite خفيف",
|
||||
"modeSelection.pro.desc": "يحتوي على مفهوم سير العمل، ويسعى للتعاون العميق والتخصيص",
|
||||
"modeSelection.pro.subtitle": "وضع الإنتاجية الاحترافية. شركة فردية، تعاون بين عدة مساعدين، تخصيص عميق للنماذج وسير العمل، لبناء مركزك الذكي الخاص.",
|
||||
"modeSelection.pro.title": "Pro احترافي",
|
||||
"modeSelection.title": "ما هو نمط العمل الذي تفضله؟",
|
||||
"modeSelection.title2": "خفيف أم احترافي؟ القرار لك!",
|
||||
"modeSelection.title3": "أخبرني، وسأخصصه لك خصيصًا~",
|
||||
"next": "الخطوة التالية",
|
||||
"proSettings.connectors.title": "اربط أدواتك المفضلة",
|
||||
"proSettings.devMode.title": "وضع المطور",
|
||||
"proSettings.model.title": "النموذج الافتراضي المستخدم من قبل الوكيل",
|
||||
"proSettings.title": "قم بإعداد الخيارات المتقدمة مسبقًا",
|
||||
"proSettings.title2": "جرّب ربط بعض الأدوات الشائعة~",
|
||||
"proSettings.title3": "لنستعد للعمل بكفاءة!",
|
||||
"responseLanguage.auto": "تلقائي (وفقًا للغة النظام)",
|
||||
"responseLanguage.desc": "اختر لغة ردود الوكيل",
|
||||
"responseLanguage.hint": "بعد اختيار اللغة، ستُستخدم هذه اللغة في ردود الذكاء الاصطناعي، كما ستتزامن لغة الواجهة",
|
||||
"responseLanguage.title": "ما اللغة التي تود أن نتواصل بها؟",
|
||||
"responseLanguage.title2": "ابدأ باللغة، وابنِ فهماً حقيقياً.",
|
||||
"responseLanguage.title3": "دعني أتحدث بوضوح وأفهمك بشكل أفضل~",
|
||||
"telemetry.agreement": "جميع البيانات التي يتم جمعها مجهولة وتُستخدم فقط لتحسين تجربة المنتج. بمتابعتك، فإنك تؤكد أنك تفهم وتوافق على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>.",
|
||||
"telemetry.desc": "أنا مساعدك الشخصي — هنا لأساعدك في التفكير، الإبداع، وإدارة الوكلاء والمجموعات.",
|
||||
"proSettings.model.title": "النموذج الافتراضي الذي يستخدمه الوكيل",
|
||||
"proSettings.title": "يمكنك إعداد بعض الخيارات المتقدمة مسبقًا",
|
||||
"proSettings.title2": "جرّب ربط بعض الأدوات الشائعة~",
|
||||
"proSettings.title3": "لنستعد للعمل بكفاءة عالية!",
|
||||
"responseLanguage.auto": "تلقائي (يتبع لغة النظام)",
|
||||
"responseLanguage.desc": "اختر اللغة التي يستخدمها المساعد الذكي في الردود",
|
||||
"responseLanguage.hint": "بعد اختيار اللغة، سيستخدم المساعد هذه اللغة في الردود، كما سيتم تغيير لغة الواجهة تلقائيًا",
|
||||
"responseLanguage.title": "ما اللغة التي نستخدمها للتواصل؟",
|
||||
"responseLanguage.title2": "ابدأ باللغة، لبناء فهم حقيقي.",
|
||||
"responseLanguage.title3": "دعني أتكلم بوضوح، وأفهمك تمامًا ~",
|
||||
"telemetry.agreement": "جميع البيانات التي يتم جمعها مجهولة الهوية وتُستخدم فقط لتحسين تجربة المنتج. من خلال المتابعة، فإنك تؤكد أنك قرأت ووافقت على <terms>الشروط والأحكام</terms> و<privacy>سياسة الخصوصية</privacy>.",
|
||||
"telemetry.desc": "أنا مساعدك الذكي، دائمًا معك للتفكير، الإبداع، وإدارة فريقك من الوكلاء.",
|
||||
"telemetry.helpImprove": "ساعد في تحسين {{appName}}",
|
||||
"telemetry.next": "لنبدأ",
|
||||
"telemetry.privacy": "سياسة الخصوصية",
|
||||
"telemetry.rows.collaborate.desc": "هنا، يعمل الناس والوكلاء معًا، يتعلمون ويتطورون — مما يجعل الإنتاجية تتدفق بشكل طبيعي.",
|
||||
"telemetry.rows.collaborate.title": "تعاون · تطوّر بذكاء",
|
||||
"telemetry.rows.create.desc": "من الفكرة إلى التنفيذ. فقط فكّر، وسيولد وكيلك.",
|
||||
"telemetry.rows.create.title": "أنشئ · حوّل الإلهام إلى واقع",
|
||||
"telemetry.rows.evolve.desc": "كل تفاعل يساعدني على فهمك بشكل أفضل — ليس فقط في الرد، بل في الفهم أيضًا.",
|
||||
"telemetry.rows.evolve.title": "تطوّر · كلما استخدمتني أكثر، فهمتك أكثر",
|
||||
"telemetry.rows.privacy.desc": "نستخدم بيانات مجهولة لتحسين التجربة باستمرار. يمكنك تغيير هذا في أي وقت من تفضيلات الخصوصية.",
|
||||
"telemetry.rows.privacy.title": "لنُحسّن {{appName}} معًا",
|
||||
"telemetry.rows.collaborate.desc": "هنا، يعمل الناس والوكلاء معًا، يتعلمون ويتطورون، لتتدفق الإنتاجية بأكثر الطرق طبيعية.",
|
||||
"telemetry.rows.collaborate.title": "تعاون · تطور ذكي مشترك",
|
||||
"telemetry.rows.create.desc": "فكر، فأنشئ. بمجرد أن تخطر الفكرة، يولد الوكيل.",
|
||||
"telemetry.rows.create.title": "إبداع · الإلهام يتحقق فورًا",
|
||||
"telemetry.rows.evolve.desc": "كل تفاعل يجعلني أفهمك أكثر. ليس فقط في الرد، بل في الفهم أيضًا.",
|
||||
"telemetry.rows.evolve.title": "تطور · كلما استخدمتني، فهمتك أكثر",
|
||||
"telemetry.rows.privacy.desc": "نستخدم بيانات مجهولة لتحسين تجربة {{appName}} باستمرار. وبالطبع، يمكنك تعديل هذا الخيار في إعدادات الخصوصية في أي وقت.",
|
||||
"telemetry.rows.privacy.title": "لنجعل {{appName}} أفضل معًا",
|
||||
"telemetry.terms": "شروط الخدمة",
|
||||
"telemetry.title": "مرحبًا، أنا {{name}}",
|
||||
"telemetry.title2": "تشرفت بلقائك~",
|
||||
"telemetry.title3": "لووووب! لنبدأ!",
|
||||
"telemetry.title2": "سعيد بلقائك ~",
|
||||
"telemetry.title3": "Loooobe! هيا نبدأ!",
|
||||
"title": "مرحبًا بك في {{appName}}",
|
||||
"username.desc": "أخبرنا كيف نُناديك",
|
||||
"username.hint": "يمكنك تغييره في أي وقت من الإعدادات",
|
||||
"username.placeholder": "أدخل اسمك...",
|
||||
"username.title": "بالمناسبة، ماذا يجب أن أُسميك؟",
|
||||
"username.title2": "دعنا نتعرف على بعضنا أولاً!",
|
||||
"username.title3": "هكذا يمكننا التحدث بشكل طبيعي أكثر من الآن فصاعدًا~"
|
||||
"username.desc": "أخبرنا كيف نناديك",
|
||||
"username.hint": "يمكنك تغييره في الإعدادات في أي وقت",
|
||||
"username.placeholder": "يرجى إدخال اسمك...",
|
||||
"username.title": "بالمناسبة، كيف أناديك؟",
|
||||
"username.title2": "دعنا نتعرف عليك أولًا!",
|
||||
"username.title3": "حتى نصبح أكثر ألفة في محادثاتنا القادمة ~"
|
||||
}
|
||||
|
||||
+274
-317
@@ -1,141 +1,100 @@
|
||||
{
|
||||
"arguments.title": "المعلمات",
|
||||
"arguments.title": "قائمة المعلمات",
|
||||
"builtins.lobe-agent-builder.apiName.getAvailableModels": "الحصول على النماذج المتاحة",
|
||||
"builtins.lobe-agent-builder.apiName.getAvailableTools": "الحصول على المهارات المتاحة",
|
||||
"builtins.lobe-agent-builder.apiName.getAvailableTools": "الحصول على الأدوات المتاحة",
|
||||
"builtins.lobe-agent-builder.apiName.getConfig": "الحصول على الإعدادات",
|
||||
"builtins.lobe-agent-builder.apiName.getMeta": "الحصول على البيانات الوصفية",
|
||||
"builtins.lobe-agent-builder.apiName.getPrompt": "الحصول على موجه النظام",
|
||||
"builtins.lobe-agent-builder.apiName.searchMarketTools": "البحث في سوق المهارات",
|
||||
"builtins.lobe-agent-builder.apiName.searchOfficialTools": "البحث في المهارات الرسمية",
|
||||
"builtins.lobe-agent-builder.apiName.getPrompt": "الحصول على التعليمات النظامية",
|
||||
"builtins.lobe-agent-builder.apiName.searchMarketTools": "البحث في سوق الإضافات",
|
||||
"builtins.lobe-agent-builder.apiName.searchOfficialTools": "البحث عن الأدوات الرسمية",
|
||||
"builtins.lobe-agent-builder.apiName.setModel": "تعيين النموذج",
|
||||
"builtins.lobe-agent-builder.apiName.setOpeningMessage": "تعيين رسالة البداية",
|
||||
"builtins.lobe-agent-builder.apiName.setOpeningQuestions": "تعيين الأسئلة الافتتاحية",
|
||||
"builtins.lobe-agent-builder.apiName.togglePlugin": "تفعيل/تعطيل المهارة",
|
||||
"builtins.lobe-agent-builder.apiName.setOpeningQuestions": "تعيين أسئلة البداية",
|
||||
"builtins.lobe-agent-builder.apiName.togglePlugin": "تبديل الإضافة",
|
||||
"builtins.lobe-agent-builder.apiName.updateChatConfig": "تحديث إعدادات المحادثة",
|
||||
"builtins.lobe-agent-builder.apiName.updateConfig": "تحديث الإعدادات",
|
||||
"builtins.lobe-agent-builder.apiName.updateMeta": "تحديث البيانات الوصفية",
|
||||
"builtins.lobe-agent-builder.apiName.updatePrompt": "تحديث موجه النظام",
|
||||
"builtins.lobe-agent-builder.title": "خبير بناء الوكلاء",
|
||||
"builtins.lobe-cloud-sandbox.apiName.editLocalFile": "تعديل الملف",
|
||||
"builtins.lobe-cloud-sandbox.apiName.executeCode": "تنفيذ الكود",
|
||||
"builtins.lobe-cloud-sandbox.apiName.exportFile": "تصدير الملف",
|
||||
"builtins.lobe-cloud-sandbox.apiName.getCommandOutput": "الحصول على ناتج الأمر",
|
||||
"builtins.lobe-cloud-sandbox.apiName.globLocalFiles": "بحث شامل في الملفات",
|
||||
"builtins.lobe-cloud-sandbox.apiName.grepContent": "البحث في المحتوى",
|
||||
"builtins.lobe-cloud-sandbox.apiName.killCommand": "إيقاف الأمر",
|
||||
"builtins.lobe-cloud-sandbox.apiName.listLocalFiles": "عرض الملفات",
|
||||
"builtins.lobe-cloud-sandbox.apiName.moveLocalFiles": "نقل الملفات",
|
||||
"builtins.lobe-cloud-sandbox.apiName.readLocalFile": "قراءة محتوى الملف",
|
||||
"builtins.lobe-cloud-sandbox.apiName.renameLocalFile": "إعادة تسمية",
|
||||
"builtins.lobe-cloud-sandbox.apiName.runCommand": "تشغيل الأمر",
|
||||
"builtins.lobe-cloud-sandbox.apiName.searchLocalFiles": "البحث في الملفات",
|
||||
"builtins.lobe-cloud-sandbox.apiName.writeLocalFile": "كتابة الملف",
|
||||
"builtins.lobe-cloud-sandbox.title": "بيئة سحابية",
|
||||
"builtins.lobe-agent-builder.apiName.updatePrompt": "تحديث التعليمات النظامية",
|
||||
"builtins.lobe-agent-builder.title": "منشئ الوكيل",
|
||||
"builtins.lobe-group-agent-builder.apiName.getAvailableModels": "الحصول على النماذج المتاحة",
|
||||
"builtins.lobe-group-agent-builder.apiName.installPlugin": "تثبيت المهارة",
|
||||
"builtins.lobe-group-agent-builder.apiName.installPlugin": "تثبيت الإضافة",
|
||||
"builtins.lobe-group-agent-builder.apiName.inviteAgent": "دعوة عضو",
|
||||
"builtins.lobe-group-agent-builder.apiName.removeAgent": "إزالة عضو",
|
||||
"builtins.lobe-group-agent-builder.apiName.searchMarketTools": "البحث في سوق المهارات",
|
||||
"builtins.lobe-group-agent-builder.apiName.updateAgentConfig": "تحديث إعدادات العضو",
|
||||
"builtins.lobe-group-agent-builder.apiName.updatePrompt": "تحديث موجه النظام",
|
||||
"builtins.lobe-group-agent-builder.title": "خبير بناء المجموعات",
|
||||
"builtins.lobe-group-management.apiName.broadcast": "تحدث الجميع",
|
||||
"builtins.lobe-group-management.apiName.createAgent": "إضافة عضو للمجموعة",
|
||||
"builtins.lobe-group-agent-builder.apiName.removeAgent": "إزالة العضو",
|
||||
"builtins.lobe-group-agent-builder.apiName.searchMarketTools": "البحث في سوق الإضافات",
|
||||
"builtins.lobe-group-agent-builder.apiName.updateAgentConfig": "تحديث إعدادات الوكيل",
|
||||
"builtins.lobe-group-agent-builder.apiName.updatePrompt": "تحديث التعليمات النظامية",
|
||||
"builtins.lobe-group-agent-builder.title": "منشئ الوكلاء الجماعي",
|
||||
"builtins.lobe-group-management.apiName.broadcast": "إرسال رسالة للجميع",
|
||||
"builtins.lobe-group-management.apiName.createAgent": "إضافة عضو إلى الفريق",
|
||||
"builtins.lobe-group-management.apiName.createWorkflow": "تخطيط سير العمل",
|
||||
"builtins.lobe-group-management.apiName.executeTask": "تنفيذ المهمة",
|
||||
"builtins.lobe-group-management.apiName.getAgentInfo": "الحصول على معلومات العضو",
|
||||
"builtins.lobe-group-management.apiName.interrupt": "مقاطعة المهمة",
|
||||
"builtins.lobe-group-management.apiName.inviteAgent": "دعوة عضو",
|
||||
"builtins.lobe-group-management.apiName.removeAgent": "إزالة عضو",
|
||||
"builtins.lobe-group-management.apiName.searchAgent": "البحث عن خبراء ذوي صلة",
|
||||
"builtins.lobe-group-management.apiName.speak": "تحديد المتحدث",
|
||||
"builtins.lobe-group-management.apiName.searchAgent": "البحث عن خبير ذي صلة",
|
||||
"builtins.lobe-group-management.apiName.speak": "تعيين عضو للتحدث",
|
||||
"builtins.lobe-group-management.apiName.summarize": "تلخيص المحادثة",
|
||||
"builtins.lobe-group-management.apiName.vote": "بدء التصويت",
|
||||
"builtins.lobe-group-management.inspector.broadcast.title": "الوكلاء المتحدثون:",
|
||||
"builtins.lobe-group-management.inspector.speak.title": "المتحدث المحدد:",
|
||||
"builtins.lobe-group-management.title": "منسق المجموعة",
|
||||
"builtins.lobe-group-management.apiName.vote": "بدء تصويت",
|
||||
"builtins.lobe-group-management.title": "تنسيق الفريق",
|
||||
"builtins.lobe-gtd.apiName.clearTodos": "مسح المهام",
|
||||
"builtins.lobe-gtd.apiName.clearTodos.modeAll": "الكل",
|
||||
"builtins.lobe-gtd.apiName.clearTodos.modeCompleted": "المكتملة",
|
||||
"builtins.lobe-gtd.apiName.clearTodos.result": "تم مسح المهام <mode>{{mode}}</mode>",
|
||||
"builtins.lobe-gtd.apiName.completeTodos": "إكمال المهام",
|
||||
"builtins.lobe-gtd.apiName.createPlan": "إنشاء خطة",
|
||||
"builtins.lobe-gtd.apiName.createPlan.result": "تم إنشاء الخطة: <goal>{{goal}}</goal>",
|
||||
"builtins.lobe-gtd.apiName.createTodos": "إنشاء مهام",
|
||||
"builtins.lobe-gtd.apiName.execTask": "تنفيذ المهمة",
|
||||
"builtins.lobe-gtd.apiName.execTask.result": "تم التنفيذ: <desc>{{description}}</desc>",
|
||||
"builtins.lobe-gtd.apiName.execTasks": "تنفيذ المهام",
|
||||
"builtins.lobe-gtd.apiName.removeTodos": "حذف المهام",
|
||||
"builtins.lobe-gtd.apiName.updatePlan": "تحديث الخطة",
|
||||
"builtins.lobe-gtd.apiName.updatePlan.completed": "مكتملة",
|
||||
"builtins.lobe-gtd.apiName.updatePlan.modified": "تم التعديل",
|
||||
"builtins.lobe-gtd.apiName.updateTodos": "تحديث المهام",
|
||||
"builtins.lobe-gtd.title": "أدوات المهام",
|
||||
"builtins.lobe-knowledge-base.apiName.readKnowledge": "قراءة محتوى المكتبة",
|
||||
"builtins.lobe-knowledge-base.apiName.searchKnowledgeBase": "البحث في المكتبة",
|
||||
"builtins.lobe-knowledge-base.inspector.andMoreFiles": "و{{count}} ملفًا آخر",
|
||||
"builtins.lobe-knowledge-base.inspector.noResults": "لا توجد نتائج",
|
||||
"builtins.lobe-knowledge-base.title": "المكتبة",
|
||||
"builtins.lobe-local-system.apiName.editLocalFile": "تعديل الملف",
|
||||
"builtins.lobe-local-system.apiName.getCommandOutput": "الحصول على ناتج الأمر",
|
||||
"builtins.lobe-local-system.apiName.globLocalFiles": "بحث شامل في الملفات",
|
||||
"builtins.lobe-gtd.title": "أداة GTD",
|
||||
"builtins.lobe-knowledge-base.apiName.readKnowledge": "قراءة محتوى قاعدة المعرفة",
|
||||
"builtins.lobe-knowledge-base.apiName.searchKnowledgeBase": "البحث في قاعدة المعرفة",
|
||||
"builtins.lobe-knowledge-base.title": "قاعدة المعرفة",
|
||||
"builtins.lobe-local-system.apiName.editLocalFile": "تحرير الملف",
|
||||
"builtins.lobe-local-system.apiName.getCommandOutput": "الحصول على مخرجات الكود",
|
||||
"builtins.lobe-local-system.apiName.globLocalFiles": "البحث عن الملفات",
|
||||
"builtins.lobe-local-system.apiName.grepContent": "البحث في المحتوى",
|
||||
"builtins.lobe-local-system.apiName.killCommand": "إيقاف الأمر",
|
||||
"builtins.lobe-local-system.apiName.listLocalFiles": "عرض الملفات",
|
||||
"builtins.lobe-local-system.apiName.killCommand": "إيقاف تنفيذ الكود",
|
||||
"builtins.lobe-local-system.apiName.listLocalFiles": "عرض قائمة الملفات",
|
||||
"builtins.lobe-local-system.apiName.moveLocalFiles": "نقل الملفات",
|
||||
"builtins.lobe-local-system.apiName.readLocalFile": "قراءة محتوى الملف",
|
||||
"builtins.lobe-local-system.apiName.renameLocalFile": "إعادة تسمية",
|
||||
"builtins.lobe-local-system.apiName.runCommand": "تشغيل الأمر",
|
||||
"builtins.lobe-local-system.apiName.runCommand": "تنفيذ الكود",
|
||||
"builtins.lobe-local-system.apiName.searchLocalFiles": "البحث في الملفات",
|
||||
"builtins.lobe-local-system.apiName.writeLocalFile": "كتابة الملف",
|
||||
"builtins.lobe-local-system.inspector.noResults": "لا توجد نتائج",
|
||||
"builtins.lobe-local-system.inspector.rename.result": "<old>{{oldName}}</old> → <new>{{newName}}</new>",
|
||||
"builtins.lobe-local-system.apiName.writeLocalFile": "كتابة إلى الملف",
|
||||
"builtins.lobe-local-system.title": "النظام المحلي",
|
||||
"builtins.lobe-page-agent.apiName.batchUpdate": "تحديث جماعي للعقد",
|
||||
"builtins.lobe-page-agent.apiName.batchUpdate": "تحديث الدُفعة للعُقد",
|
||||
"builtins.lobe-page-agent.apiName.compareSnapshots": "مقارنة اللقطات",
|
||||
"builtins.lobe-page-agent.apiName.convertToList": "تحويل إلى قائمة",
|
||||
"builtins.lobe-page-agent.apiName.createNode": "إنشاء عقدة",
|
||||
"builtins.lobe-page-agent.apiName.cropImage": "قص الصورة",
|
||||
"builtins.lobe-page-agent.apiName.cropImage": "اقتصاص الصورة",
|
||||
"builtins.lobe-page-agent.apiName.deleteNode": "حذف العقدة",
|
||||
"builtins.lobe-page-agent.apiName.deleteSnapshot": "حذف اللقطة",
|
||||
"builtins.lobe-page-agent.apiName.deleteTableColumn": "حذف عمود الجدول",
|
||||
"builtins.lobe-page-agent.apiName.deleteTableRow": "حذف صف الجدول",
|
||||
"builtins.lobe-page-agent.apiName.duplicateNode": "نسخ العقدة",
|
||||
"builtins.lobe-page-agent.apiName.editTitle": "إعادة تسمية عنوان الصفحة",
|
||||
"builtins.lobe-page-agent.apiName.editTitle.result": "تمت إعادة التسمية إلى \"<title>{{title}}</title>\"",
|
||||
"builtins.lobe-page-agent.apiName.getPageContent": "الحصول على هيكل المستند",
|
||||
"builtins.lobe-page-agent.apiName.indentListItem": "زيادة المسافة البادئة",
|
||||
"builtins.lobe-page-agent.apiName.initPage": "بدء كتابة المحتوى",
|
||||
"builtins.lobe-page-agent.apiName.initPage.chars": " حرف",
|
||||
"builtins.lobe-page-agent.apiName.initPage.creating": "جاري إنشاء المستند",
|
||||
"builtins.lobe-page-agent.apiName.initPage.lines": " سطر",
|
||||
"builtins.lobe-page-agent.apiName.initPage.result": "تم إنشاء المستند",
|
||||
"builtins.lobe-page-agent.apiName.insertTableColumn": "إدراج عمود جدول",
|
||||
"builtins.lobe-page-agent.apiName.insertTableRow": "إدراج صف جدول",
|
||||
"builtins.lobe-page-agent.apiName.editTitle": "تحرير عنوان المستند",
|
||||
"builtins.lobe-page-agent.apiName.indentListItem": "زيادة المسافة البادئة لعنصر القائمة",
|
||||
"builtins.lobe-page-agent.apiName.initPage": "تهيئة المستند",
|
||||
"builtins.lobe-page-agent.apiName.insertTableColumn": "إدراج عمود في الجدول",
|
||||
"builtins.lobe-page-agent.apiName.insertTableRow": "إدراج صف في الجدول",
|
||||
"builtins.lobe-page-agent.apiName.listSnapshots": "عرض اللقطات",
|
||||
"builtins.lobe-page-agent.apiName.mergeNodes": "دمج العقد",
|
||||
"builtins.lobe-page-agent.apiName.modifyNodes": "تعديل الصفحة",
|
||||
"builtins.lobe-page-agent.apiName.modifyNodes": "تعديل المستند",
|
||||
"builtins.lobe-page-agent.apiName.modifyNodes.addNodes": "إضافة محتوى",
|
||||
"builtins.lobe-page-agent.apiName.modifyNodes.deleteNodes": "حذف محتوى",
|
||||
"builtins.lobe-page-agent.apiName.modifyNodes.init": "التحضير للتعديل",
|
||||
"builtins.lobe-page-agent.apiName.modifyNodes.result": "+{{insert}} / ~{{modify}} / -{{remove}}",
|
||||
"builtins.lobe-page-agent.apiName.modifyNodes.deleteNodes": "حذف المحتوى",
|
||||
"builtins.lobe-page-agent.apiName.moveNode": "نقل العقدة",
|
||||
"builtins.lobe-page-agent.apiName.outdentListItem": "تقليل المسافة البادئة",
|
||||
"builtins.lobe-page-agent.apiName.outdentListItem": "تقليل المسافة البادئة لعنصر القائمة",
|
||||
"builtins.lobe-page-agent.apiName.replaceText": "استبدال النص",
|
||||
"builtins.lobe-page-agent.apiName.replaceText.count": "{{count}} تم استبدالها",
|
||||
"builtins.lobe-page-agent.apiName.replaceText.empty": "(فارغ)",
|
||||
"builtins.lobe-page-agent.apiName.replaceText.init": "التحضير للاستبدال",
|
||||
"builtins.lobe-page-agent.apiName.resizeImage": "تغيير حجم الصورة",
|
||||
"builtins.lobe-page-agent.apiName.restoreSnapshot": "استعادة اللقطة",
|
||||
"builtins.lobe-page-agent.apiName.rotateImage": "تدوير الصورة",
|
||||
"builtins.lobe-page-agent.apiName.saveSnapshot": "حفظ اللقطة",
|
||||
"builtins.lobe-page-agent.apiName.setImageAlt": "تعيين نص بديل للصورة",
|
||||
"builtins.lobe-page-agent.apiName.setImageAlt": "تعيين النص البديل للصورة",
|
||||
"builtins.lobe-page-agent.apiName.splitNode": "تقسيم العقدة",
|
||||
"builtins.lobe-page-agent.apiName.toggleListType": "تبديل نوع القائمة",
|
||||
"builtins.lobe-page-agent.apiName.unwrapNode": "إزالة التغليف",
|
||||
"builtins.lobe-page-agent.apiName.unwrapNode": "إلغاء تغليف العقدة",
|
||||
"builtins.lobe-page-agent.apiName.updateNode": "تحديث العقدة",
|
||||
"builtins.lobe-page-agent.apiName.wrapNodes": "تغليف العقد",
|
||||
"builtins.lobe-page-agent.title": "الصفحة",
|
||||
"builtins.lobe-page-agent.title": "المستند",
|
||||
"builtins.lobe-user-memory.apiName.addContextMemory": "إضافة ذاكرة السياق",
|
||||
"builtins.lobe-user-memory.apiName.addExperienceMemory": "إضافة ذاكرة الخبرة",
|
||||
"builtins.lobe-user-memory.apiName.addIdentityMemory": "إضافة ذاكرة الهوية",
|
||||
@@ -144,193 +103,191 @@
|
||||
"builtins.lobe-user-memory.apiName.searchUserMemory": "البحث في الذاكرة",
|
||||
"builtins.lobe-user-memory.apiName.updateIdentityMemory": "تحديث ذاكرة الهوية",
|
||||
"builtins.lobe-user-memory.title": "الذاكرة",
|
||||
"builtins.lobe-web-browsing.apiName.crawlMultiPages": "قراءة صفحات متعددة",
|
||||
"builtins.lobe-web-browsing.apiName.crawlMultiPages": "قراءة محتوى عدة صفحات",
|
||||
"builtins.lobe-web-browsing.apiName.crawlSinglePage": "قراءة محتوى الصفحة",
|
||||
"builtins.lobe-web-browsing.apiName.search": "البحث في الصفحات",
|
||||
"builtins.lobe-web-browsing.inspector.noResults": "لا توجد نتائج",
|
||||
"builtins.lobe-web-browsing.title": "بحث الويب",
|
||||
"builtins.lobe-web-browsing.title": "البحث عبر الإنترنت",
|
||||
"confirm": "تأكيد",
|
||||
"debug.arguments": "المعلمات",
|
||||
"debug.arguments": "معلمات الاستدعاء",
|
||||
"debug.function_call": "استدعاء الدالة",
|
||||
"debug.intervention": "تدخل المهارة",
|
||||
"debug.off": "إيقاف التصحيح",
|
||||
"debug.on": "عرض معلومات استدعاء المهارة",
|
||||
"debug.payload": "حمولة المهارة",
|
||||
"debug.pluginState": "حالة المهارة",
|
||||
"debug.response": "الاستجابة",
|
||||
"debug.title": "تفاصيل المهارة",
|
||||
"debug.tool_call": "طلب استدعاء المهارة",
|
||||
"detailModal.customPlugin.description": "عرض التفاصيل في صفحة التعديل",
|
||||
"detailModal.customPlugin.editBtn": "تعديل الآن",
|
||||
"detailModal.customPlugin.title": "هذه مهارة مخصصة",
|
||||
"detailModal.emptyState.description": "قم بتثبيت هذه المهارة لعرض إمكانياتها وإعداداتها",
|
||||
"detailModal.emptyState.title": "قم بالتثبيت لعرض تفاصيل المهارة",
|
||||
"debug.on": "عرض معلومات استدعاء الإضافة",
|
||||
"debug.payload": "حمولة الإضافة",
|
||||
"debug.pluginState": "حالة المكون الإضافي",
|
||||
"debug.response": "النتيجة المرجعة",
|
||||
"debug.title": "تفاصيل الإضافة",
|
||||
"debug.tool_call": "طلب استدعاء الأداة",
|
||||
"detailModal.customPlugin.description": "يرجى الانتقال إلى صفحة التحرير لمشاهدة التفاصيل",
|
||||
"detailModal.customPlugin.editBtn": "تحرير الآن",
|
||||
"detailModal.customPlugin.title": "هذه إضافة مخصصة",
|
||||
"detailModal.emptyState.description": "يرجى تثبيت هذه الإضافة أولاً لعرض قدرات الإضافة وخيارات التكوين",
|
||||
"detailModal.emptyState.title": "عرض تفاصيل الإضافة بعد التثبيت",
|
||||
"detailModal.info.description": "وصف API",
|
||||
"detailModal.info.name": "اسم API",
|
||||
"detailModal.tabs.info": "الإمكانيات",
|
||||
"detailModal.tabs.manifest": "البيان",
|
||||
"detailModal.tabs.info": "قدرات الإضافة",
|
||||
"detailModal.tabs.manifest": "ملف التثبيت",
|
||||
"detailModal.tabs.settings": "الإعدادات",
|
||||
"detailModal.title": "تفاصيل المهارة",
|
||||
"dev.confirmDeleteDevPlugin": "سيتم حذف هذه المهارة المحلية نهائيًا. هل ترغب في المتابعة؟",
|
||||
"dev.customParams.useProxy.label": "التثبيت عبر وكيل (فعّل إذا واجهت أخطاء CORS، ثم أعد المحاولة)",
|
||||
"dev.deleteSuccess": "تم حذف المهارة",
|
||||
"dev.manifest.identifier.desc": "معرّف فريد للمهارة",
|
||||
"dev.manifest.identifier.label": "المعرّف",
|
||||
"dev.manifest.mode.mcp": "MCP",
|
||||
"detailModal.title": "تفاصيل الإضافة",
|
||||
"dev.confirmDeleteDevPlugin": "سيتم حذف هذه الإضافة المحلية ولن يمكن استعادتها، هل تريد حذف هذه الإضافة؟",
|
||||
"dev.customParams.useProxy.label": "التثبيت عبر الوكيل (إذا واجهت خطأ وصول عبر النطاق، جرب تفعيل هذا الخيار ثم أعد التثبيت)",
|
||||
"dev.deleteSuccess": "تم حذف الإضافة بنجاح",
|
||||
"dev.manifest.identifier.desc": "المعرف الفريد للإضافة",
|
||||
"dev.manifest.identifier.label": "المعرف",
|
||||
"dev.manifest.mode.mcp": "إضافة MCP",
|
||||
"dev.manifest.mode.mcpExp": "تجريبي",
|
||||
"dev.manifest.mode.url": "رابط مباشر",
|
||||
"dev.manifest.name.desc": "عنوان المهارة",
|
||||
"dev.manifest.name.desc": "عنوان الإضافة",
|
||||
"dev.manifest.name.label": "العنوان",
|
||||
"dev.manifest.name.placeholder": "محرك بحث",
|
||||
"dev.mcp.advanced.title": "خيارات متقدمة",
|
||||
"dev.mcp.args.desc": "المعلمات المرسلة إلى الأمر، عادة اسم خادم MCP أو مسار السكربت",
|
||||
"dev.mcp.args.label": "المعلمات",
|
||||
"dev.manifest.name.placeholder": "محرك البحث",
|
||||
"dev.mcp.advanced.title": "إعدادات متقدمة",
|
||||
"dev.mcp.args.desc": "قائمة المعلمات الممررة لأمر التنفيذ، عادةً هنا يتم إدخال اسم خادم MCP أو مسار سكريبت التشغيل",
|
||||
"dev.mcp.args.label": "معلمات الأمر",
|
||||
"dev.mcp.args.placeholder": "مثال: mcp-hello-world",
|
||||
"dev.mcp.args.required": "أدخل المعلمات",
|
||||
"dev.mcp.args.required": "يرجى إدخال معلمات التشغيل",
|
||||
"dev.mcp.auth.bear": "مفتاح API",
|
||||
"dev.mcp.auth.desc": "اختر طريقة المصادقة لخادم MCP",
|
||||
"dev.mcp.auth.label": "نوع المصادقة",
|
||||
"dev.mcp.auth.none": "بدون مصادقة",
|
||||
"dev.mcp.auth.placeholder": "اختر نوع المصادقة",
|
||||
"dev.mcp.auth.token.desc": "أدخل مفتاح API أو رمز Bearer",
|
||||
"dev.mcp.auth.desc": "اختر طريقة التوثيق لخادم MCP",
|
||||
"dev.mcp.auth.label": "نوع التوثيق",
|
||||
"dev.mcp.auth.none": "لا حاجة للتوثيق",
|
||||
"dev.mcp.auth.placeholder": "يرجى اختيار نوع التوثيق",
|
||||
"dev.mcp.auth.token.desc": "أدخل مفتاح API أو رمز الحامل الخاص بك",
|
||||
"dev.mcp.auth.token.label": "مفتاح API",
|
||||
"dev.mcp.auth.token.placeholder": "sk-xxxxx",
|
||||
"dev.mcp.auth.token.required": "أدخل رمز المصادقة",
|
||||
"dev.mcp.avatar.label": "أيقونة المهارة",
|
||||
"dev.mcp.command.desc": "الأمر أو السكربت لتشغيل خادم MCP STDIO",
|
||||
"dev.mcp.auth.token.required": "يرجى إدخال رمز التوثيق",
|
||||
"dev.mcp.avatar.label": "أيقونة الإضافة",
|
||||
"dev.mcp.command.desc": "الملف التنفيذي أو السكريبت المستخدم لتشغيل خادم MCP STDIO",
|
||||
"dev.mcp.command.label": "الأمر",
|
||||
"dev.mcp.command.placeholder": "مثال: npx / uv / docker",
|
||||
"dev.mcp.command.required": "أدخل الأمر",
|
||||
"dev.mcp.desc.desc": "أضف وصفًا للمهارة",
|
||||
"dev.mcp.desc.label": "الوصف",
|
||||
"dev.mcp.desc.placeholder": "تعليمات الاستخدام والسيناريوهات",
|
||||
"dev.mcp.endpoint.desc": "أدخل عنوان خادم MCP القابل للبث عبر HTTP",
|
||||
"dev.mcp.endpoint.label": "رابط MCP",
|
||||
"dev.mcp.env.add": "إضافة صف",
|
||||
"dev.mcp.env.desc": "أدخل متغيرات البيئة لخادم MCP",
|
||||
"dev.mcp.env.duplicateKeyError": "يجب أن تكون المفاتيح فريدة",
|
||||
"dev.mcp.env.formValidationFailed": "فشل التحقق من النموذج، تحقق من التنسيق",
|
||||
"dev.mcp.env.keyRequired": "المفتاح مطلوب",
|
||||
"dev.mcp.command.placeholder": "مثال: npx / uv / docker إلخ",
|
||||
"dev.mcp.command.required": "يرجى إدخال أمر التشغيل",
|
||||
"dev.mcp.desc.desc": "أضف وصفًا للإضافة",
|
||||
"dev.mcp.desc.label": "وصف الإضافة",
|
||||
"dev.mcp.desc.placeholder": "أضف معلومات عن استخدام الإضافة وسيناريوهاتها",
|
||||
"dev.mcp.endpoint.desc": "أدخل عنوان خادم MCP Streamable HTTP الخاص بك",
|
||||
"dev.mcp.endpoint.label": "رابط نقطة نهاية MCP",
|
||||
"dev.mcp.env.add": "أضف سطرًا جديدًا",
|
||||
"dev.mcp.env.desc": "أدخل متغيرات البيئة المطلوبة لخادم MCP",
|
||||
"dev.mcp.env.duplicateKeyError": "مفتاح الحقل يجب أن يكون فريدًا",
|
||||
"dev.mcp.env.formValidationFailed": "فشل التحقق من النموذج، يرجى مراجعة تنسيق المعلمات",
|
||||
"dev.mcp.env.keyRequired": "مفتاح الحقل لا يمكن أن يكون فارغًا",
|
||||
"dev.mcp.env.label": "متغيرات بيئة خادم MCP",
|
||||
"dev.mcp.env.stringifyError": "لا يمكن التسلسل، تحقق من التنسيق",
|
||||
"dev.mcp.headers.add": "إضافة صف",
|
||||
"dev.mcp.headers.desc": "أدخل رؤوس HTTP",
|
||||
"dev.mcp.env.stringifyError": "تعذر تسلسل المعلمات، يرجى مراجعة التنسيق",
|
||||
"dev.mcp.headers.add": "أضف سطرًا جديدًا",
|
||||
"dev.mcp.headers.desc": "أدخل رؤوس الطلب",
|
||||
"dev.mcp.headers.label": "رؤوس HTTP",
|
||||
"dev.mcp.identifier.desc": "اسم لهذا MCP (أحرف إنجليزية فقط)",
|
||||
"dev.mcp.identifier.invalid": "يجب أن يحتوي المعرّف على أحرف، أرقام، شرطات أو شرطات سفلية فقط",
|
||||
"dev.mcp.identifier.label": "اسم MCP",
|
||||
"dev.mcp.identifier.desc": "حدد اسمًا لإضافة MCP الخاصة بك، يجب أن يكون بالأحرف الإنجليزية",
|
||||
"dev.mcp.identifier.invalid": "المعرف يمكن أن يحتوي فقط على أحرف، أرقام، شرطات وشرطات سفلية",
|
||||
"dev.mcp.identifier.label": "اسم إضافة MCP",
|
||||
"dev.mcp.identifier.placeholder": "مثال: my-mcp-plugin",
|
||||
"dev.mcp.identifier.required": "أدخل معرّف MCP",
|
||||
"dev.mcp.previewManifest": "معاينة البيان",
|
||||
"dev.mcp.quickImport": "استيراد إعدادات JSON",
|
||||
"dev.mcp.quickImportError.empty": "المحتوى لا يمكن أن يكون فارغًا",
|
||||
"dev.mcp.quickImportError.invalidJson": "JSON غير صالح",
|
||||
"dev.mcp.identifier.required": "يرجى إدخال معرف خدمة MCP",
|
||||
"dev.mcp.previewManifest": "معاينة ملف وصف الإضافة",
|
||||
"dev.mcp.quickImport": "استيراد سريع لتكوين JSON",
|
||||
"dev.mcp.quickImportError.empty": "لا يمكن أن يكون المحتوى فارغًا",
|
||||
"dev.mcp.quickImportError.invalidJson": "تنسيق JSON غير صالح",
|
||||
"dev.mcp.quickImportError.invalidStructure": "هيكل JSON غير صالح",
|
||||
"dev.mcp.stdioNotSupported": "STDIO MCP غير مدعوم في البيئة الحالية",
|
||||
"dev.mcp.stdioNotSupported": "البيئة الحالية لا تدعم إضافات MCP من نوع stdio",
|
||||
"dev.mcp.testConnection": "اختبار الاتصال",
|
||||
"dev.mcp.testConnectionTip": "سيكون MCP متاحًا بعد نجاح اختبار الاتصال",
|
||||
"dev.mcp.type.desc": "اختر نوع MCP، الويب يدعم فقط HTTP القابل للبث",
|
||||
"dev.mcp.testConnectionTip": "يجب أن ينجح اختبار الاتصال لكي تعمل إضافة MCP بشكل صحيح",
|
||||
"dev.mcp.type.desc": "اختر طريقة اتصال إضافة MCP، النسخة الويب تدعم فقط Streamable HTTP",
|
||||
"dev.mcp.type.httpFeature1": "متوافق مع الويب وسطح المكتب",
|
||||
"dev.mcp.type.httpFeature2": "اتصال بخادم MCP عن بُعد، لا حاجة للإعداد",
|
||||
"dev.mcp.type.httpShortDesc": "بروتوكول HTTP القابل للبث",
|
||||
"dev.mcp.type.label": "نوع MCP",
|
||||
"dev.mcp.type.stdioFeature1": "زمن استجابة أقل، للتنفيذ المحلي",
|
||||
"dev.mcp.type.stdioFeature2": "يتطلب تثبيت خادم MCP محلي",
|
||||
"dev.mcp.type.stdioNotAvailable": "STDIO متاح فقط على سطح المكتب",
|
||||
"dev.mcp.type.stdioShortDesc": "بروتوكول الإدخال/الإخراج القياسي",
|
||||
"dev.mcp.type.title": "نوع MCP",
|
||||
"dev.mcp.url.desc": "أدخل رابط خادم MCP عبر HTTP القابل للبث (SSE غير مدعوم)",
|
||||
"dev.mcp.url.invalid": "أدخل رابطًا صالحًا",
|
||||
"dev.mcp.url.label": "رابط HTTP القابل للبث",
|
||||
"dev.mcp.url.required": "أدخل رابط خادم MCP",
|
||||
"dev.meta.author.desc": "مؤلف المهارة",
|
||||
"dev.mcp.type.httpFeature2": "اتصال بخادم MCP عن بعد، لا حاجة لتثبيت إضافي",
|
||||
"dev.mcp.type.httpShortDesc": "بروتوكول اتصال HTTP متدفق",
|
||||
"dev.mcp.type.label": "نوع إضافة MCP",
|
||||
"dev.mcp.type.stdioFeature1": "تأخير اتصال أقل، مناسب للتنفيذ المحلي",
|
||||
"dev.mcp.type.stdioFeature2": "يجب تثبيت وتشغيل خادم MCP محليًا",
|
||||
"dev.mcp.type.stdioNotAvailable": "وضع STDIO متاح فقط في نسخة سطح المكتب",
|
||||
"dev.mcp.type.stdioShortDesc": "بروتوكول اتصال يعتمد على الإدخال والإخراج القياسي",
|
||||
"dev.mcp.type.title": "نوع إضافة MCP",
|
||||
"dev.mcp.url.desc": "أدخل عنوان MCP Server Streamable HTTP الخاص بك، لا يدعم وضع SSE",
|
||||
"dev.mcp.url.invalid": "يرجى إدخال عنوان URL صالح",
|
||||
"dev.mcp.url.label": "رابط نقطة نهاية HTTP المتدفق",
|
||||
"dev.mcp.url.required": "يرجى إدخال عنوان URL لخدمة MCP",
|
||||
"dev.meta.author.desc": "مؤلف الإضافة",
|
||||
"dev.meta.author.label": "المؤلف",
|
||||
"dev.meta.avatar.desc": "أيقونة المهارة (رمز تعبيري أو رابط)",
|
||||
"dev.meta.avatar.desc": "أيقونة الإضافة، يمكن استخدام إيموجي أو رابط URL",
|
||||
"dev.meta.avatar.label": "الأيقونة",
|
||||
"dev.meta.description.desc": "وصف المهارة",
|
||||
"dev.meta.description.desc": "وصف الإضافة",
|
||||
"dev.meta.description.label": "الوصف",
|
||||
"dev.meta.description.placeholder": "محرك بحث للمعلومات",
|
||||
"dev.meta.formFieldRequired": "حقل مطلوب",
|
||||
"dev.meta.homepage.desc": "الصفحة الرئيسية للمهارة",
|
||||
"dev.meta.description.placeholder": "ابحث في محرك البحث للحصول على معلومات",
|
||||
"dev.meta.formFieldRequired": "هذا الحقل مطلوب",
|
||||
"dev.meta.homepage.desc": "الصفحة الرئيسية للإضافة",
|
||||
"dev.meta.homepage.label": "الصفحة الرئيسية",
|
||||
"dev.meta.identifier.desc": "معرّف فريد، يتم اكتشافه تلقائيًا من البيان",
|
||||
"dev.meta.identifier.errorDuplicate": "المعرّف يتعارض مع مهارة موجودة",
|
||||
"dev.meta.identifier.label": "المعرّف",
|
||||
"dev.meta.identifier.pattenErrorMessage": "يسمح فقط بالأحرف، الأرقام، الشرطات، والشرطات السفلية",
|
||||
"dev.meta.lobe": "مهارة {{appName}}",
|
||||
"dev.meta.manifest.desc": "{{appName}} سيقوم بتثبيت المهارة عبر هذا الرابط",
|
||||
"dev.meta.manifest.label": "رابط البيان",
|
||||
"dev.meta.manifest.preview": "معاينة البيان",
|
||||
"dev.meta.identifier.desc": "المعرف الفريد للإضافة، سيتم التعرف عليه تلقائيًا من ملف manifest",
|
||||
"dev.meta.identifier.errorDuplicate": "المعرف مكرر مع إضافة موجودة، يرجى تغييره",
|
||||
"dev.meta.identifier.label": "المعرف",
|
||||
"dev.meta.identifier.pattenErrorMessage": "يمكن إدخال أحرف إنجليزية، أرقام، - و _ فقط",
|
||||
"dev.meta.lobe": "إضافة {{appName}}",
|
||||
"dev.meta.manifest.desc": "سيتم تثبيت {{appName}} عبر هذا الرابط",
|
||||
"dev.meta.manifest.label": "رابط ملف وصف الإضافة (Manifest)",
|
||||
"dev.meta.manifest.preview": "معاينة Manifest",
|
||||
"dev.meta.manifest.refresh": "تحديث",
|
||||
"dev.meta.openai": "مهارة OpenAI",
|
||||
"dev.meta.title.desc": "عنوان المهارة",
|
||||
"dev.meta.openai": "إضافة OpenAI",
|
||||
"dev.meta.title.desc": "عنوان الإضافة",
|
||||
"dev.meta.title.label": "العنوان",
|
||||
"dev.meta.title.placeholder": "محرك بحث",
|
||||
"dev.metaConfig": "إعدادات التعريف",
|
||||
"dev.modalDesc": "يمكن استخدام المهارات المخصصة للتطوير أو مباشرة في المحادثات. راجع <1>الوثائق↗</1>",
|
||||
"dev.openai.importUrl": "استيراد من رابط",
|
||||
"dev.meta.title.placeholder": "محرك البحث",
|
||||
"dev.metaConfig": "تكوين معلومات الإضافة الأساسية",
|
||||
"dev.modalDesc": "بعد إضافة إضافة مخصصة، يمكن استخدامها للتحقق من تطوير الإضافة أو استخدامها مباشرة في المحادثة. يرجى الرجوع إلى <1>وثائق التطوير↗</> لتطوير الإضافات.",
|
||||
"dev.openai.importUrl": "استيراد من رابط URL",
|
||||
"dev.openai.schema": "المخطط",
|
||||
"dev.preview.api.noParams": "لا توجد معلمات",
|
||||
"dev.preview.api.noResults": "لم يتم العثور على واجهات API",
|
||||
"dev.preview.api.noParams": "هذه الأداة لا تحتوي على معلمات",
|
||||
"dev.preview.api.noResults": "لم يتم العثور على API تطابق شروط البحث",
|
||||
"dev.preview.api.params": "المعلمات:",
|
||||
"dev.preview.api.searchPlaceholder": "ابحث عن مهارات…",
|
||||
"dev.preview.card": "بطاقة معاينة المهارة",
|
||||
"dev.preview.desc": "وصف المعاينة",
|
||||
"dev.preview.empty.desc": "أكمل الإعداد لمعاينة إمكانيات المهارة",
|
||||
"dev.preview.empty.title": "قم بالإعداد للمعاينة",
|
||||
"dev.preview.title": "معاينة اسم المهارة",
|
||||
"dev.save": "تثبيت",
|
||||
"dev.saveSuccess": "تم حفظ الإعدادات",
|
||||
"dev.tabs.manifest": "البيان",
|
||||
"dev.tabs.meta": "معلومات التعريف",
|
||||
"dev.title.create": "إضافة مهارة مخصصة",
|
||||
"dev.title.edit": "تعديل مهارة مخصصة",
|
||||
"dev.type.lobe": "مهارة {{appName}}",
|
||||
"dev.type.openai": "مهارة OpenAI",
|
||||
"dev.preview.api.searchPlaceholder": "ابحث عن أداة...",
|
||||
"dev.preview.card": "معاينة عرض الإضافة",
|
||||
"dev.preview.desc": "معاينة وصف الإضافة",
|
||||
"dev.preview.empty.desc": "بعد إكمال التكوين، يمكنك معاينة قدرات الأدوات المدعومة هنا",
|
||||
"dev.preview.empty.title": "ابدأ المعاينة بعد تكوين الإضافة",
|
||||
"dev.preview.title": "معاينة اسم الإضافة",
|
||||
"dev.save": "تثبيت الإضافة",
|
||||
"dev.saveSuccess": "تم حفظ إعدادات الإضافة بنجاح",
|
||||
"dev.tabs.manifest": "قائمة وصف الوظائف (Manifest)",
|
||||
"dev.tabs.meta": "معلومات الإضافة الأساسية",
|
||||
"dev.title.create": "إضافة إضافة مخصصة",
|
||||
"dev.title.edit": "تحرير إضافة مخصصة",
|
||||
"dev.type.lobe": "إضافة {{appName}}",
|
||||
"dev.type.openai": "إضافة OpenAI",
|
||||
"dev.update": "تحديث",
|
||||
"dev.updateSuccess": "تم تحديث الإعدادات",
|
||||
"empty.description": "تصفح متجر المهارات. قم بتثبيت واحدة للبدء، وأضف المزيد لاحقًا.",
|
||||
"empty.search": "لا توجد مهارات مطابقة",
|
||||
"empty.title": "لا توجد مهارات",
|
||||
"dev.updateSuccess": "تم تحديث إعدادات الإضافة بنجاح",
|
||||
"empty.description": "يحتوي متجر الإضافات على العديد من الأدوات في انتظارك لاكتشافها، قم بزيارة المتجر وابدأ الاستكشاف",
|
||||
"empty.search": "لم يتم العثور على إضافات مطابقة",
|
||||
"empty.title": "لا توجد إضافات حالياً",
|
||||
"error.details": "تفاصيل الخطأ",
|
||||
"error.fetchError": "فشل في جلب البيان. تحقق من الرابط وصلاحيات CORS",
|
||||
"error.installError": "فشل في تثبيت {{name}}",
|
||||
"error.manifestInvalid": "بيان غير صالح:\n\n{{error}}",
|
||||
"error.noManifest": "لم يتم العثور على البيان",
|
||||
"error.openAPIInvalid": "فشل تحليل OpenAPI:\n\n{{error}}",
|
||||
"error.reinstallError": "فشل في تحديث {{name}}",
|
||||
"error.renderError": "خطأ في العرض",
|
||||
"error.testConnectionFailed": "فشل في جلب البيان: {{error}}",
|
||||
"error.unknownError": "خطأ غير معروف",
|
||||
"error.urlError": "الرابط لم يُرجع JSON، تحقق من الرابط",
|
||||
"inspector.args": "عرض المعلمات",
|
||||
"inspector.delete": "حذف الاستدعاء",
|
||||
"inspector.orphanedToolCall": "تم اكتشاف استدعاء مهارة يتيم، قد يؤثر على تنفيذ الوكيل. قم بإزالته.",
|
||||
"inspector.pluginRender": "عرض واجهة المهارة",
|
||||
"error.fetchError": "فشل طلب رابط manifest، يرجى التأكد من صلاحية الرابط وفحص ما إذا كان يسمح بالوصول عبر النطاق",
|
||||
"error.installError": "فشل تثبيت الإضافة {{name}}",
|
||||
"error.manifestInvalid": "الملف manifest غير مطابق للمواصفات، نتيجة التحقق: \n\n {{error}}",
|
||||
"error.noManifest": "ملف الوصف غير موجود",
|
||||
"error.openAPIInvalid": "فشل تحليل OpenAPI، الخطأ: \n\n {{error}}",
|
||||
"error.reinstallError": "فشل تحديث الإضافة {{name}}",
|
||||
"error.renderError": "خطأ في عرض الأداة",
|
||||
"error.testConnectionFailed": "فشل الحصول على Manifest: {{error}}",
|
||||
"error.unknownError": "حدث خطأ غير معروف",
|
||||
"error.urlError": "الرابط لم يرجع محتوى بصيغة JSON، يرجى التأكد من صحة الرابط",
|
||||
"inspector.args": "عرض قائمة المعلمات",
|
||||
"inspector.delete": "حذف استدعاء الأداة",
|
||||
"inspector.orphanedToolCall": "قد تكون رسالة استدعاء الأداة هذه معزولة بسبب ظروف غير طبيعية، مما قد يؤثر على تنفيذ الوكيل بشكل صحيح. يُرجى إزالتها.",
|
||||
"inspector.pluginRender": "عرض واجهة الإضافة",
|
||||
"list.item.deprecated.title": "تم الحذف",
|
||||
"list.item.local.config": "الإعداد",
|
||||
"list.item.local.config": "الإعدادات",
|
||||
"list.item.local.title": "مخصص",
|
||||
"loading.content": "جارٍ استدعاء المهارة…",
|
||||
"loading.plugin": "المهارة قيد التشغيل…",
|
||||
"mcpEmpty.deployment": "لا توجد خيارات نشر",
|
||||
"mcpEmpty.prompts": "لا توجد مطالبات",
|
||||
"mcpEmpty.resources": "لا توجد موارد",
|
||||
"mcpEmpty.tools": "لا توجد أدوات",
|
||||
"mcpInstall.CHECKING_INSTALLATION": "جارٍ التحقق من التثبيت…",
|
||||
"mcpInstall.COMPLETED": "اكتمل",
|
||||
"mcpInstall.CONFIGURATION_REQUIRED": "أكمل الإعداد للمتابعة",
|
||||
"loading.content": "جارٍ استدعاء الإضافة...",
|
||||
"loading.plugin": "تشغيل الإضافة...",
|
||||
"mcpEmpty.deployment": "لا توجد خيارات نشر حالياً",
|
||||
"mcpEmpty.prompts": "لا توجد مطالبات متاحة لهذه الإضافة حالياً",
|
||||
"mcpEmpty.resources": "لا توجد موارد متاحة لهذه الإضافة حالياً",
|
||||
"mcpEmpty.tools": "لا توجد قدرات أدوات متاحة لهذه الإضافة حالياً",
|
||||
"mcpInstall.CHECKING_INSTALLATION": "جارٍ فحص بيئة التثبيت...",
|
||||
"mcpInstall.COMPLETED": "اكتمل التثبيت",
|
||||
"mcpInstall.CONFIGURATION_REQUIRED": "يرجى إكمال التكوين المطلوب للمتابعة بالتثبيت",
|
||||
"mcpInstall.ERROR": "خطأ في التثبيت",
|
||||
"mcpInstall.FETCHING_MANIFEST": "جارٍ جلب الملف التعريفي…",
|
||||
"mcpInstall.GETTING_SERVER_MANIFEST": "جارٍ تهيئة خادم MCP…",
|
||||
"mcpInstall.INSTALLING_PLUGIN": "جارٍ تثبيت المهارة…",
|
||||
"mcpInstall.configurationDescription": "قم بإعداد المعلمات المطلوبة لهذا الـ MCP",
|
||||
"mcpInstall.configurationRequired": "إعداد المعلمات",
|
||||
"mcpInstall.continueInstall": "متابعة",
|
||||
"mcpInstall.dependenciesDescription": "قم بتثبيت التبعيات المطلوبة، ثم أعد التحقق للمتابعة.",
|
||||
"mcpInstall.dependenciesRequired": "تثبيت تبعيات النظام",
|
||||
"mcpInstall.FETCHING_MANIFEST": "جارٍ الحصول على ملف وصف الإضافة...",
|
||||
"mcpInstall.GETTING_SERVER_MANIFEST": "جارٍ تهيئة خادم MCP...",
|
||||
"mcpInstall.INSTALLING_PLUGIN": "جارٍ تثبيت الإضافة...",
|
||||
"mcpInstall.configurationDescription": "تتطلب هذه الإضافة MCP إعداد معلمات لتعمل بشكل صحيح، يرجى ملء المعلومات اللازمة",
|
||||
"mcpInstall.configurationRequired": "تكوين معلمات الإضافة",
|
||||
"mcpInstall.continueInstall": "متابعة التثبيت",
|
||||
"mcpInstall.dependenciesDescription": "تتطلب هذه الإضافة تثبيت تبعيات نظامية لتعمل بشكل صحيح، يرجى تثبيت التبعيات المفقودة حسب التعليمات ثم اضغط إعادة الفحص للمتابعة بالتثبيت.",
|
||||
"mcpInstall.dependenciesRequired": "يرجى تثبيت تبعيات النظام للإضافة",
|
||||
"mcpInstall.dependencyStatus.installed": "مثبت",
|
||||
"mcpInstall.dependencyStatus.notInstalled": "غير مثبت",
|
||||
"mcpInstall.dependencyStatus.requiredVersion": "المطلوب: {{version}}",
|
||||
"mcpInstall.dependencyStatus.requiredVersion": "الإصدار المطلوب: {{version}}",
|
||||
"mcpInstall.errorDetails.args": "المعلمات",
|
||||
"mcpInstall.errorDetails.command": "الأمر",
|
||||
"mcpInstall.errorDetails.connectionParams": "معلمات الاتصال",
|
||||
@@ -340,121 +297,121 @@
|
||||
"mcpInstall.errorDetails.hideDetails": "إخفاء التفاصيل",
|
||||
"mcpInstall.errorDetails.originalError": "الخطأ الأصلي",
|
||||
"mcpInstall.errorDetails.showDetails": "عرض التفاصيل",
|
||||
"mcpInstall.errorTypes.AUTHORIZATION_ERROR": "خطأ في التفويض",
|
||||
"mcpInstall.errorTypes.AUTHORIZATION_ERROR": "خطأ في التحقق من التفويض",
|
||||
"mcpInstall.errorTypes.CONNECTION_FAILED": "فشل الاتصال",
|
||||
"mcpInstall.errorTypes.INITIALIZATION_TIMEOUT": "انتهت مهلة التهيئة",
|
||||
"mcpInstall.errorTypes.PROCESS_SPAWN_ERROR": "فشل بدء العملية",
|
||||
"mcpInstall.errorTypes.UNKNOWN_ERROR": "خطأ غير معروف",
|
||||
"mcpInstall.errorTypes.VALIDATION_ERROR": "فشل التحقق",
|
||||
"mcpInstall.installError": "فشل تثبيت MCP: {{detail}}",
|
||||
"mcpInstall.installMethods.manual": "يدوي:",
|
||||
"mcpInstall.installMethods.recommended": "موصى به:",
|
||||
"mcpInstall.recheckDependencies": "إعادة التحقق",
|
||||
"mcpInstall.skipDependencies": "تخطي",
|
||||
"pluginList": "المهارات",
|
||||
"mcpInstall.errorTypes.VALIDATION_ERROR": "فشل التحقق من المعلمات",
|
||||
"mcpInstall.installError": "فشل تثبيت إضافة MCP، السبب: {{detail}}",
|
||||
"mcpInstall.installMethods.manual": "تثبيت يدوي:",
|
||||
"mcpInstall.installMethods.recommended": "طريقة التثبيت الموصى بها:",
|
||||
"mcpInstall.recheckDependencies": "إعادة فحص",
|
||||
"mcpInstall.skipDependencies": "تخطي الفحص",
|
||||
"pluginList": "قائمة الإضافات",
|
||||
"protocolInstall.actions.install": "تثبيت",
|
||||
"protocolInstall.actions.installAnyway": "تثبيت على أي حال",
|
||||
"protocolInstall.actions.installed": "مثبت",
|
||||
"protocolInstall.config.addEnv": "إضافة متغير بيئة",
|
||||
"protocolInstall.config.addHeaders": "إضافة ترويسة",
|
||||
"protocolInstall.config.addHeaders": "إضافة رؤوس الطلب",
|
||||
"protocolInstall.config.args": "المعلمات",
|
||||
"protocolInstall.config.command": "الأمر",
|
||||
"protocolInstall.config.env": "البيئة",
|
||||
"protocolInstall.config.headers": "الترويسات",
|
||||
"protocolInstall.config.title": "الإعداد",
|
||||
"protocolInstall.config.env": "متغيرات البيئة",
|
||||
"protocolInstall.config.headers": "رؤوس الطلب",
|
||||
"protocolInstall.config.title": "معلومات التكوين",
|
||||
"protocolInstall.config.type.http": "النوع: HTTP",
|
||||
"protocolInstall.config.type.label": "النوع",
|
||||
"protocolInstall.config.type.stdio": "النوع: Stdio",
|
||||
"protocolInstall.config.url": "رابط الخادم",
|
||||
"protocolInstall.custom.badge": "مهارة مخصصة",
|
||||
"protocolInstall.custom.security.description": "مهارة غير رسمية، قد تحتوي على مخاطر أمنية. تحقق من المصدر قبل التثبيت.",
|
||||
"protocolInstall.custom.security.title": "الأمان",
|
||||
"protocolInstall.custom.title": "تثبيت مهارة مخصصة",
|
||||
"protocolInstall.config.url": "عنوان الخدمة",
|
||||
"protocolInstall.custom.badge": "إضافة مخصصة",
|
||||
"protocolInstall.custom.security.description": "هذه الإضافة لم يتم التحقق منها رسميًا، قد تحمل مخاطر أمنية! يرجى التأكد من ثقتك بمصدر الإضافة.",
|
||||
"protocolInstall.custom.security.title": "⚠️ تحذير أمني",
|
||||
"protocolInstall.custom.title": "تثبيت إضافة مخصصة",
|
||||
"protocolInstall.install.title": "معلومات التثبيت",
|
||||
"protocolInstall.marketplace.title": "تثبيت مهارة من طرف ثالث",
|
||||
"protocolInstall.marketplace.trustedBy": "بواسطة {{name}}",
|
||||
"protocolInstall.marketplace.unverified.title": "مهارة غير موثقة من طرف ثالث",
|
||||
"protocolInstall.marketplace.unverified.warning": "تحقق من المصدر قبل تثبيت هذه المهارة المجتمعية.",
|
||||
"protocolInstall.marketplace.verified": "موثقة",
|
||||
"protocolInstall.marketplace.title": "تثبيت إضافات الطرف الثالث",
|
||||
"protocolInstall.marketplace.trustedBy": "مقدم من {{name}}",
|
||||
"protocolInstall.marketplace.unverified.title": "إضافات طرف ثالث غير موثوقة",
|
||||
"protocolInstall.marketplace.unverified.warning": "هذا المكون الإضافي来自 مجتمع طرف ثالث غير موثوق به. يرجى التأكد من أنك تثق في هذا المصدر قبل التثبيت.",
|
||||
"protocolInstall.marketplace.verified": "موثوقة",
|
||||
"protocolInstall.messages.connectionTestFailed": "فشل اختبار الاتصال",
|
||||
"protocolInstall.messages.installError": "فشل التثبيت، حاول مرة أخرى",
|
||||
"protocolInstall.messages.installSuccess": "{{name}} تم تثبيتها. يمكنك تفعيلها الآن أو إعدادها لاحقًا.",
|
||||
"protocolInstall.messages.manifestError": "فشل في جلب معلومات المهارة. تحقق من الشبكة أو حاول لاحقًا.",
|
||||
"protocolInstall.messages.manifestNotFound": "الملف التعريفي غير موجود",
|
||||
"protocolInstall.messages.installError": "فشل تثبيت الإضافة، يرجى المحاولة مجددًا",
|
||||
"protocolInstall.messages.installSuccess": "تم تثبيت الإضافة {{name}} بنجاح!",
|
||||
"protocolInstall.messages.manifestError": "فشل الحصول على تفاصيل الإضافة، يرجى التحقق من الاتصال بالشبكة والمحاولة مجددًا",
|
||||
"protocolInstall.messages.manifestNotFound": "تعذر الحصول على ملف وصف الإضافة",
|
||||
"protocolInstall.meta.author": "المؤلف",
|
||||
"protocolInstall.meta.homepage": "الصفحة الرئيسية",
|
||||
"protocolInstall.meta.identifier": "المعرف",
|
||||
"protocolInstall.meta.source": "المصدر",
|
||||
"protocolInstall.meta.version": "الإصدار",
|
||||
"protocolInstall.official.badge": "مهارة رسمية من LobeHub",
|
||||
"protocolInstall.official.description": "مهارة رسمية من LobeHub، تم التحقق منها وفحصها أمنيًا.",
|
||||
"protocolInstall.official.loadingMessage": "جارٍ تحميل تفاصيل المهارة…",
|
||||
"protocolInstall.official.badge": "إضافة رسمية من LobeHub",
|
||||
"protocolInstall.official.description": "تم تطوير هذه الإضافة وصيانتها رسميًا من قبل LobeHub، وتمت مراجعتها أمنيًا بدقة، يمكن استخدامها بأمان.",
|
||||
"protocolInstall.official.loadingMessage": "جارٍ الحصول على تفاصيل الإضافة...",
|
||||
"protocolInstall.official.loadingTitle": "جارٍ التحميل",
|
||||
"protocolInstall.official.title": "تثبيت مهارة رسمية",
|
||||
"protocolInstall.title": "تثبيت MCP",
|
||||
"protocolInstall.warning": "تحقق من مصدر المهارة. يمكنك تعطيلها أو إزالتها في أي وقت من الإعدادات.",
|
||||
"protocolInstall.official.title": "تثبيت إضافة رسمية",
|
||||
"protocolInstall.title": "تثبيت إضافة MCP",
|
||||
"protocolInstall.warning": "⚠️ يرجى التأكد من ثقتك بمصدر هذه الإضافة، الإضافات الخبيثة قد تضر بأمان نظامك.",
|
||||
"search.config.addKey": "إضافة مفتاح",
|
||||
"search.config.close": "إزالة",
|
||||
"search.config.confirm": "تم، أعد المحاولة",
|
||||
"search.crawPages.crawling": "جارٍ تحديد الروابط",
|
||||
"search.config.close": "حذف",
|
||||
"search.config.confirm": "تم إكمال التكوين وأعيد المحاولة",
|
||||
"search.crawPages.crawling": "جارٍ التعرف على الروابط",
|
||||
"search.crawPages.detail.preview": "معاينة",
|
||||
"search.crawPages.detail.raw": "نص خام",
|
||||
"search.crawPages.detail.tooLong": "تم تقليص النص إلى {{characters}} حرفًا للسياق، وتم حذف الزائد.",
|
||||
"search.crawPages.detail.tooLong": "النص طويل جدًا، يحتفظ سياق المحادثة فقط بأول {{characters}} حرفًا، الجزء الزائد غير مدرج في السياق",
|
||||
"search.crawPages.meta.crawler": "وضع الزحف",
|
||||
"search.crawPages.meta.words": "عدد الأحرف",
|
||||
"search.searchxng.baseURL": "أدخل الرابط",
|
||||
"search.searchxng.description": "أدخل رابط SearchXNG لبدء البحث عبر الويب",
|
||||
"search.searchxng.keyPlaceholder": "أدخل المفتاح",
|
||||
"search.searchxng.title": "إعداد SearchXNG",
|
||||
"search.searchxng.unconfiguredDesc": "اتصل بالمسؤول لإعداد SearchXNG",
|
||||
"search.searchxng.unconfiguredTitle": "SearchXNG غير مُعد",
|
||||
"search.title": "بحث عبر الويب",
|
||||
"setting": "الإعدادات",
|
||||
"settings.capabilities.prompts": "المطالبات",
|
||||
"search.searchxng.baseURL": "يرجى الإدخال",
|
||||
"search.searchxng.description": "يرجى إدخال عنوان SearchXNG للبدء في البحث عبر الإنترنت",
|
||||
"search.searchxng.keyPlaceholder": "يرجى إدخال المفتاح",
|
||||
"search.searchxng.title": "تكوين محرك البحث SearchXNG",
|
||||
"search.searchxng.unconfiguredDesc": "يرجى الاتصال بالمسؤول لإكمال تكوين محرك البحث SearchXNG للبدء في البحث عبر الإنترنت",
|
||||
"search.searchxng.unconfiguredTitle": "لم يتم تكوين محرك البحث SearchXNG بعد",
|
||||
"search.title": "البحث عبر الإنترنت",
|
||||
"setting": "إعدادات الإضافة",
|
||||
"settings.capabilities.prompts": "عبارات التوجيه",
|
||||
"settings.capabilities.resources": "الموارد",
|
||||
"settings.capabilities.title": "المهارات",
|
||||
"settings.capabilities.title": "قدرات الإضافة",
|
||||
"settings.capabilities.tools": "الأدوات",
|
||||
"settings.configuration.title": "الإعداد",
|
||||
"settings.connection.args": "المعلمات",
|
||||
"settings.connection.command": "الأمر",
|
||||
"settings.connection.title": "الاتصال",
|
||||
"settings.connection.type": "النوع",
|
||||
"settings.connection.url": "رابط الخادم",
|
||||
"settings.edit": "تعديل",
|
||||
"settings.envConfigDescription": "يتم تمريرها كمتغيرات بيئة عند بدء خادم MCP",
|
||||
"settings.httpTypeNotice": "MCP من نوع HTTP لا يحتوي على متغيرات بيئة للإعداد",
|
||||
"settings.configuration.title": "تكوين الإضافة",
|
||||
"settings.connection.args": "معلمات التشغيل",
|
||||
"settings.connection.command": "أمر التشغيل",
|
||||
"settings.connection.title": "معلومات الاتصال",
|
||||
"settings.connection.type": "نوع الاتصال",
|
||||
"settings.connection.url": "عنوان الخدمة",
|
||||
"settings.edit": "تحرير",
|
||||
"settings.envConfigDescription": "سيتم تمرير هذه الإعدادات كمتغيرات بيئة عند بدء تشغيل خادم MCP",
|
||||
"settings.httpTypeNotice": "إضافات MCP من نوع HTTP لا تحتاج إلى متغيرات بيئة للتكوين حاليًا",
|
||||
"settings.indexUrl.title": "فهرس المجتمع",
|
||||
"settings.indexUrl.tooltip": "قم بالتعديل عبر متغيرات بيئة النشر",
|
||||
"settings.messages.connectionUpdateFailed": "فشل تحديث الاتصال",
|
||||
"settings.messages.connectionUpdateSuccess": "تم تحديث الاتصال",
|
||||
"settings.indexUrl.tooltip": "لا يدعم التحرير عبر الإنترنت حاليًا، يرجى التكوين عبر متغيرات البيئة عند النشر",
|
||||
"settings.messages.connectionUpdateFailed": "فشل تحديث معلومات الاتصال",
|
||||
"settings.messages.connectionUpdateSuccess": "تم تحديث معلومات الاتصال بنجاح",
|
||||
"settings.messages.envUpdateFailed": "فشل حفظ متغيرات البيئة",
|
||||
"settings.messages.envUpdateSuccess": "تم حفظ متغيرات البيئة",
|
||||
"settings.modalDesc": "قم بإعداد رابط المجتمع لاستخدام مجتمع مهارات مخصص.",
|
||||
"settings.rules.argsRequired": "أدخل المعلمات",
|
||||
"settings.rules.commandRequired": "أدخل الأمر",
|
||||
"settings.rules.urlRequired": "أدخل رابط الخادم",
|
||||
"settings.saveSettings": "حفظ",
|
||||
"settings.title": "إعدادات مجتمع المهارات",
|
||||
"showInPortal": "عرض التفاصيل في مساحة العمل",
|
||||
"store.actions.cancel": "إلغاء",
|
||||
"store.actions.confirmUninstall": "سيؤدي إلغاء التثبيت إلى مسح إعدادات المهارة. هل ترغب في المتابعة؟",
|
||||
"store.actions.detail": "تفاصيل",
|
||||
"settings.messages.envUpdateSuccess": "تم حفظ متغيرات البيئة بنجاح",
|
||||
"settings.modalDesc": "بعد تكوين عنوان مجتمع المكونات الإضافية، يمكنك استخدام مجتمع مكونات إضافية مخصص",
|
||||
"settings.rules.argsRequired": "يرجى إدخال معلمات التشغيل",
|
||||
"settings.rules.commandRequired": "يرجى إدخال أمر التشغيل",
|
||||
"settings.rules.urlRequired": "يرجى إدخال عنوان الخدمة",
|
||||
"settings.saveSettings": "حفظ الإعدادات",
|
||||
"settings.title": "إعداد مجتمع المكونات الإضافية",
|
||||
"showInPortal": "يرجى عرض التفاصيل في مساحة العمل",
|
||||
"store.actions.cancel": "إلغاء التثبيت",
|
||||
"store.actions.confirmUninstall": "سيتم إلغاء تثبيت هذه الإضافة وسيتم حذف إعداداتها، يرجى تأكيد العملية",
|
||||
"store.actions.detail": "التفاصيل",
|
||||
"store.actions.install": "تثبيت",
|
||||
"store.actions.manifest": "تعديل الملف التعريفي",
|
||||
"store.actions.manifest": "تحرير ملف التثبيت",
|
||||
"store.actions.settings": "الإعدادات",
|
||||
"store.actions.uninstall": "إلغاء التثبيت",
|
||||
"store.communityPlugin": "مجتمعي",
|
||||
"store.communityPlugin": "مجتمع الطرف الثالث",
|
||||
"store.customPlugin": "مخصص",
|
||||
"store.empty": "لا توجد مهارات مثبتة",
|
||||
"store.emptySelectHint": "اختر مهارة لعرض التفاصيل",
|
||||
"store.empty": "لا توجد إضافات مثبتة",
|
||||
"store.emptySelectHint": "اختر إضافة لمعاينة التفاصيل",
|
||||
"store.installAllPlugins": "تثبيت الكل",
|
||||
"store.networkError": "فشل في جلب متجر المهارات. تحقق من الشبكة وأعد المحاولة.",
|
||||
"store.placeholder": "ابحث عن مهارات بالاسم أو الكلمة المفتاحية…",
|
||||
"store.releasedAt": "تم الإصدار في {{createdAt}}",
|
||||
"store.tabs.installed": "المثبتة",
|
||||
"store.tabs.mcp": "MCP",
|
||||
"store.tabs.old": "مهارات LobeHub",
|
||||
"store.title": "متجر المهارات",
|
||||
"store.networkError": "فشل الحصول على متجر الإضافات، يرجى التحقق من الاتصال بالشبكة والمحاولة مجددًا",
|
||||
"store.placeholder": "ابحث عن اسم الإضافة أو الوصف أو الكلمات المفتاحية...",
|
||||
"store.releasedAt": "نُشر في {{createdAt}}",
|
||||
"store.tabs.installed": "مثبت",
|
||||
"store.tabs.mcp": "إضافات MCP",
|
||||
"store.tabs.old": "ملحقات LobeHub",
|
||||
"store.title": "متجر الإضافات",
|
||||
"unknownError": "خطأ غير معروف",
|
||||
"unknownPlugin": "مهارة غير معروفة"
|
||||
"unknownPlugin": "إضافة غير معروفة"
|
||||
}
|
||||
|
||||
+12
-15
@@ -1,25 +1,22 @@
|
||||
{
|
||||
"Artifacts": "القطع الأثرية",
|
||||
"FilePreview.tabs.chunk": "جزء",
|
||||
"FilePreview.tabs.file": "ملف",
|
||||
"Plugins": "المهارات",
|
||||
"artifacts.display.code": "الشفرة",
|
||||
"Plugins": "ملحقات",
|
||||
"artifacts.display.code": "رمز",
|
||||
"artifacts.display.preview": "معاينة",
|
||||
"artifacts.svg.copyAsImage": "نسخ كصورة",
|
||||
"artifacts.svg.copyFail": "فشل النسخ: {{error}}. حاول مرة أخرى.",
|
||||
"artifacts.svg.copyFail": "فشل النسخ، سبب الخطأ: {{error}}",
|
||||
"artifacts.svg.copySuccess": "تم نسخ الصورة بنجاح",
|
||||
"artifacts.svg.download.png": "تنزيل كـ PNG",
|
||||
"artifacts.svg.download.svg": "تنزيل كـ SVG",
|
||||
"document.todos.allCompleted": "تم إنجاز جميع المهام",
|
||||
"document.todos.title": "المهام",
|
||||
"emptyArtifactList": "لا توجد قطع أثرية بعد. استخدم المهارات في المحادثة، ثم عد إلى هنا.",
|
||||
"emptyKnowledgeList": "هذه القائمة فارغة.",
|
||||
"files": "الملفات",
|
||||
"artifacts.svg.download.png": "تحميل كـ PNG",
|
||||
"artifacts.svg.download.svg": "تحميل كـ SVG",
|
||||
"emptyArtifactList": "قائمة القطع الأثرية الحالية فارغة، يرجى استخدام الإضافات في الجلسة ومن ثم التحقق مرة أخرى",
|
||||
"emptyKnowledgeList": "قائمة المعرفة الحالية فارغة، يرجى فتح قاعدة المعرفة حسب الحاجة في المحادثة قبل العرض",
|
||||
"files": "ملفات",
|
||||
"messageDetail": "تفاصيل الرسالة",
|
||||
"notebook.confirmDelete": "هل تريد حذف هذه الصفحة؟",
|
||||
"notebook.confirmDelete": "هل أنت متأكد أنك تريد حذف هذا المستند؟",
|
||||
"notebook.delete": "حذف",
|
||||
"notebook.empty": "لا توجد صفحات بعد. ستظهر الصفحات المرتبطة بهذا الموضوع هنا.",
|
||||
"notebook.empty": "لا توجد مستندات حالياً، ستظهر المستندات المرتبطة بالموضوع هنا",
|
||||
"notebook.title": "دفتر الملاحظات",
|
||||
"openInPageEditor": "تحرير في الصفحة",
|
||||
"title": "مساحة العمل"
|
||||
"openInPageEditor": "تحرير في المستند",
|
||||
"title": "نافذة موسعة"
|
||||
}
|
||||
|
||||
+68
-68
@@ -1,70 +1,70 @@
|
||||
{
|
||||
"ai21.description": "تقوم AI21 Labs ببناء نماذج أساسية وأنظمة ذكاء اصطناعي للمؤسسات، مما يسرّع من تطبيق الذكاء الاصطناعي التوليدي في بيئات الإنتاج.",
|
||||
"ai302.description": "302.AI هي منصة ذكاء اصطناعي تعتمد على الدفع حسب الاستخدام، وتقدم مجموعة واسعة من واجهات برمجة التطبيقات (APIs) والتطبيقات الذكية عبر الإنترنت.",
|
||||
"ai360.description": "360 AI هي منصة نماذج وخدمات من شركة 360، تقدم نماذج معالجة اللغة الطبيعية مثل 360GPT2 Pro و360GPT Pro و360GPT Turbo. تجمع هذه النماذج بين المعلمات واسعة النطاق والقدرات متعددة الوسائط لتوليد النصوص، وفهم المعاني، والدردشة، والبرمجة، مع تسعير مرن لتلبية احتياجات متنوعة.",
|
||||
"aihubmix.description": "يوفر AiHubMix الوصول إلى نماذج ذكاء اصطناعي متعددة من خلال واجهة برمجة تطبيقات موحدة.",
|
||||
"akashchat.description": "أكاش هو سوق موارد سحابية غير مركزي يتميز بأسعار تنافسية مقارنة بمزودي الخدمات السحابية التقليديين.",
|
||||
"anthropic.description": "تقوم Anthropic بتطوير نماذج لغوية متقدمة مثل Claude 3.5 Sonnet وClaude 3 Sonnet وClaude 3 Opus وClaude 3 Haiku، وتوازن بين الذكاء والسرعة والتكلفة لتناسب مختلف حالات الاستخدام من المؤسسات إلى الاستجابات السريعة.",
|
||||
"azure.description": "تقدم Azure نماذج ذكاء اصطناعي متقدمة، بما في ذلك سلسلة GPT-3.5 وGPT-4، لمعالجة أنواع بيانات متنوعة ومهام معقدة مع التركيز على الأمان والموثوقية والاستدامة.",
|
||||
"azureai.description": "توفر Azure نماذج ذكاء اصطناعي متقدمة، بما في ذلك سلسلة GPT-3.5 وGPT-4، لمعالجة أنواع بيانات متنوعة ومهام معقدة مع التركيز على الأمان والموثوقية والاستدامة.",
|
||||
"baichuan.description": "تركز Baichuan AI على النماذج الأساسية ذات الأداء القوي في المعرفة الصينية، ومعالجة السياقات الطويلة، والتوليد الإبداعي. تم تحسين نماذجها (Baichuan 4 وBaichuan 3 Turbo وBaichuan 3 Turbo 128k) لسيناريوهات مختلفة وتقدم قيمة عالية.",
|
||||
"bedrock.description": "توفر Amazon Bedrock للمؤسسات نماذج لغوية وبصرية متقدمة، بما في ذلك Anthropic Claude وMeta Llama 3.1، بدءًا من الخيارات الخفيفة إلى عالية الأداء لمهام النصوص والدردشة والصور.",
|
||||
"bfl.description": "مختبر أبحاث رائد في مجال الذكاء الاصطناعي المتقدم، يعمل على بناء البنية التحتية البصرية للمستقبل.",
|
||||
"cerebras.description": "Cerebras هي منصة استدلال تعتمد على نظام CS-3، تركز على تقديم خدمات نماذج لغوية كبيرة بزمن استجابة منخفض جدًا وسرعة عالية لمهام الوقت الحقيقي مثل توليد الأكواد والمهام التفاعلية.",
|
||||
"cloudflare.description": "تشغيل نماذج تعلم الآلة المعتمدة على وحدات معالجة الرسومات (GPU) بدون خوادم عبر شبكة Cloudflare العالمية.",
|
||||
"cohere.description": "تقدم Cohere نماذج متعددة اللغات متطورة، واسترجاعًا متقدمًا، ومساحات عمل ذكاء اصطناعي للمؤسسات الحديثة — كل ذلك ضمن منصة آمنة واحدة.",
|
||||
"cometapi.description": "توفر CometAPI الوصول إلى نماذج متقدمة من OpenAI وAnthropic وGoogle وغيرها، مما يتيح للمستخدمين اختيار النموذج والسعر الأنسب لحالات الاستخدام المختلفة.",
|
||||
"comfyui.description": "محرك سير عمل مفتوح المصدر قوي لتوليد الصور والفيديو والصوت، يدعم نماذج مثل SD وFLUX وQwen وHunyuan وWAN مع تحرير قائم على العقد ونشر خاص.",
|
||||
"deepseek.description": "تركز DeepSeek على أبحاث وتطبيقات الذكاء الاصطناعي؛ تتفوق أحدث نماذجها DeepSeek-V3 على نماذج مفتوحة مثل Qwen2.5-72B وLlama-3.1-405B، وتقترب من أداء النماذج المغلقة الرائدة مثل GPT-4o وClaude-3.5-Sonnet.",
|
||||
"fal.description": "منصة وسائط توليدية مصممة للمطورين.",
|
||||
"fireworksai.description": "توفر Fireworks AI خدمات نماذج لغوية متقدمة مع دعم استدعاء الوظائف والمعالجة متعددة الوسائط. تم تحسين Firefunction V2 (المبني على Llama-3) لاستدعاء الوظائف والدردشة وتنفيذ التعليمات، بينما يدعم FireLLaVA-13B إدخال الصور والنصوص معًا. تشمل النماذج الأخرى Llama وMixtral.",
|
||||
"giteeai.description": "توفر Gitee AI واجهات برمجة تطبيقات بدون خوادم لخدمات استدلال النماذج اللغوية الكبيرة، جاهزة للاستخدام من قبل المطورين.",
|
||||
"github.description": "مع نماذج GitHub، يمكن للمطورين العمل كمهندسي ذكاء اصطناعي باستخدام نماذج رائدة في الصناعة.",
|
||||
"google.description": "عائلة Gemini من Google هي أكثر نماذج الذكاء الاصطناعي تطورًا للأغراض العامة، تم تطويرها بواسطة Google DeepMind للاستخدام متعدد الوسائط عبر النصوص والرموز والصور والصوت والفيديو. يمكن تشغيلها من مراكز البيانات إلى الأجهزة المحمولة بكفاءة عالية وانتشار واسع.",
|
||||
"groq.description": "توفر محركات الاستدلال LPU من Groq أداءً متميزًا في المعايير مع سرعة وكفاءة استثنائية، مما يضع معيارًا عاليًا للاستدلال منخفض الكمون في السحابة.",
|
||||
"higress.description": "Higress هو بوابة API سحابية أصلية تم تطويرها داخل Alibaba لمعالجة تأثير إعادة تحميل Tengine على الاتصالات طويلة الأمد وسد الفجوات في موازنة تحميل gRPC/Dubbo.",
|
||||
"huggingface.description": "توفر واجهة برمجة التطبيقات للاستدلال من Hugging Face طريقة سريعة لاستكشاف آلاف النماذج لمهام متعددة، مع وصول فوري إلى نماذج عالية الأداء لتجارب النماذج وتطوير تعلم الآلة.",
|
||||
"hunyuan.description": "نموذج لغوي كبير من تطوير Tencent يتميز بقدرات قوية في الكتابة باللغة الصينية، والتفكير المنطقي في السياقات المعقدة، وتنفيذ المهام بدقة.",
|
||||
"infiniai.description": "توفر خدمات نماذج لغوية كبيرة عالية الأداء وسهلة الاستخدام وآمنة لمطوري التطبيقات، تغطي كامل دورة العمل من تطوير النموذج إلى نشره في الإنتاج.",
|
||||
"internlm.description": "منظمة مفتوحة المصدر تركز على أبحاث النماذج الكبيرة والأدوات، وتوفر منصة فعالة وسهلة الاستخدام تتيح الوصول إلى أحدث النماذج والخوارزميات.",
|
||||
"jina.description": "تأسست Jina AI في عام 2020، وهي شركة رائدة في مجال البحث الذكي. تشمل تقنياتها نماذج المتجهات، ومعيدو الترتيب، ونماذج لغوية صغيرة لبناء تطبيقات بحث توليدية ومتعددة الوسائط عالية الجودة.",
|
||||
"lmstudio.description": "LM Studio هو تطبيق سطح مكتب لتطوير وتجربة النماذج اللغوية الكبيرة على جهازك.",
|
||||
"minimax.description": "تأسست MiniMax في عام 2021، وتبني نماذج ذكاء اصطناعي متعددة الوسائط للأغراض العامة، بما في ذلك نماذج نصية بمليارات المعلمات، ونماذج صوتية وبصرية، بالإضافة إلى تطبيقات مثل Hailuo AI.",
|
||||
"mistral.description": "تقدم Mistral نماذج متقدمة عامة ومتخصصة وبحثية للتفكير المعقد، والمهام متعددة اللغات، وتوليد الأكواد، مع دعم استدعاء الوظائف للتكامل المخصص.",
|
||||
"modelscope.description": "ModelScope هي منصة نماذج كخدمة من Alibaba Cloud، تقدم مجموعة واسعة من النماذج وخدمات الاستدلال.",
|
||||
"moonshot.description": "تقدم Moonshot، من Moonshot AI (شركة Beijing Moonshot Technology)، نماذج معالجة لغة طبيعية متعددة لحالات استخدام مثل إنشاء المحتوى، والبحث، والتوصيات، والتحليل الطبي، مع دعم قوي للسياقات الطويلة والتوليد المعقد.",
|
||||
"nebius.description": "توفر Nebius بنية تحتية عالية الأداء لمبتكري الذكاء الاصطناعي حول العالم من خلال مجموعات GPU واسعة النطاق ومنصة سحابية متكاملة رأسياً.",
|
||||
"newapi.description": "منصة مفتوحة المصدر لتجميع وتوجيه خدمات الذكاء الاصطناعي المتعددة.",
|
||||
"novita.description": "تقدم Novita AI واجهات برمجة تطبيقات مرنة وموثوقة وفعالة من حيث التكلفة للنماذج اللغوية الكبيرة وتوليد الصور. تدعم نماذج مثل Llama 3 وMistral وتوفر واجهات برمجة تطبيقات قابلة للتوسع وسهلة الاستخدام للشركات الناشئة في مجال الذكاء الاصطناعي التوليدي.",
|
||||
"nvidia.description": "توفر NVIDIA NIM حاويات لخدمات استدلال ذاتية الاستضافة مع تسريع GPU عبر السحابة ومراكز البيانات وأجهزة RTX AI وأجهزة العمل، للنماذج المدربة مسبقًا والمخصصة.",
|
||||
"ollama.description": "تقدم Ollama نماذج لتوليد الأكواد، والرياضيات، والمعالجة متعددة اللغات، والدردشة، مع دعم للنشر المؤسسي والمحلي.",
|
||||
"ollamacloud.description": "توفر Ollama Cloud استدلالًا مدارًا مع وصول فوري إلى مكتبة نماذج Ollama وواجهات برمجة تطبيقات متوافقة مع OpenAI.",
|
||||
"openai.description": "OpenAI هي مختبر أبحاث رائد في مجال الذكاء الاصطناعي، طورت نماذج GPT التي أحدثت تقدمًا كبيرًا في معالجة اللغة الطبيعية، مع أداء قوي وقيمة عالية في البحث والأعمال والابتكار.",
|
||||
"openrouter.description": "يوفر OpenRouter الوصول إلى العديد من النماذج المتقدمة من OpenAI وAnthropic وLLaMA وغيرها، مما يتيح للمستخدمين اختيار النموذج والسعر الأنسب لحالتهم.",
|
||||
"perplexity.description": "تقدم Perplexity نماذج دردشة متقدمة، بما في ذلك إصدارات Llama 3.1، للاستخدام عبر الإنترنت وغير المتصل ولمهام معالجة اللغة الطبيعية المعقدة.",
|
||||
"ppio.description": "توفر PPIO واجهات برمجة تطبيقات موثوقة وفعالة من حيث التكلفة للنماذج المفتوحة، بما في ذلك DeepSeek وLlama وQwen وغيرها من النماذج الرائدة.",
|
||||
"qiniu.description": "توفر Qiniu خدمات استدلال ذكاء اصطناعي في الوقت الحقيقي وعلى دفعات، موثوقة وسهلة الاستخدام وفعالة من حيث التكلفة.",
|
||||
"qwen.description": "Qwen هو نموذج لغوي كبير من Alibaba Cloud يتميز بفهم وتوليد قوي، ويغطي الأسئلة والأجوبة، والكتابة، والتعبير عن الرأي، والبرمجة في مجالات متعددة.",
|
||||
"replicate.description": "تشغل Replicate نماذج صور مفتوحة المصدر مثل FLUX وStable Diffusion عبر واجهة برمجة تطبيقات سحابية بسيطة.",
|
||||
"sambanova.description": "تتيح SambaNova Cloud للمطورين استخدام نماذج مفتوحة المصدر رائدة مع استدلال فائق السرعة.",
|
||||
"search1api.description": "توفر Search1API الوصول إلى نماذج DeepSeek مع إمكانية الاتصال بالويب، بما في ذلك إصدارات قياسية وسريعة بأحجام معلمات متعددة.",
|
||||
"sensenova.description": "تقدم SenseNova خدمات نماذج لغوية كبيرة كاملة المكدس، فعالة وسهلة الاستخدام، مدعومة ببنية SenseTime التحتية.",
|
||||
"siliconcloud.description": "SiliconCloud هي خدمة سحابية للذكاء الاصطناعي التوليدي فعالة من حيث التكلفة، مبنية على نماذج مفتوحة المصدر قوية.",
|
||||
"spark.description": "يوفر iFLYTEK Spark ذكاءً اصطناعيًا متعدد اللغات قويًا عبر مجالات متعددة، مما يمكّن من الابتكار في الأجهزة الذكية والرعاية الصحية والتمويل وغيرها.",
|
||||
"stepfun.description": "تقدم نماذج Stepfun قدرات رائدة في التعدد الوسائطي والتفكير المعقد، مع فهم طويل للسياق وتنظيم بحث مستقل قوي.",
|
||||
"taichu.description": "Taichu هو نموذج متعدد الوسائط من الجيل التالي من CASIA ومعهد ووهان للذكاء الاصطناعي، يدعم الأسئلة والأجوبة متعددة الجولات، والكتابة، وتوليد الصور، وفهم الأبعاد الثلاثية، وتحليل الإشارات بقدرات إدراكية وإبداعية متقدمة.",
|
||||
"tencentcloud.description": "توفر Tencent Cloud محرك معرفة قائم على النماذج اللغوية الكبيرة يقدم إجابات معرفية شاملة للمؤسسات والمطورين، مع خدمات معيارية مثل تحليل المستندات، والتقسيم، والتضمين، وإعادة الصياغة متعددة الجولات لبناء حلول ذكاء اصطناعي مخصصة.",
|
||||
"togetherai.description": "توفر Together AI أداءً رائدًا من خلال نماذج مبتكرة، وتخصيص واسع، وتوسع سريع، ونشر بسيط لتلبية احتياجات المؤسسات.",
|
||||
"upstage.description": "تقوم Upstage ببناء نماذج ذكاء اصطناعي لتلبية احتياجات الأعمال، بما في ذلك Solar LLM وDocument AI، مع واجهات دردشة تدعم استدعاء الوظائف، والترجمة، والتضمين، وحالات الاستخدام المتخصصة.",
|
||||
"v0.description": "v0 هو مساعد برمجة ثنائي يحول الأفكار المكتوبة بلغة طبيعية إلى كود وواجهة مستخدم لمشروعك.",
|
||||
"vercelaigateway.description": "يوفر Vercel AI Gateway واجهة برمجة تطبيقات موحدة لأكثر من 100 نموذج من OpenAI وAnthropic وGoogle وغيرها، مع ميزات الميزانية، ومراقبة الاستخدام، وموازنة التحميل، والتجاوز التلقائي.",
|
||||
"vertexai.description": "عائلة Gemini من Google هي أكثر نماذج الذكاء الاصطناعي تطورًا للأغراض العامة، تم تطويرها بواسطة Google DeepMind للاستخدام متعدد الوسائط عبر النصوص والرموز والصور والصوت والفيديو. يمكن تشغيلها من مراكز البيانات إلى الأجهزة المحمولة، مما يعزز الكفاءة ومرونة النشر.",
|
||||
"vllm.description": "vLLM مكتبة سريعة وسهلة الاستخدام لاستدلال وخدمة النماذج اللغوية الكبيرة.",
|
||||
"volcengine.description": "توفر منصة نماذج ByteDance وصولًا آمنًا وغنيًا بالميزات وفعالًا من حيث التكلفة إلى النماذج، بالإضافة إلى أدوات شاملة للبيانات، والتخصيص، والاستدلال، والتقييم.",
|
||||
"wenxin.description": "منصة متكاملة للمؤسسات لتطوير النماذج الأساسية والتطبيقات الذكية، تقدم أدوات شاملة لسير عمل النماذج التوليدية وتطبيقاتها.",
|
||||
"xai.description": "تقوم xAI ببناء ذكاء اصطناعي لتسريع الاكتشاف العلمي، بهدف تعميق فهم البشرية للكون.",
|
||||
"xinference.description": "Xorbits Inference (Xinference) هي منصة مفتوحة المصدر تسهّل تشغيل ودمج نماذج الذكاء الاصطناعي. تتيح تشغيل النماذج اللغوية الكبيرة، ونماذج التضمين، والنماذج متعددة الوسائط محليًا أو في السحابة لبناء تطبيقات ذكاء اصطناعي قوية.",
|
||||
"zenmux.description": "ZenMux هي منصة تجميع ذكاء اصطناعي موحدة تدعم OpenAI وAnthropic وGoogle VertexAI وغيرها، مع توجيه مرن لتبديل وإدارة النماذج بسهولة.",
|
||||
"zeroone.description": "01.AI تقود ثورة الذكاء الاصطناعي 2.0 المتمحورة حول الإنسان، باستخدام النماذج اللغوية الكبيرة لخلق قيمة اقتصادية واجتماعية وبناء أنظمة بيئية ونماذج أعمال جديدة.",
|
||||
"zhipu.description": "توفر ZhiPu AI منصة مفتوحة للنماذج متعددة الوسائط واللغوية، تغطي معالجة النصوص، وفهم الصور، والمساعدة في البرمجة."
|
||||
"ai21.description": "تقوم AI21 Labs ببناء نماذج أساسية وأنظمة ذكاء اصطناعي للشركات، مما يسرع من تطبيق الذكاء الاصطناعي التوليدي في الإنتاج.",
|
||||
"ai302.description": "302.AI هو منصة تطبيقات ذكاء اصطناعي تعتمد على الدفع حسب الاستخدام، تقدم أكثر واجهات برمجة التطبيقات للتعلم الآلي وتطبيقات الذكاء الاصطناعي عبر الإنترنت شمولاً في السوق",
|
||||
"ai360.description": "AI 360 هي منصة نماذج وخدمات الذكاء الاصطناعي التي أطلقتها شركة 360، تقدم مجموعة متنوعة من نماذج معالجة اللغة الطبيعية المتقدمة، بما في ذلك 360GPT2 Pro و360GPT Pro و360GPT Turbo و360GPT Turbo Responsibility 8K. تجمع هذه النماذج بين المعلمات الكبيرة والقدرات متعددة الوسائط، وتستخدم على نطاق واسع في توليد النصوص، وفهم المعاني، وأنظمة الحوار، وتوليد الشيفرات. من خلال استراتيجيات تسعير مرنة، تلبي AI 360 احتياجات المستخدمين المتنوعة، وتدعم المطورين في التكامل، مما يعزز الابتكار والتطوير في التطبيقات الذكية.",
|
||||
"aihubmix.description": "يوفر AiHubMix الوصول إلى نماذج الذكاء الاصطناعي المتعددة من خلال واجهة برمجة تطبيقات موحدة.",
|
||||
"akashchat.description": "آكاش هو سوق موارد سحابية بدون ترخيص، يتميز بأسعار تنافسية مقارنة بمزودي السحابة التقليديين.",
|
||||
"anthropic.description": "Anthropic هي شركة تركز على أبحاث وتطوير الذكاء الاصطناعي، وتقدم مجموعة من نماذج اللغة المتقدمة، مثل Claude 3.5 Sonnet وClaude 3 Sonnet وClaude 3 Opus وClaude 3 Haiku. تحقق هذه النماذج توازنًا مثاليًا بين الذكاء والسرعة والتكلفة، وتناسب مجموعة متنوعة من سيناريوهات التطبيقات، من أحمال العمل على مستوى المؤسسات إلى الاستجابات السريعة. يعتبر Claude 3.5 Sonnet أحدث نماذجها، وقد أظهر أداءً ممتازًا في العديد من التقييمات مع الحفاظ على نسبة تكلفة فعالة.",
|
||||
"azure.description": "توفر Azure مجموعة متنوعة من نماذج الذكاء الاصطناعي المتقدمة، بما في ذلك GPT-3.5 وأحدث سلسلة GPT-4، تدعم أنواع بيانات متعددة ومهام معقدة، وتلتزم بحلول ذكاء اصطناعي آمنة وموثوقة ومستدامة.",
|
||||
"azureai.description": "توفر Azure مجموعة متنوعة من نماذج الذكاء الاصطناعي المتقدمة، بما في ذلك GPT-3.5 وأحدث سلسلة GPT-4، تدعم أنواع البيانات المتعددة والمهام المعقدة، وتهدف إلى تقديم حلول ذكاء اصطناعي آمنة وموثوقة ومستدامة.",
|
||||
"baichuan.description": "Baichuan Intelligence هي شركة تركز على تطوير نماذج الذكاء الاصطناعي الكبيرة، حيث تظهر نماذجها أداءً ممتازًا في المهام الصينية مثل الموسوعات المعرفية ومعالجة النصوص الطويلة والإبداع. تتفوق على النماذج الرئيسية الأجنبية. كما تتمتع Baichuan Intelligence بقدرات متعددة الوسائط رائدة في الصناعة، وقد أظهرت أداءً ممتازًا في العديد من التقييمات الموثوقة. تشمل نماذجها Baichuan 4 وBaichuan 3 Turbo وBaichuan 3 Turbo 128k، وكل منها مُحسّن لمشاهد تطبيق مختلفة، مما يوفر حلولًا فعالة من حيث التكلفة.",
|
||||
"bedrock.description": "Bedrock هي خدمة تقدمها أمازون AWS، تركز على توفير نماذج لغة ورؤية متقدمة للذكاء الاصطناعي للشركات. تشمل عائلة نماذجها سلسلة Claude من Anthropic وسلسلة Llama 3.1 من Meta، وتغطي مجموعة من الخيارات من النماذج الخفيفة إلى عالية الأداء، وتدعم مهام مثل توليد النصوص، والحوار، ومعالجة الصور، مما يجعلها مناسبة لتطبيقات الشركات بمختلف أحجامها واحتياجاتها.",
|
||||
"bfl.description": "مختبر بحثي رائد في مجال الذكاء الاصطناعي المتقدّم، يبني بنية تحتية بصرية للغد.",
|
||||
"cerebras.description": "Cerebras هو نظام استدلال ذكاء اصطناعي يعتمد على نظام CS-3 المخصص، ويهدف إلى تقديم أسرع خدمات النماذج اللغوية الكبيرة (LLM) في العالم مع استجابة فورية وقدرة معالجة عالية. تم تصميمه خصيصًا للقضاء على التأخير وتسريع سير العمل المعقد للذكاء الاصطناعي مثل توليد الشيفرات في الوقت الحقيقي والمهام التفاعلية.",
|
||||
"cloudflare.description": "تشغيل نماذج التعلم الآلي المدفوعة بوحدات معالجة الرسوميات بدون خادم على شبكة Cloudflare العالمية.",
|
||||
"cohere.description": "تقدم Cohere أحدث نماذج متعددة اللغات، وميزات بحث متقدمة، ومساحة عمل AI مصممة خصيصًا للشركات الحديثة - كل ذلك مدمج في منصة آمنة.",
|
||||
"cometapi.description": "CometAPI هو منصة خدمات توفر واجهات متعددة لنماذج الذكاء الاصطناعي المتقدمة، تدعم OpenAI وAnthropic وGoogle والمزيد، مناسبة لمتطلبات التطوير والتطبيق المتنوعة. يمكن للمستخدمين اختيار النموذج والسعر الأمثل وفقًا لاحتياجاتهم، مما يعزز تجربة الذكاء الاصطناعي.",
|
||||
"comfyui.description": "محرك سير عمل قوي ومفتوح المصدر لتوليد الصور والفيديو والصوت، يدعم نماذج متقدمة مثل SD وFLUX وQwen وHunyuan وWAN، ويوفر إمكانيات تحرير سير العمل عبر العقد والنشر الخاص.",
|
||||
"deepseek.description": "DeepSeek هي شركة تركز على أبحاث وتطبيقات تقنيات الذكاء الاصطناعي، حيث يجمع نموذجها الأحدث DeepSeek-V2.5 بين قدرات الحوار العامة ومعالجة الشيفرات، وقد حقق تحسينات ملحوظة في محاذاة تفضيلات البشر، ومهام الكتابة، واتباع التعليمات.",
|
||||
"fal.description": "منصة وسائط توليدية موجهة للمطورين",
|
||||
"fireworksai.description": "Fireworks AI هي شركة رائدة في تقديم خدمات نماذج اللغة المتقدمة، تركز على استدعاء الوظائف والمعالجة متعددة الوسائط. نموذجها الأحدث Firefunction V2 مبني على Llama-3، مُحسّن لاستدعاء الوظائف، والحوار، واتباع التعليمات. يدعم نموذج اللغة البصرية FireLLaVA-13B إدخال الصور والنصوص المختلطة. تشمل النماذج البارزة الأخرى سلسلة Llama وسلسلة Mixtral، مما يوفر دعمًا فعالًا لاتباع التعليمات وتوليدها بلغات متعددة.",
|
||||
"giteeai.description": "خادم واجهات برمجة التطبيقات gitee منظمة العفو الدولية يوفر نموذج كبير المنطق API خدمة منظمة العفو الدولية للمطورين .",
|
||||
"github.description": "مع نماذج GitHub، يمكن للمطورين أن يصبحوا مهندسي ذكاء اصطناعي ويبنون باستخدام نماذج الذكاء الاصطناعي الرائدة في الصناعة.",
|
||||
"google.description": "سلسلة Gemini من Google هي نماذج الذكاء الاصطناعي الأكثر تقدمًا وشمولية، تم تطويرها بواسطة Google DeepMind، مصممة خصيصًا لتكون متعددة الوسائط، تدعم الفهم والمعالجة السلسة للنصوص، والشيفرات، والصور، والصوت، والفيديو. تناسب مجموعة متنوعة من البيئات، من مراكز البيانات إلى الأجهزة المحمولة، مما يعزز بشكل كبير كفاءة نماذج الذكاء الاصطناعي وانتشار استخدامها.",
|
||||
"groq.description": "يتميز محرك الاستدلال LPU من Groq بأداء ممتاز في أحدث اختبارات المعايير لنماذج اللغة الكبيرة المستقلة (LLM)، حيث أعاد تعريف معايير حلول الذكاء الاصطناعي بسرعته وكفاءته المذهلة. Groq يمثل سرعة استدلال فورية، ويظهر أداءً جيدًا في النشر القائم على السحابة.",
|
||||
"higress.description": "Higress هو بوابة API سحابية الأصل، تم تطويرها داخل علي بابا لحل مشاكل إعادة تحميل Tengine التي تؤثر سلبًا على الأعمال ذات الاتصالات الطويلة، بالإضافة إلى نقص قدرات توازن الحمل لـ gRPC/Dubbo.",
|
||||
"huggingface.description": "تقدم واجهة برمجة التطبيقات الخاصة بـ HuggingFace طريقة سريعة ومجانية لاستكشاف الآلاف من النماذج لمجموعة متنوعة من المهام. سواء كنت تقوم بتصميم نموذج أولي لتطبيق جديد أو تحاول استكشاف إمكانيات التعلم الآلي، فإن هذه الواجهة تتيح لك الوصول الفوري إلى نماذج عالية الأداء في مجالات متعددة.",
|
||||
"hunyuan.description": "نموذج لغة متقدم تم تطويره بواسطة Tencent، يتمتع بقدرة قوية على الإبداع باللغة الصينية، وقدرة على الاستدلال المنطقي في سياقات معقدة، بالإضافة إلى قدرة موثوقة على تنفيذ المهام.",
|
||||
"infiniai.description": "يقدم خدمات نماذج كبيرة ذات أداء عالٍ وسهولة الاستخدام وأمان موثوق به للمطورين، تغطي كامل العملية من تطوير النماذج الكبيرة إلى نشرها كخدمات.",
|
||||
"internlm.description": "منظمة مفتوحة المصدر مكرسة لأبحاث وتطوير أدوات النماذج الكبيرة. توفر منصة مفتوحة المصدر فعالة وسهلة الاستخدام لجميع مطوري الذكاء الاصطناعي، مما يجعل أحدث تقنيات النماذج الكبيرة والخوارزميات في متناول اليد.",
|
||||
"jina.description": "تأسست Jina AI في عام 2020، وهي شركة رائدة في مجال الذكاء الاصطناعي للبحث. تحتوي منصتنا الأساسية للبحث على نماذج متجهة، ومعيدي ترتيب، ونماذج لغوية صغيرة، لمساعدة الشركات في بناء تطبيقات بحث موثوقة وعالية الجودة تعتمد على الذكاء الاصطناعي التوليدي ومتعددة الوسائط.",
|
||||
"lmstudio.description": "LM Studio هو تطبيق سطح مكتب لتطوير وتجربة نماذج اللغة الكبيرة (LLMs) على جهاز الكمبيوتر الخاص بك.",
|
||||
"minimax.description": "MiniMax هي شركة تكنولوجيا الذكاء الاصطناعي العامة التي تأسست في عام 2021، تكرس جهودها للتعاون مع المستخدمين في إنشاء الذكاء. طورت MiniMax نماذج كبيرة عامة من أوضاع مختلفة، بما في ذلك نموذج نصي MoE الذي يحتوي على تريليونات من المعلمات، ونموذج صوتي، ونموذج صور. وقد أطلقت تطبيقات مثل Conch AI.",
|
||||
"mistral.description": "تقدم Mistral نماذج متقدمة عامة ومتخصصة وبحثية، تستخدم على نطاق واسع في الاستدلال المعقد، والمهام متعددة اللغات، وتوليد الشيفرات، من خلال واجهة استدعاء الوظائف، يمكن للمستخدمين دمج وظائف مخصصة لتحقيق تطبيقات محددة.",
|
||||
"modelscope.description": "ModelScope هو منصة نموذج كخدمة أطلقتها علي بابا كلاود، تقدم مجموعة واسعة من نماذج الذكاء الاصطناعي وخدمات الاستدلال.",
|
||||
"moonshot.description": "Moonshot هي منصة مفتوحة أطلقتها شركة Beijing Dark Side Technology Co.، Ltd، تقدم مجموعة متنوعة من نماذج معالجة اللغة الطبيعية، وتغطي مجالات واسعة، بما في ذلك ولكن لا تقتصر على إنشاء المحتوى، والبحث الأكاديمي، والتوصيات الذكية، والتشخيص الطبي، وتدعم معالجة النصوص الطويلة والمهام المعقدة.",
|
||||
"nebius.description": "نيبيوس توفر بنية تحتية عالية الأداء للمبتكرين في مجال الذكاء الاصطناعي حول العالم من خلال بناء مجموعات ضخمة من وحدات معالجة الرسومات ومنصة سحابية متكاملة رأسياً.",
|
||||
"newapi.description": "منصة مفتوحة المصدر لتجميع وتحويل خدمات الذكاء الاصطناعي المتعددة بشكل موحد",
|
||||
"novita.description": "Novita AI هي منصة تقدم خدمات API لمجموعة متنوعة من نماذج اللغة الكبيرة وتوليد الصور بالذكاء الاصطناعي، مرنة وموثوقة وفعالة من حيث التكلفة. تدعم أحدث النماذج مفتوحة المصدر مثل Llama3 وMistral، وتوفر حلول API شاملة وسهلة الاستخدام وقابلة للتوسع تلقائيًا لتطوير تطبيقات الذكاء الاصطناعي، مما يجعلها مناسبة لنمو الشركات الناشئة في مجال الذكاء الاصطناعي.",
|
||||
"nvidia.description": "تقدم NVIDIA NIM™ حاويات يمكن استخدامها لاستضافة خدمات استدلال معززة بواسطة GPU، تدعم نشر نماذج الذكاء الاصطناعي المدربة مسبقًا والمخصصة على السحابة ومراكز البيانات وأجهزة الكمبيوتر الشخصية RTX™ ومحطات العمل.",
|
||||
"ollama.description": "تغطي نماذج Ollama مجموعة واسعة من مجالات توليد الشيفرة، والعمليات الرياضية، ومعالجة اللغات المتعددة، والتفاعل الحواري، وتدعم احتياجات النشر على مستوى المؤسسات والتخصيص المحلي.",
|
||||
"ollamacloud.description": "توفر Ollama Cloud خدمة استدلال مُدارة رسميًا، تتيح الوصول الفوري إلى مكتبة نماذج Ollama، وتدعم واجهة متوافقة مع OpenAI.",
|
||||
"openai.description": "OpenAI هي مؤسسة رائدة عالميًا في أبحاث الذكاء الاصطناعي، حيث دفعت النماذج التي طورتها مثل سلسلة GPT حدود معالجة اللغة الطبيعية. تلتزم OpenAI بتغيير العديد من الصناعات من خلال حلول الذكاء الاصطناعي المبتكرة والفعالة. تتمتع منتجاتهم بأداء ملحوظ وفعالية من حيث التكلفة، وتستخدم على نطاق واسع في البحث والتجارة والتطبيقات الابتكارية.",
|
||||
"openrouter.description": "OpenRouter هي منصة خدمة تقدم واجهات لمجموعة متنوعة من النماذج الكبيرة المتقدمة، تدعم OpenAI وAnthropic وLLaMA وغيرها، مما يجعلها مناسبة لاحتياجات التطوير والتطبيق المتنوعة. يمكن للمستخدمين اختيار النموذج والسعر الأمثل وفقًا لاحتياجاتهم، مما يعزز تجربة الذكاء الاصطناعي.",
|
||||
"perplexity.description": "Perplexity هي شركة رائدة في تقديم نماذج توليد الحوار، تقدم مجموعة من نماذج Llama 3.1 المتقدمة، تدعم التطبيقات عبر الإنترنت وغير المتصلة، وتناسب بشكل خاص مهام معالجة اللغة الطبيعية المعقدة.",
|
||||
"ppio.description": "تقدم PPIO بايو السحابية خدمات واجهة برمجة التطبيقات لنماذج مفتوحة المصدر مستقرة وذات تكلفة فعالة، تدعم جميع سلسلة DeepSeek، وLlama، وQwen، وغيرها من النماذج الكبيرة الرائدة في الصناعة.",
|
||||
"qiniu.description": "كشركة رائدة في خدمات السحابة، تقدم Qiniu خدمات استدلال ذكاء اصطناعي في الوقت الفعلي ومجموعة كبيرة بتكلفة فعالة وموثوقة، سهلة الاستخدام.",
|
||||
"qwen.description": "Qwen هو نموذج لغة ضخم تم تطويره ذاتيًا بواسطة Alibaba Cloud، يتمتع بقدرات قوية في فهم وتوليد اللغة الطبيعية. يمكنه الإجابة على مجموعة متنوعة من الأسئلة، وكتابة المحتوى، والتعبير عن الآراء، وكتابة الشيفرات، ويؤدي دورًا في مجالات متعددة.",
|
||||
"replicate.description": "Replicate تُشغّل نماذج الصور مفتوحة المصدر مثل FLUX وStable Diffusion من خلال واجهة برمجة تطبيقات سحابية بسيطة.",
|
||||
"sambanova.description": "تتيح لك سحابة SambaNova استخدام أفضل النماذج مفتوحة المصدر بسهولة، والاستمتاع بأسرع سرعة استدلال.",
|
||||
"search1api.description": "يوفر Search1API الوصول إلى سلسلة نماذج DeepSeek التي يمكن الاتصال بها حسب الحاجة، بما في ذلك النسخة القياسية والنسخة السريعة، مع دعم لاختيار نماذج بمقاييس معلمات متعددة.",
|
||||
"sensenova.description": "تقدم شركة SenseTime خدمات نماذج كبيرة شاملة وسهلة الاستخدام، مدعومة بقوة من البنية التحتية الكبيرة لشركة SenseTime.",
|
||||
"siliconcloud.description": "تسعى SiliconFlow إلى تسريع الذكاء الاصطناعي العام (AGI) لفائدة البشرية، من خلال تحسين كفاءة الذكاء الاصطناعي على نطاق واسع باستخدام حزمة GenAI سهلة الاستخدام وذات التكلفة المنخفضة.",
|
||||
"spark.description": "تقدم شركة iFlytek نموذج Spark الكبير، الذي يوفر قدرات ذكاء اصطناعي قوية عبر مجالات متعددة ولغات متعددة، باستخدام تقنيات معالجة اللغة الطبيعية المتقدمة، لبناء تطبيقات مبتكرة مناسبة للأجهزة الذكية، والرعاية الصحية الذكية، والتمويل الذكي، وغيرها من السيناريوهات الرأسية.",
|
||||
"stepfun.description": "نموذج StepFun الكبير يتمتع بقدرات متعددة الوسائط واستدلال معقد رائدة في الصناعة، ويدعم فهم النصوص الطويلة جدًا وميزات قوية لمحرك البحث الذاتي.",
|
||||
"taichu.description": "أطلقت الأكاديمية الصينية للعلوم ومعهد ووهان للذكاء الاصطناعي نموذجًا جديدًا متعدد الوسائط، يدعم أسئلة وأجوبة متعددة الجولات، وإنشاء النصوص، وتوليد الصور، وفهم 3D، وتحليل الإشارات، ويغطي مجموعة شاملة من مهام الأسئلة والأجوبة، مع قدرات أقوى في الإدراك والفهم والإبداع، مما يوفر تجربة تفاعلية جديدة.",
|
||||
"tencentcloud.description": "قدرة المحرك المعرفي الذري (LLM Knowledge Engine Atomic Power) هي قدرة كاملة للإجابة على الأسئلة مبنية على تطوير المحرك المعرفي، موجهة نحو الشركات والمطورين، وتوفر القدرة على تجميع وتطوير تطبيقات النماذج بشكل مرن. يمكنك من خلال مجموعة من القدرات الذرية تجميع خدمة النموذج الخاصة بك، واستدعاء خدمات تحليل الوثائق، والتقسيم، والتضمين، وإعادة الكتابة متعددة الجولات، لتخصيص أعمال الذكاء الاصطناعي الخاصة بالشركة.",
|
||||
"togetherai.description": "تسعى Together AI لتحقيق أداء رائد من خلال نماذج الذكاء الاصطناعي المبتكرة، وتقدم مجموعة واسعة من القدرات المخصصة، بما في ذلك دعم التوسع السريع وعمليات النشر البديهية، لتلبية احتياجات الشركات المتنوعة.",
|
||||
"upstage.description": "تتخصص Upstage في تطوير نماذج الذكاء الاصطناعي لتلبية احتياجات الأعمال المتنوعة، بما في ذلك Solar LLM وDocument AI، بهدف تحقيق الذكاء الاصطناعي العام (AGI) القائم على العمل. من خلال واجهة Chat API، يمكن إنشاء وكلاء حوار بسيطين، وتدعم استدعاء الوظائف، والترجمة، والتضمين، وتطبيقات المجالات المحددة.",
|
||||
"v0.description": "v0 هو مساعد برمجة تعاوني، كل ما عليك هو وصف أفكارك بلغة طبيعية، وسيقوم بإنشاء الشيفرة وواجهة المستخدم (UI) لمشروعك.",
|
||||
"vercelaigateway.description": "بوابة Vercel AI توفر واجهة برمجة تطبيقات موحدة للوصول إلى أكثر من 100 نموذج، من خلال نقطة نهاية واحدة يمكن استخدامها مع نماذج مقدمي خدمات مثل OpenAI وAnthropic وGoogle وغيرها. تدعم إعداد الميزانية، مراقبة الاستخدام، موازنة تحميل الطلبات والتبديل التلقائي عند الفشل.",
|
||||
"vertexai.description": "سلسلة جيميني من جوجل هي نماذج الذكاء الاصطناعي الأكثر تقدمًا وعمومية، تم تطويرها بواسطة جوجل ديب مايند، مصممة خصيصًا لتكون متعددة الوسائط، تدعم الفهم والمعالجة السلسة للنصوص، الأكواد، الصور، الصوتيات، والفيديو. تناسب مجموعة متنوعة من البيئات، من مراكز البيانات إلى الأجهزة المحمولة، مما يعزز بشكل كبير كفاءة نماذج الذكاء الاصطناعي وتطبيقاتها الواسعة.",
|
||||
"vllm.description": "vLLM هو مكتبة سريعة وسهلة الاستخدام لاستدلال LLM والخدمات.",
|
||||
"volcengine.description": "منصة تطوير خدمات النماذج الكبيرة التي أطلقتها بايت دانس، تقدم خدمات استدعاء نماذج غنية بالوظائف وآمنة وتنافسية من حيث الأسعار، كما توفر بيانات النماذج، والتعديل الدقيق، والاستدلال، والتقييم، وغيرها من الوظائف الشاملة، لضمان تطوير تطبيقات الذكاء الاصطناعي الخاصة بك بشكل كامل.",
|
||||
"wenxin.description": "منصة تطوير وخدمات النماذج الكبيرة والتطبيقات الأصلية للذكاء الاصطناعي على مستوى المؤسسات، تقدم مجموعة شاملة وسهلة الاستخدام من أدوات تطوير النماذج الذكية التوليدية وأدوات تطوير التطبيقات على مدار العملية بأكملها.",
|
||||
"xai.description": "xAI هي شركة تكرّس جهودها لبناء الذكاء الاصطناعي لتسريع الاكتشافات العلمية البشرية. مهمتنا هي تعزيز فهمنا المشترك للكون.",
|
||||
"xinference.description": "Xorbits Inference (Xinference) هو منصة مفتوحة المصدر مصممة لتبسيط تشغيل ودمج نماذج الذكاء الاصطناعي المتنوعة. باستخدام Xinference، يمكنك تشغيل الاستدلال على نماذج LLM مفتوحة المصدر، ونماذج التضمين، والنماذج متعددة الوسائط سواء في السحابة أو في البيئات المحلية، وإنشاء تطبيقات ذكاء اصطناعي قوية.",
|
||||
"zenmux.description": "ZenMux هو منصة موحدة لتجميع خدمات الذكاء الاصطناعي، تدعم العديد من واجهات خدمات الذكاء الاصطناعي الرائدة مثل OpenAI وAnthropic وGoogle VertexAI. توفر قدرة توجيه مرنة تتيح لك التبديل وإدارة نماذج الذكاء الاصطناعي المختلفة بسهولة.",
|
||||
"zeroone.description": "01.AI تركز على تقنيات الذكاء الاصطناعي في عصر الذكاء الاصطناعي 2.0، وتعزز الابتكار والتطبيقات \"الإنسان + الذكاء الاصطناعي\"، باستخدام نماذج قوية وتقنيات ذكاء اصطناعي متقدمة لتعزيز إنتاجية البشر وتحقيق تمكين التكنولوجيا.",
|
||||
"zhipu.description": "تقدم Zhipu AI منصة مفتوحة للنماذج متعددة الوسائط ونماذج اللغة، تدعم مجموعة واسعة من سيناريوهات تطبيقات الذكاء الاصطناعي، بما في ذلك معالجة النصوص، وفهم الصور، والمساعدة في البرمجة."
|
||||
}
|
||||
|
||||
+18
-18
@@ -1,42 +1,42 @@
|
||||
{
|
||||
"addDataset.confirm": "إنشاء",
|
||||
"addDataset.confirm": "إنشاء جديد",
|
||||
"addDataset.description.placeholder": "وصف مجموعة البيانات (اختياري)",
|
||||
"addDataset.name.placeholder": "اسم مجموعة البيانات",
|
||||
"addDataset.name.required": "يرجى إدخال اسم مجموعة البيانات",
|
||||
"addDataset.title": "إضافة مجموعة بيانات",
|
||||
"dataset.addNewButton": "إنشاء مجموعة بيانات",
|
||||
"dataset.emptyGuide": "لا توجد مجموعات بيانات حالياً. يرجى إنشاء مجموعة بيانات.",
|
||||
"dataset.list.table.actions.importData": "استيراد بيانات",
|
||||
"dataset.emptyGuide": "مجموعة البيانات الحالية فارغة، يرجى إنشاء مجموعة بيانات.",
|
||||
"dataset.list.table.actions.importData": "استيراد البيانات",
|
||||
"dataset.list.table.columns.actions": "الإجراءات",
|
||||
"dataset.list.table.columns.ideal.title": "الإجابة المتوقعة",
|
||||
"dataset.list.table.columns.ideal.title": "الإجابة المثالية",
|
||||
"dataset.list.table.columns.question.title": "السؤال",
|
||||
"dataset.list.table.columns.referenceFiles.title": "الملفات المرجعية",
|
||||
"dataset.list.table.notSelected": "يرجى اختيار مجموعة بيانات من القائمة على اليسار",
|
||||
"dataset.list.table.columns.referenceFiles.title": "ملفات مرجعية",
|
||||
"dataset.list.table.notSelected": "يرجى اختيار مجموعة بيانات من اليسار",
|
||||
"dataset.list.table.title": "تفاصيل مجموعة البيانات",
|
||||
"dataset.list.title": "مجموعة البيانات",
|
||||
"evaluation.addEvaluation.confirm": "إنشاء",
|
||||
"evaluation.addEvaluation.datasetId.placeholder": "يرجى اختيار مجموعة البيانات للتقييم",
|
||||
"evaluation.addEvaluation.datasetId.required": "يرجى اختيار مجموعة بيانات للتقييم",
|
||||
"evaluation.addEvaluation.confirm": "إنشاء جديد",
|
||||
"evaluation.addEvaluation.datasetId.placeholder": "يرجى اختيار مجموعة بيانات التقييم الخاصة بك",
|
||||
"evaluation.addEvaluation.datasetId.required": "يرجى اختيار مجموعة بيانات التقييم",
|
||||
"evaluation.addEvaluation.description.placeholder": "وصف مهمة التقييم (اختياري)",
|
||||
"evaluation.addEvaluation.name.placeholder": "اسم مهمة التقييم",
|
||||
"evaluation.addEvaluation.name.required": "يرجى إدخال اسم مهمة التقييم",
|
||||
"evaluation.addEvaluation.title": "إضافة مهمة تقييم",
|
||||
"evaluation.addNewButton": "إنشاء تقييم",
|
||||
"evaluation.emptyGuide": "لا توجد مهام تقييم حالياً. ابدأ بإنشاء تقييم.",
|
||||
"evaluation.table.columns.actions.checkStatus": "التحقق من الحالة",
|
||||
"evaluation.table.columns.actions.confirmDelete": "هل أنت متأكد أنك تريد حذف هذا التقييم؟",
|
||||
"evaluation.table.columns.actions.confirmRun": "هل أنت متأكد أنك تريد بدء التشغيل؟ سيتم تنفيذ مهمة التقييم بشكل غير متزامن في الخلفية، ولن يؤثر إغلاق الصفحة على تنفيذ المهمة.",
|
||||
"evaluation.table.columns.actions.downloadRecords": "تنزيل التقييم",
|
||||
"evaluation.emptyGuide": "مهمة التقييم الحالية فارغة، ابدأ بإنشاء تقييم.",
|
||||
"evaluation.table.columns.actions.checkStatus": "تحقق من الحالة",
|
||||
"evaluation.table.columns.actions.confirmDelete": "هل تريد حذف هذه المهمة من التقييم؟",
|
||||
"evaluation.table.columns.actions.confirmRun": "هل تريد بدء التشغيل؟ بعد بدء التشغيل، سيتم تنفيذ مهمة التقييم في الخلفية بشكل غير متزامن، وإغلاق الصفحة لن يؤثر على تنفيذ المهمة غير المتزامنة.",
|
||||
"evaluation.table.columns.actions.downloadRecords": "تنزيل السجلات",
|
||||
"evaluation.table.columns.actions.retry": "إعادة المحاولة",
|
||||
"evaluation.table.columns.actions.run": "تشغيل",
|
||||
"evaluation.table.columns.actions.title": "الإجراءات",
|
||||
"evaluation.table.columns.datasetId.title": "مجموعة البيانات",
|
||||
"evaluation.table.columns.name.title": "اسم مهمة التقييم",
|
||||
"evaluation.table.columns.records.title": "عدد سجلات التقييم",
|
||||
"evaluation.table.columns.referenceFiles.title": "الملفات المرجعية",
|
||||
"evaluation.table.columns.status.error": "خطأ في التنفيذ",
|
||||
"evaluation.table.columns.status.pending": "قيد الانتظار",
|
||||
"evaluation.table.columns.status.processing": "قيد التنفيذ",
|
||||
"evaluation.table.columns.referenceFiles.title": "ملفات مرجعية",
|
||||
"evaluation.table.columns.status.error": "حدث خطأ أثناء التنفيذ",
|
||||
"evaluation.table.columns.status.pending": "في انتظار التشغيل",
|
||||
"evaluation.table.columns.status.processing": "جارٍ التشغيل",
|
||||
"evaluation.table.columns.status.success": "تم التنفيذ بنجاح",
|
||||
"evaluation.table.columns.status.title": "الحالة",
|
||||
"evaluation.table.title": "قائمة مهام التقييم"
|
||||
|
||||
+355
-355
@@ -1,539 +1,539 @@
|
||||
{
|
||||
"_cloud.officialProvider": "خدمة النماذج الرسمية من {{name}}",
|
||||
"about.title": "حول",
|
||||
"advancedSettings": "الإعدادات المتقدمة",
|
||||
"agentInfoDescription.basic.avatar": "الصورة الرمزية",
|
||||
"agentInfoDescription.basic.description": "الوصف",
|
||||
"agentInfoDescription.basic.name": "الاسم",
|
||||
"agentInfoDescription.basic.tags": "الوسوم",
|
||||
"agentInfoDescription.basic.title": "معلومات الوكيل",
|
||||
"agentInfoDescription.chat.enableHistoryCount": "تمكين عداد سجل الرسائل",
|
||||
"agentInfoDescription.chat.historyCount": "عدد الرسائل في السجل",
|
||||
"agentInfoDescription.basic.title": "معلومات المساعد",
|
||||
"agentInfoDescription.chat.enableHistoryCount": "تمكين عداد الرسائل السابقة",
|
||||
"agentInfoDescription.chat.historyCount": "عدد الرسائل السابقة",
|
||||
"agentInfoDescription.chat.no": "لا",
|
||||
"agentInfoDescription.chat.searchMode": "وضع البحث",
|
||||
"agentInfoDescription.chat.title": "تفضيلات المحادثة",
|
||||
"agentInfoDescription.chat.title": "تفضيلات الدردشة",
|
||||
"agentInfoDescription.chat.yes": "نعم",
|
||||
"agentInfoDescription.model.maxTokens": "الحد الأقصى للرموز",
|
||||
"agentInfoDescription.model.model": "النموذج",
|
||||
"agentInfoDescription.model.provider": "المزود",
|
||||
"agentInfoDescription.model.temperature": "درجة الإبداع",
|
||||
"agentInfoDescription.model.temperature": "درجة الحرارة",
|
||||
"agentInfoDescription.model.title": "إعدادات النموذج",
|
||||
"agentInfoDescription.model.topP": "قيمة Top P",
|
||||
"agentInfoDescription.plugins.count": "إعدادات المهارات ({{count}})",
|
||||
"agentInfoDescription.plugins.empty": "لا توجد مهارات مثبتة بعد",
|
||||
"agentInfoDescription.plugins.title": "المهارات المثبتة",
|
||||
"agentInfoDescription.role.systemRole": "ملف تعريف الوكيل",
|
||||
"agentInfoDescription.role.title": "ملف تعريف الوكيل",
|
||||
"agentInfoDescription.value.unset": "غير محدد",
|
||||
"agentInfoDescription.value.untitled": "وكيل بدون عنوان",
|
||||
"agentTab.chat": "تفضيلات المحادثة",
|
||||
"agentTab.meta": "معلومات الوكيل",
|
||||
"agentInfoDescription.plugins.count": "إعدادات الإضافات ({{count}})",
|
||||
"agentInfoDescription.plugins.empty": "لم يتم تثبيت أي إضافات بعد",
|
||||
"agentInfoDescription.plugins.title": "الإضافات المثبتة",
|
||||
"agentInfoDescription.role.systemRole": "تعليمات النظام",
|
||||
"agentInfoDescription.role.title": "إعدادات الدور",
|
||||
"agentInfoDescription.value.unset": "غير مُعيّن",
|
||||
"agentInfoDescription.value.untitled": "مساعد بدون عنوان",
|
||||
"agentTab.chat": "تفضيلات الدردشة",
|
||||
"agentTab.meta": "معلومات المساعد",
|
||||
"agentTab.modal": "إعدادات النموذج",
|
||||
"agentTab.opening": "إعدادات البداية",
|
||||
"agentTab.plugin": "إعدادات المهارات",
|
||||
"agentTab.prompt": "ملف تعريف الوكيل",
|
||||
"agentTab.tts": "خدمة الصوت",
|
||||
"analytics.telemetry.desc": "ساعدنا في تحسين {{appName}} من خلال بيانات استخدام مجهولة",
|
||||
"analytics.telemetry.title": "إرسال بيانات استخدام مجهولة",
|
||||
"analytics.title": "التحليلات",
|
||||
"agentTab.opening": "إعداد الافتتاح",
|
||||
"agentTab.plugin": "إعدادات الإضافة",
|
||||
"agentTab.prompt": "تعيين الشخصية",
|
||||
"agentTab.tts": "خدمة النص إلى كلام",
|
||||
"analytics.telemetry.desc": "من خلال اختيار إرسال بيانات القياس عن بُعد، يمكنك مساعدتنا في تحسين تجربة المستخدم العامة لـ {{appName}}",
|
||||
"analytics.telemetry.title": "إرسال بيانات الاستخدام المجهولة",
|
||||
"analytics.title": "تحليلات",
|
||||
"checking": "جارٍ التحقق...",
|
||||
"checkingPermissions": "جارٍ التحقق من الأذونات...",
|
||||
"danger.clear.action": "مسح الآن",
|
||||
"danger.clear.confirm": "هل تريد مسح جميع بيانات المحادثة؟ لا يمكن التراجع عن هذا الإجراء.",
|
||||
"danger.clear.desc": "سيتم حذف جميع البيانات، بما في ذلك الوكلاء والملفات والرسائل والمهارات. لن يتم حذف حسابك.",
|
||||
"danger.clear.confirm": "هل تؤكد مسح جميع بيانات المحادثات؟",
|
||||
"danger.clear.desc": "سيتم مسح جميع بيانات الجلسة بما في ذلك المساعد والملفات والرسائل والإضافات",
|
||||
"danger.clear.success": "تم مسح جميع رسائل الجلسة",
|
||||
"danger.clear.title": "مسح البيانات",
|
||||
"danger.reset.action": "إعادة التعيين الآن",
|
||||
"danger.reset.confirm": "هل تريد إعادة تعيين جميع الإعدادات؟",
|
||||
"danger.clear.title": "مسح جميع رسائل الجلسة",
|
||||
"danger.reset.action": "إعادة تعيين الآن",
|
||||
"danger.reset.confirm": "هل تؤكد إعادة تعيين جميع الإعدادات؟",
|
||||
"danger.reset.currentVersion": "الإصدار الحالي",
|
||||
"danger.reset.desc": "استعادة جميع الإعدادات إلى الوضع الافتراضي. لن يتم حذف بياناتك.",
|
||||
"danger.reset.success": "تمت إعادة تعيين جميع الإعدادات",
|
||||
"danger.reset.desc": "إعادة تعيين جميع عناصر الإعدادات إلى القيم الافتراضية",
|
||||
"danger.reset.success": "تمت إعادة ضبط جميع الإعدادات",
|
||||
"danger.reset.title": "إعادة تعيين جميع الإعدادات",
|
||||
"defaultAgent.model.desc": "النموذج الافتراضي المستخدم عند إنشاء وكيل جديد",
|
||||
"defaultAgent.model.title": "النموذج",
|
||||
"defaultAgent.title": "إعدادات الوكيل الافتراضي",
|
||||
"group.aiConfig": "النموذج",
|
||||
"defaultAgent.title": "إعدادات المساعد الافتراضي",
|
||||
"group.aiConfig": "إعدادات الذكاء الاصطناعي",
|
||||
"group.common": "عام",
|
||||
"group.profile": "الحساب",
|
||||
"group.subscription": "الاشتراك",
|
||||
"group.system": "النظام",
|
||||
"groupTab.chat": "المحادثة",
|
||||
"groupTab.chat": "الدردشة",
|
||||
"groupTab.members": "الأعضاء",
|
||||
"groupTab.meta": "معلومات أساسية",
|
||||
"header.desc": "تفضيلات وإعدادات النموذج",
|
||||
"header.global": "الإعدادات العامة",
|
||||
"header.group": "إعدادات المجموعة",
|
||||
"header.groupDesc": "إدارة المجموعة وتفضيلات المحادثة",
|
||||
"groupTab.meta": "المعلومات الأساسية",
|
||||
"header.desc": "إعدادات التفضيلات والنماذج.",
|
||||
"header.global": "إعدادات عامة",
|
||||
"header.group": "إعدادات الفريق",
|
||||
"header.groupDesc": "إدارة المجموعات وتفضيلات الدردشة",
|
||||
"header.session": "إعدادات الجلسة",
|
||||
"header.sessionDesc": "ملف تعريف الوكيل وتفضيلات الجلسة",
|
||||
"header.sessionDesc": "إعداد الشخصية وتفضيلات الجلسة.",
|
||||
"header.sessionWithName": "إعدادات الجلسة · {{name}}",
|
||||
"header.title": "الإعدادات",
|
||||
"hotkey.conflicts": "تعارض مع اختصارات موجودة",
|
||||
"hotkey.errors.CONFLICT": "تعارض في الاختصار: هذا الاختصار مستخدم بالفعل لوظيفة أخرى",
|
||||
"hotkey.errors.INVALID_FORMAT": "تنسيق اختصار غير صالح: يرجى استخدام التنسيق الصحيح (مثل CommandOrControl+E)",
|
||||
"hotkey.errors.INVALID_ID": "معرف اختصار غير صالح",
|
||||
"hotkey.errors.NO_MODIFIER": "يجب أن يحتوي الاختصار على مفتاح معدل (Ctrl، Alt، Shift، إلخ)",
|
||||
"hotkey.errors.SYSTEM_OCCUPIED": "الاختصار مستخدم من قبل النظام أو تطبيق آخر",
|
||||
"header.title": "إعدادات",
|
||||
"hotkey.conflicts": "يتعارض مع اختصارات لوحة المفاتيح الحالية",
|
||||
"hotkey.errors.CONFLICT": "تعارض في اختصار لوحة المفاتيح: هذا الاختصار مستخدم بالفعل من قبل وظيفة أخرى",
|
||||
"hotkey.errors.INVALID_FORMAT": "تنسيق اختصار لوحة المفاتيح غير صالح: يرجى استخدام التنسيق الصحيح (مثل CommandOrControl+E)",
|
||||
"hotkey.errors.INVALID_ID": "معرف اختصار لوحة المفاتيح غير صالح",
|
||||
"hotkey.errors.NO_MODIFIER": "يجب أن يحتوي اختصار لوحة المفاتيح على مفتاح تعديل (Ctrl، Alt، Shift، إلخ)",
|
||||
"hotkey.errors.SYSTEM_OCCUPIED": "اختصار لوحة المفاتيح مستخدم من قبل النظام أو تطبيقات أخرى",
|
||||
"hotkey.errors.UNKNOWN": "فشل التحديث: خطأ غير معروف",
|
||||
"hotkey.group.conversation": "المحادثة",
|
||||
"hotkey.group.desktop": "سطح المكتب",
|
||||
"hotkey.group.essential": "أساسي",
|
||||
"hotkey.invalidCombination": "يجب أن يحتوي الاختصار على مفتاح معدل واحد على الأقل (Ctrl، Alt، Shift) ومفتاح عادي واحد",
|
||||
"hotkey.record": "اضغط على مفتاح لتسجيل الاختصار",
|
||||
"hotkey.reset": "إعادة تعيين الاختصارات إلى الوضع الافتراضي",
|
||||
"hotkey.title": "الاختصارات",
|
||||
"hotkey.updateError": "فشل تحديث الاختصار: خطأ في الشبكة أو النظام",
|
||||
"hotkey.updateSuccess": "تم تحديث الاختصار بنجاح",
|
||||
"llm.aesGcm": "سيتم تشفير مفاتيحك وعنوان الوكيل باستخدام خوارزمية التشفير <1>AES-GCM</1>",
|
||||
"llm.apiKey.desc": "يرجى إدخال مفتاح API الخاص بـ {{name}}",
|
||||
"llm.apiKey.placeholder": "مفتاح API الخاص بـ {{name}}",
|
||||
"hotkey.invalidCombination": "يجب أن تحتوي اختصارات لوحة المفاتيح على مفتاح تعديل واحد على الأقل (Ctrl، Alt، Shift) ومفتاح عادي واحد",
|
||||
"hotkey.record": "اضغط على المفتاح لتسجيل اختصار لوحة المفاتيح",
|
||||
"hotkey.reset": "إعادة تعيين إلى اختصارات لوحة المفاتيح الافتراضية",
|
||||
"hotkey.title": "اختصارات لوحة المفاتيح",
|
||||
"hotkey.updateError": "فشل تحديث اختصار لوحة المفاتيح: خطأ في الشبكة أو النظام",
|
||||
"hotkey.updateSuccess": "تم تحديث اختصار لوحة المفاتيح بنجاح",
|
||||
"llm.aesGcm": "سيتم استخدام خوارزمية التشفير <1>AES-GCM</1> لتشفير مفتاحك وعنوان الوكيل",
|
||||
"llm.apiKey.desc": "يرجى ملء مفتاح API الخاص بك {{name}}",
|
||||
"llm.apiKey.placeholder": "{{name}} مفتاح API",
|
||||
"llm.apiKey.title": "مفتاح API",
|
||||
"llm.checker.button": "تحقق",
|
||||
"llm.checker.desc": "اختبر ما إذا تم ملء مفتاح API وعنوان الوكيل بشكل صحيح",
|
||||
"llm.checker.pass": "تم التحقق بنجاح",
|
||||
"llm.checker.button": "فحص",
|
||||
"llm.checker.desc": "اختبار ما إذا كان مفتاح واجهة البرمجة وعنوان الوكيل مملوء بشكل صحيح",
|
||||
"llm.checker.pass": "تمت المراقبة",
|
||||
"llm.checker.title": "فحص الاتصال",
|
||||
"llm.customModelCards.addNew": "إنشاء وإضافة نموذج {{id}}",
|
||||
"llm.customModelCards.config": "تهيئة النموذج",
|
||||
"llm.customModelCards.confirmDelete": "أنت على وشك حذف هذا النموذج المخصص. لا يمكن استعادته بعد الحذف. يرجى المتابعة بحذر.",
|
||||
"llm.customModelCards.modelConfig.azureDeployName.extra": "الحقل المطلوب فعليًا في Azure OpenAI",
|
||||
"llm.customModelCards.modelConfig.azureDeployName.placeholder": "أدخل اسم نشر النموذج في Azure",
|
||||
"llm.customModelCards.config": "تكوين النموذج",
|
||||
"llm.customModelCards.confirmDelete": "سيتم حذف النموذج المخصص هذا، وبمجرد الحذف لا يمكن استعادته، يرجى التحلي بالحذر.",
|
||||
"llm.customModelCards.modelConfig.azureDeployName.extra": "الحقل الفعلي المطلوب في طلب Azure OpenAI",
|
||||
"llm.customModelCards.modelConfig.azureDeployName.placeholder": "الرجاء إدخال اسم نشر النموذج في Azure",
|
||||
"llm.customModelCards.modelConfig.azureDeployName.title": "اسم نشر النموذج",
|
||||
"llm.customModelCards.modelConfig.displayName.placeholder": "أدخل اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ.",
|
||||
"llm.customModelCards.modelConfig.displayName.title": "اسم عرض النموذج",
|
||||
"llm.customModelCards.modelConfig.files.extra": "تنفيذ تحميل الملفات الحالي هو حل مؤقت مخصص للتجارب الشخصية فقط. يرجى انتظار ميزة تحميل الملفات الكاملة في التحديثات القادمة.",
|
||||
"llm.customModelCards.modelConfig.displayName.placeholder": "الرجاء إدخال اسم العرض للنموذج، مثل ChatGPT، GPT-4، إلخ",
|
||||
"llm.customModelCards.modelConfig.displayName.title": "اسم العرض للنموذج",
|
||||
"llm.customModelCards.modelConfig.files.extra": "تنفيذ تحميل الملفات الحالي هو مجرد حل Hack، ومخصص للتجربة الذاتية فقط. يرجى الانتظار حتى يتم تنفيذ القدرة الكاملة على تحميل الملفات لاحقًا",
|
||||
"llm.customModelCards.modelConfig.files.title": "دعم تحميل الملفات",
|
||||
"llm.customModelCards.modelConfig.functionCall.extra": "هذا يمكّن فقط استدعاء المهارات داخل التطبيق. دعم النموذج الفعلي لاستدعاء المهارات يعتمد على النموذج نفسه — يرجى اختباره.",
|
||||
"llm.customModelCards.modelConfig.functionCall.title": "يدعم استدعاء المهارات",
|
||||
"llm.customModelCards.modelConfig.id.extra": "سيتم عرضه كاسم النموذج",
|
||||
"llm.customModelCards.modelConfig.id.placeholder": "أدخل معرف النموذج، مثل gpt-4-turbo-preview أو claude-2.1",
|
||||
"llm.customModelCards.modelConfig.functionCall.extra": "ستفتح هذه الإعدادات فقط القدرة على استدعاء الوظائف داخل التطبيق، وما إذا كانت الوظائف مدعومة يعتمد تمامًا على النموذج نفسه، يرجى اختبار قابلية استخدام استدعاء الوظائف لهذا النموذج بنفسك",
|
||||
"llm.customModelCards.modelConfig.functionCall.title": "دعم استدعاء الوظائف",
|
||||
"llm.customModelCards.modelConfig.id.extra": "سيتم عرضه كعلامة للنموذج",
|
||||
"llm.customModelCards.modelConfig.id.placeholder": "الرجاء إدخال معرف النموذج، مثل gpt-4-turbo-preview أو claude-2.1",
|
||||
"llm.customModelCards.modelConfig.id.title": "معرف النموذج",
|
||||
"llm.customModelCards.modelConfig.modalTitle": "تهيئة النموذج المخصص",
|
||||
"llm.customModelCards.modelConfig.tokens.title": "الحد الأقصى لعدد الرموز",
|
||||
"llm.customModelCards.modelConfig.vision.extra": "هذا يمكّن فقط تحميل الصور داخل التطبيق. دعم النموذج للرؤية يعتمد على النموذج نفسه — يرجى اختباره.",
|
||||
"llm.customModelCards.modelConfig.vision.title": "يدعم الرؤية",
|
||||
"llm.fetchOnClient.desc": "إرسال الطلبات مباشرة من المتصفح لتحسين زمن الاستجابة.",
|
||||
"llm.fetchOnClient.title": "استخدام وضع طلب العميل",
|
||||
"llm.fetcher.clear": "مسح النموذج المسترجع",
|
||||
"llm.fetcher.fetch": "جلب قائمة النماذج",
|
||||
"llm.fetcher.fetching": "جارٍ جلب قائمة النماذج...",
|
||||
"llm.customModelCards.modelConfig.modalTitle": "تكوين النموذج المخصص",
|
||||
"llm.customModelCards.modelConfig.tokens.title": "أقصى عدد من الرموز",
|
||||
"llm.customModelCards.modelConfig.vision.extra": "ستفتح هذه الإعدادات فقط القدرة على تحميل الصور داخل التطبيق، وما إذا كانت القدرة على التعرف مدعومة يعتمد تمامًا على النموذج نفسه، يرجى اختبار قابلية استخدام التعرف البصري لهذا النموذج بنفسك",
|
||||
"llm.customModelCards.modelConfig.vision.title": "دعم التعرف على الصور",
|
||||
"llm.fetchOnClient.desc": "طريقة طلب العميل ستبدأ طلب الجلسة مباشرة من المتصفح، مما يمكن أن يعزز سرعة الاستجابة",
|
||||
"llm.fetchOnClient.title": "استخدام طريقة طلب العميل",
|
||||
"llm.fetcher.clear": "مسح النموذج المستخرج",
|
||||
"llm.fetcher.fetch": "احصل على قائمة النماذج",
|
||||
"llm.fetcher.fetching": "جاري الحصول على قائمة النماذج...",
|
||||
"llm.fetcher.latestTime": "آخر تحديث: {{time}}",
|
||||
"llm.fetcher.noLatestTime": "لا توجد قائمة متاحة بعد",
|
||||
"llm.helpDoc": "دليل التهيئة",
|
||||
"llm.modelList.desc": "حدد النماذج التي سيتم عرضها في الجلسة. سيتم عرض النماذج المحددة في قائمة النماذج.",
|
||||
"llm.modelList.placeholder": "يرجى اختيار نموذج من القائمة",
|
||||
"llm.fetcher.noLatestTime": "لم يتم الحصول على قائمة بعد",
|
||||
"llm.helpDoc": "دليل التكوين",
|
||||
"llm.modelList.desc": "اختيار النموذج الذي سيتم عرضه في الجلسة، سيتم عرض النموذج المحدد في قائمة النماذج",
|
||||
"llm.modelList.placeholder": "الرجاء اختيار نموذج من القائمة",
|
||||
"llm.modelList.title": "قائمة النماذج",
|
||||
"llm.modelList.total": "إجمالي النماذج المتاحة: {{count}}",
|
||||
"llm.proxyUrl.desc": "يجب أن يتضمن http(s):// بالإضافة إلى العنوان الافتراضي",
|
||||
"llm.modelList.total": "متاح {{count}} نموذج",
|
||||
"llm.proxyUrl.desc": "يجب أن يتضمن عنوان الوكيل API بالإضافة إلى العنوان الافتراضي http(s)://",
|
||||
"llm.proxyUrl.title": "عنوان وكيل API",
|
||||
"llm.waitingForMore": "سيتم <1>إضافة المزيد من النماذج</1> قريبًا، ترقبوا",
|
||||
"llm.waitingForMoreLinkAriaLabel": "فتح نموذج طلب المزود",
|
||||
"marketPublish.modal.changelog.extra": "وصف التغييرات والتحسينات الرئيسية في هذا الإصدار",
|
||||
"llm.waitingForMore": "يتم <1>التخطيط لتوفير</1> المزيد من النماذج، ترقبوا المزيد",
|
||||
"llm.waitingForMoreLinkAriaLabel": "افتح نموذج طلب دمج مزود الخدمة النموذجية",
|
||||
"marketPublish.modal.changelog.extra": "صف التغييرات والتحسينات الرئيسية في هذا الإصدار",
|
||||
"marketPublish.modal.changelog.label": "سجل التغييرات",
|
||||
"marketPublish.modal.changelog.maxLengthError": "يجب ألا يتجاوز سجل التغييرات 500 حرف",
|
||||
"marketPublish.modal.changelog.placeholder": "أدخل سجل التغييرات",
|
||||
"marketPublish.modal.changelog.maxLengthError": "لا يمكن أن يتجاوز سجل التغييرات 500 حرف",
|
||||
"marketPublish.modal.changelog.placeholder": "يرجى إدخال سجل التغييرات",
|
||||
"marketPublish.modal.changelog.required": "يرجى إدخال سجل التغييرات",
|
||||
"marketPublish.modal.comparison.local": "الإصدار المحلي الحالي",
|
||||
"marketPublish.modal.comparison.remote": "الإصدار المنشور حاليًا",
|
||||
"marketPublish.modal.identifier.extra": "هذا هو المعرف الفريد للوكيل. استخدم أحرفًا صغيرة وأرقامًا وشرطات.",
|
||||
"marketPublish.modal.identifier.label": "معرف الوكيل",
|
||||
"marketPublish.modal.comparison.remote": "الإصدار المنشور الحالي",
|
||||
"marketPublish.modal.identifier.extra": "سيكون المعرف هو الهوية الفريدة للمساعد، يُفضل استخدام أحرف صغيرة وأرقام وشرطات",
|
||||
"marketPublish.modal.identifier.label": "معرف المساعد",
|
||||
"marketPublish.modal.identifier.lengthError": "يجب أن يتراوح طول المعرف بين 3 و50 حرفًا",
|
||||
"marketPublish.modal.identifier.patternError": "يمكن أن يحتوي المعرف فقط على أحرف صغيرة وأرقام وشرطات",
|
||||
"marketPublish.modal.identifier.placeholder": "أدخل معرفًا فريدًا للوكيل، مثل web-development",
|
||||
"marketPublish.modal.identifier.required": "يرجى إدخال معرف الوكيل",
|
||||
"marketPublish.modal.identifier.placeholder": "يرجى إدخال معرف فريد للمساعد، مثل: web-development",
|
||||
"marketPublish.modal.identifier.required": "يرجى إدخال معرف المساعد",
|
||||
"marketPublish.modal.loading.fetchingRemote": "جارٍ تحميل البيانات البعيدة...",
|
||||
"marketPublish.modal.loading.submit": "جارٍ إرسال الوكيل...",
|
||||
"marketPublish.modal.loading.submit": "جارٍ نشر المساعد...",
|
||||
"marketPublish.modal.loading.upload": "جارٍ نشر الإصدار الجديد...",
|
||||
"marketPublish.modal.messages.createVersionFailed": "فشل في إنشاء الإصدار: {{message}}",
|
||||
"marketPublish.modal.messages.fetchRemoteFailed": "فشل في جلب بيانات الوكيل البعيدة",
|
||||
"marketPublish.modal.messages.missingIdentifier": "لا يحتوي هذا الوكيل على معرف المجتمع بعد.",
|
||||
"marketPublish.modal.messages.notAuthenticated": "يرجى تسجيل الدخول إلى حسابك في المجتمع أولاً.",
|
||||
"marketPublish.modal.messages.createVersionFailed": "فشل إنشاء الإصدار: {{message}}",
|
||||
"marketPublish.modal.messages.fetchRemoteFailed": "فشل في جلب بيانات المساعد من السوق",
|
||||
"marketPublish.modal.messages.missingIdentifier": "لا يحتوي هذا المساعد على معرف المجتمع حتى الآن",
|
||||
"marketPublish.modal.messages.notAuthenticated": "يرجى تسجيل الدخول إلى حساب المجتمع أولاً",
|
||||
"marketPublish.modal.messages.publishFailed": "فشل النشر: {{message}}",
|
||||
"marketPublish.modal.submitButton": "نشر",
|
||||
"marketPublish.modal.title.submit": "مشاركة في مجتمع الوكلاء",
|
||||
"marketPublish.modal.title.submit": "مشاركة في مجتمع المساعدين",
|
||||
"marketPublish.modal.title.upload": "نشر إصدار جديد",
|
||||
"marketPublish.resultModal.message": "تم إرسال وكيلك للمراجعة. بمجرد الموافقة عليه، سيتم نشره تلقائيًا.",
|
||||
"marketPublish.resultModal.message": "تم إرسال المساعد الذي أنشأته للمراجعة، وسيتم نشره تلقائيًا بعد الموافقة.",
|
||||
"marketPublish.resultModal.title": "تم الإرسال بنجاح",
|
||||
"marketPublish.resultModal.view": "عرض في المجتمع",
|
||||
"marketPublish.submit.button": "مشاركة في المجتمع",
|
||||
"marketPublish.submit.tooltip": "شارك هذا الوكيل في المجتمع",
|
||||
"marketPublish.submit.tooltip": "شارك المساعد في مجتمع المساعدين",
|
||||
"marketPublish.upload.button": "نشر إصدار جديد",
|
||||
"marketPublish.upload.tooltip": "نشر إصدار جديد في مجتمع الوكلاء",
|
||||
"memory.enabled.desc": "اسمح لـ LobeHub باستخلاص التفضيلات والمعلومات من المحادثات واستخدامها لاحقًا. يمكنك عرض أو تعديل أو مسح الذاكرة في أي وقت.",
|
||||
"memory.enabled.title": "تمكين الذاكرة",
|
||||
"marketPublish.upload.tooltip": "نشر إصدار جديد في مجتمع المساعدين",
|
||||
"memory.enabled.desc": "عند التفعيل، سيتذكر الذكاء الاصطناعي تفضيلاتك من سجل المحادثات، ويجمع الذكريات لاستخدامها كمرجع في المحادثات المستقبلية",
|
||||
"memory.enabled.title": "تفعيل ميزة الذاكرة",
|
||||
"memory.title": "إعدادات الذاكرة",
|
||||
"message.success": "تم التحديث بنجاح",
|
||||
"myAgents.actions.cancel": "إلغاء",
|
||||
"myAgents.actions.confirmDeprecate": "تأكيد الإيقاف",
|
||||
"myAgents.actions.deprecate": "إيقاف دائم",
|
||||
"myAgents.actions.deprecateConfirmContent": "بعد الإيقاف، سيتم إزالة هذا الوكيل نهائيًا من السوق ولا يمكن إعادة نشره. هذا الإجراء لا يمكن التراجع عنه، يرجى المتابعة بحذر.",
|
||||
"myAgents.actions.deprecateConfirmTitle": "هل تريد تأكيد إيقاف الوكيل؟",
|
||||
"myAgents.actions.deprecateError": "فشل في إيقاف الوكيل",
|
||||
"myAgents.actions.deprecateLoading": "جارٍ إيقاف الوكيل...",
|
||||
"myAgents.actions.deprecateSuccess": "تم إيقاف الوكيل",
|
||||
"myAgents.actions.edit": "تعديل الوكيل",
|
||||
"myAgents.actions.publish": "نشر الوكيل",
|
||||
"myAgents.actions.publishError": "فشل في نشر الوكيل",
|
||||
"myAgents.actions.publishLoading": "جارٍ نشر الوكيل...",
|
||||
"myAgents.actions.publishSuccess": "تم نشر الوكيل",
|
||||
"myAgents.actions.unpublish": "إلغاء نشر الوكيل",
|
||||
"myAgents.actions.unpublishError": "فشل في إلغاء نشر الوكيل",
|
||||
"myAgents.actions.unpublishLoading": "جارٍ إلغاء نشر الوكيل...",
|
||||
"myAgents.actions.unpublishSuccess": "تم إلغاء نشر الوكيل",
|
||||
"myAgents.actions.confirmDeprecate": "تأكيد الإهمال",
|
||||
"myAgents.actions.deprecate": "إهمال دائم",
|
||||
"myAgents.actions.deprecateConfirmContent": "بعد الإهمال، سيتم إزالة هذا المساعد نهائيًا من السوق ولن يكون من الممكن إعادة نشره. هذا الإجراء لا يمكن التراجع عنه، يرجى الحذر.",
|
||||
"myAgents.actions.deprecateConfirmTitle": "هل تريد تأكيد إهمال المساعد؟",
|
||||
"myAgents.actions.deprecateError": "فشل في إهمال المساعد",
|
||||
"myAgents.actions.deprecateLoading": "جارٍ إهمال المساعد...",
|
||||
"myAgents.actions.deprecateSuccess": "تم إهمال المساعد",
|
||||
"myAgents.actions.edit": "تحرير المساعد",
|
||||
"myAgents.actions.publish": "نشر المساعد",
|
||||
"myAgents.actions.publishError": "فشل في نشر المساعد",
|
||||
"myAgents.actions.publishLoading": "جارٍ نشر المساعد...",
|
||||
"myAgents.actions.publishSuccess": "تم نشر المساعد",
|
||||
"myAgents.actions.unpublish": "إلغاء نشر المساعد",
|
||||
"myAgents.actions.unpublishError": "فشل في إلغاء نشر المساعد",
|
||||
"myAgents.actions.unpublishLoading": "جارٍ إلغاء نشر المساعد...",
|
||||
"myAgents.actions.unpublishSuccess": "تم إلغاء نشر المساعد",
|
||||
"myAgents.actions.viewDetail": "عرض التفاصيل",
|
||||
"myAgents.detail.category": "الفئة",
|
||||
"myAgents.detail.description": "الوصف",
|
||||
"myAgents.detail.identifier": "المعرف",
|
||||
"myAgents.detail.title": "تفاصيل الوكيل",
|
||||
"myAgents.empty.description": "لم تقم بنشر أي وكلاء في السوق بعد",
|
||||
"myAgents.empty.title": "لا يوجد وكلاء منشورون",
|
||||
"myAgents.errors.editFailed": "فشل في تعديل الوكيل، يرجى المحاولة لاحقًا",
|
||||
"myAgents.errors.fetchFailed": "فشل في جلب تفاصيل الوكيل",
|
||||
"myAgents.detail.identifier": "المعرّف",
|
||||
"myAgents.detail.title": "تفاصيل المساعد",
|
||||
"myAgents.empty.description": "لم تقم بنشر أي مساعد في السوق بعد",
|
||||
"myAgents.empty.title": "لا يوجد مساعدين منشورين",
|
||||
"myAgents.errors.editFailed": "فشل في تحرير المساعد، يرجى المحاولة لاحقًا",
|
||||
"myAgents.errors.fetchFailed": "فشل في جلب تفاصيل المساعد",
|
||||
"myAgents.errors.notAuthenticated": "يرجى تسجيل الدخول إلى حساب السوق أولاً",
|
||||
"myAgents.loginRequired.button": "تسجيل الدخول إلى السوق",
|
||||
"myAgents.loginRequired.description": "يرجى تسجيل الدخول إلى حساب السوق لعرض وكلائك المنشورين",
|
||||
"myAgents.loginRequired.title": "مطلوب تسجيل الدخول",
|
||||
"myAgents.loginRequired.button": "تسجيل الدخول إلى حساب السوق",
|
||||
"myAgents.loginRequired.description": "يرجى تسجيل الدخول إلى حساب السوق لعرض المساعدين الذين قمت بنشرهم",
|
||||
"myAgents.loginRequired.title": "تسجيل الدخول مطلوب",
|
||||
"myAgents.status.archived": "مؤرشف",
|
||||
"myAgents.status.deprecated": "موقوف",
|
||||
"myAgents.status.deprecated": "مهمل",
|
||||
"myAgents.status.published": "منشور",
|
||||
"myAgents.status.unpublished": "غير منشور",
|
||||
"myAgents.title": "وكلائي المنشورون",
|
||||
"plugin.addMCPPlugin": "إضافة MCP",
|
||||
"plugin.addTooltip": "مهارات مخصصة",
|
||||
"plugin.clearDeprecated": "إزالة المهارات الموقوفة",
|
||||
"plugin.empty": "لا توجد مهارات مثبتة بعد. استكشف <1>متجر المهارات</1> للبدء.",
|
||||
"myAgents.title": "مساعدي المنشور",
|
||||
"plugin.addMCPPlugin": "إضافة مكون MCP",
|
||||
"plugin.addTooltip": "إضافة البرنامج المساعد",
|
||||
"plugin.clearDeprecated": "مسح البرامج المساعدة الغير صالحة",
|
||||
"plugin.empty": "لا توجد برامج مساعدة مثبتة حاليًا، نرحب بك لزيارة <1>متجر البرامج المساعدة</1> للاستكشاف",
|
||||
"plugin.installStatus.deprecated": "تم إلغاء التثبيت",
|
||||
"plugin.settings.hint": "يرجى ملء الإعدادات التالية بناءً على الوصف",
|
||||
"plugin.settings.title": "إعدادات مهارة {{id}}",
|
||||
"plugin.settings.tooltip": "إعدادات المهارة",
|
||||
"plugin.store": "متجر المهارات",
|
||||
"settingAgent.avatar.sizeExceeded": "يتجاوز حجم الصورة 1 ميجابايت، يرجى اختيار صورة أصغر",
|
||||
"plugin.settings.hint": "يرجى ملء الإعدادات التالية وفقًا للوصف",
|
||||
"plugin.settings.title": "إعدادات البرنامج المساعد {{id}}",
|
||||
"plugin.settings.tooltip": "إعدادات البرنامج المساعد",
|
||||
"plugin.store": "متجر البرامج المساعد",
|
||||
"settingAgent.avatar.sizeExceeded": "تجاوز حجم الصورة الحد الأقصى المسموح به وهو 1 ميغابايت، يرجى اختيار صورة أصغر.",
|
||||
"settingAgent.avatar.title": "الصورة الرمزية",
|
||||
"settingAgent.backgroundColor.title": "لون الخلفية",
|
||||
"settingAgent.description.desc": "مقدمة موجزة عن وكيلك، ليست لإعداد الشخصية",
|
||||
"settingAgent.description.placeholder": "أدخل وصف الوكيل",
|
||||
"settingAgent.description.title": "وصف الوكيل",
|
||||
"settingAgent.name.placeholder": "أدخل اسم الوكيل",
|
||||
"settingAgent.description.desc": "مقدمة بسيطة عن مساعدك، لا تستخدم كإعداد شخصية",
|
||||
"settingAgent.description.placeholder": "الرجاء إدخال وصف المساعد",
|
||||
"settingAgent.description.title": "وصف المساعد",
|
||||
"settingAgent.name.placeholder": "الرجاء إدخال اسم المساعد",
|
||||
"settingAgent.name.title": "الاسم",
|
||||
"settingAgent.prompt.placeholder": "أدخل إعدادات الوكيل، اضغط / لفتح قائمة الأوامر",
|
||||
"settingAgent.prompt.templatePlaceholder": "#### الهدف\nوصف الغرض الرئيسي والهدف من هذا الوكيل.\n\n#### المهارات\n- سرد القدرات الرئيسية\n- ومجالات المعرفة المتخصصة\n\n#### سير العمل\n1. عملية خطوة بخطوة\n2. كيفية تعامل الوكيل مع المهام\n3. التفاعلات المتوقعة مع المستخدمين\n\n#### القيود\n- القيود المهمة التي يجب الالتزام بها\n- إرشادات السلوك",
|
||||
"settingAgent.prompt.title": "ملف تعريف الوكيل",
|
||||
"settingAgent.submit": "تحديث الوكيل",
|
||||
"settingAgent.tag.desc": "سيتم عرض علامات الوكيل في مجتمع الوكلاء",
|
||||
"settingAgent.tag.placeholder": "أدخل علامة",
|
||||
"settingAgent.prompt.placeholder": "أدخل إعدادات المساعد، اضغط / لفتح قائمة الأوامر",
|
||||
"settingAgent.prompt.title": "إعدادات المساعد",
|
||||
"settingAgent.submit": "تحديث معلومات المساعد",
|
||||
"settingAgent.tag.desc": "سيتم عرض وسم المساعد في مجتمع المساعدين",
|
||||
"settingAgent.tag.placeholder": "الرجاء إدخال العلامة",
|
||||
"settingAgent.tag.title": "العلامة",
|
||||
"settingAgent.title": "معلومات الوكيل",
|
||||
"settingAgent.title": "معلومات المساعد",
|
||||
"settingAppearance.animationMode.agile": "سريع",
|
||||
"settingAppearance.animationMode.desc": "اختر سرعة الرسوم المتحركة لإجراءات استجابة التطبيق",
|
||||
"settingAppearance.animationMode.desc": "اختر سرعة استجابة حركة التطبيق",
|
||||
"settingAppearance.animationMode.disabled": "إيقاف",
|
||||
"settingAppearance.animationMode.elegant": "أنيق",
|
||||
"settingAppearance.animationMode.title": "رسوم استجابة التطبيق",
|
||||
"settingAppearance.animationMode.title": "حركة الاستجابة",
|
||||
"settingAppearance.contextMenuMode.default": "افتراضي",
|
||||
"settingAppearance.contextMenuMode.desc": "تمكين قائمة النقر بزر الماوس الأيمن لبعض عناصر القائمة.",
|
||||
"settingAppearance.contextMenuMode.disabled": "معطل",
|
||||
"settingAppearance.contextMenuMode.title": "وضع قائمة النقر الأيمن",
|
||||
"settingAppearance.neutralColor.desc": "تدرجات رمادية مخصصة مع ميول لونية مختلفة",
|
||||
"settingAppearance.neutralColor.title": "اللون المحايد",
|
||||
"settingAppearance.noAnimation.desc": "تعطيل جميع تأثيرات الرسوم المتحركة في التطبيق",
|
||||
"settingAppearance.noAnimation.title": "وضع بدون رسوم متحركة",
|
||||
"settingAppearance.contextMenuMode.desc": "اختر طريقة عرض قائمة النقر بزر الماوس الأيمن لرسائل الدردشة",
|
||||
"settingAppearance.contextMenuMode.disabled": "عدم الاستخدام",
|
||||
"settingAppearance.contextMenuMode.title": "خطة قائمة النقر بزر الماوس الأيمن",
|
||||
"settingAppearance.neutralColor.desc": "تخصيص تدرجات الرمادي ذات الاتجاهات اللونية المختلفة",
|
||||
"settingAppearance.neutralColor.title": "لون محايد",
|
||||
"settingAppearance.noAnimation.desc": "تعطيل جميع تأثيرات الحركة في التطبيق",
|
||||
"settingAppearance.noAnimation.title": "وضع بدون حركة",
|
||||
"settingAppearance.preview.title": "لوحة الألوان",
|
||||
"settingAppearance.primaryColor.desc": "لون السمة المخصص",
|
||||
"settingAppearance.primaryColor.title": "لون السمة",
|
||||
"settingAppearance.primaryColor.desc": "تخصيص لون الموضوع",
|
||||
"settingAppearance.primaryColor.title": "لون الموضوع",
|
||||
"settingAppearance.title": "مظهر التطبيق",
|
||||
"settingChat.autoCreateTopicThreshold.desc": "إنشاء موضوع تلقائيًا عند تجاوز عدد الرسائل الحالية هذه القيمة",
|
||||
"settingChat.autoCreateTopicThreshold.title": "حد الرسائل",
|
||||
"settingChat.chatStyleType.title": "نمط نافذة الدردشة",
|
||||
"settingChat.chatStyleType.type.chat": "وضع المحادثة",
|
||||
"settingChat.chatStyleType.type.docs": "وضع الصفحة",
|
||||
"settingChat.compressThreshold.desc": "عند تجاوز عدد الرسائل غير المضغوطة هذه القيمة، سيتم تطبيق الضغط",
|
||||
"settingChat.compressThreshold.title": "حد ضغط طول سجل الرسائل",
|
||||
"settingChat.enableAutoCreateTopic.desc": "ما إذا كان سيتم إنشاء موضوع تلقائيًا أثناء المحادثة، فعال فقط في المواضيع المؤقتة",
|
||||
"settingChat.enableAutoCreateTopic.title": "إنشاء موضوع تلقائيًا",
|
||||
"settingChat.enableCompressHistory.title": "تمكين التلخيص التلقائي لسجل الدردشة",
|
||||
"settingChat.autoCreateTopicThreshold.desc": "عند تجاوز عدد الرسائل الحالي هذا القيمة، سيتم إنشاء موضوع تلقائيًا",
|
||||
"settingChat.autoCreateTopicThreshold.title": "عتبة إنشاء الموضوع التلقائي",
|
||||
"settingChat.chatStyleType.title": "نوع نافذة الدردشة",
|
||||
"settingChat.chatStyleType.type.chat": "نمط المحادثة",
|
||||
"settingChat.chatStyleType.type.docs": "نمط الوثائق",
|
||||
"settingChat.compressThreshold.desc": "عندما يتجاوز عدد الرسائل التاريخية غير المضغوطة هذه القيمة، سيتم ضغطها",
|
||||
"settingChat.compressThreshold.title": "عتبة ضغط طول الرسائل التاريخية",
|
||||
"settingChat.enableAutoCreateTopic.desc": "هل يجب إنشاء موضوع تلقائيًا أثناء الدردشة، يسري ذلك فقط في المواضيع المؤقتة",
|
||||
"settingChat.enableAutoCreateTopic.title": "تمكين إنشاء الموضوع تلقائيًا",
|
||||
"settingChat.enableCompressHistory.title": "تفعيل تلخيص الرسائل التاريخية تلقائيًا",
|
||||
"settingChat.enableHistoryCount.alias": "غير محدود",
|
||||
"settingChat.enableHistoryCount.limited": "تضمين فقط {{number}} رسالة محادثة",
|
||||
"settingChat.enableHistoryCount.setlimited": "تحديد عدد محدود من الرسائل",
|
||||
"settingChat.enableHistoryCount.title": "تقييد عدد رسائل السجل",
|
||||
"settingChat.enableHistoryCount.unlimited": "عدد غير محدود من رسائل السجل",
|
||||
"settingChat.enableStreaming.desc": "تمكين الإخراج المتدفق لعرض الردود في الوقت الفعلي. عند التعطيل، يتم عرض الرد الكامل فقط.",
|
||||
"settingChat.enableHistoryCount.limited": "يحتوي فقط على {{number}} رسالة محادثة",
|
||||
"settingChat.enableHistoryCount.setlimited": "تعيين عدد الرسائل التاريخية",
|
||||
"settingChat.enableHistoryCount.title": "تحديد عدد الرسائل التاريخية",
|
||||
"settingChat.enableHistoryCount.unlimited": "غير محدود",
|
||||
"settingChat.enableStreaming.desc": "تمكين الإخراج المتدفق لعرض الاستجابات في الوقت الفعلي. عند التعطيل، يتم عرض الاستجابة الكاملة فقط.",
|
||||
"settingChat.enableStreaming.title": "تمكين الإخراج المتدفق",
|
||||
"settingChat.historyCount.desc": "عدد الرسائل التاريخية المرفقة مع كل طلب",
|
||||
"settingChat.historyCount.title": "عدد رسائل السجل المرفقة",
|
||||
"settingChat.inputTemplate.desc": "سيتم ملء أحدث رسالة للمستخدم في هذا القالب",
|
||||
"settingChat.inputTemplate.placeholder": "سيتم استبدال قالب المعالجة المسبقة {{text}} بمعلومات الإدخال الفعلية",
|
||||
"settingChat.inputTemplate.title": "معالجة مسبقة لإدخال المستخدم",
|
||||
"settingChat.historyCount.desc": "عدد الرسائل التي يتم إرفاقها في كل طلب (تشمل الأسئلة والأجوبة الجديدة. يُحسب كل سؤال وجواب كرسالة واحدة)",
|
||||
"settingChat.historyCount.title": "عدد الرسائل المرفقة",
|
||||
"settingChat.inputTemplate.desc": "سيتم ملء أحدث رسالة من المستخدم في هذا القالب",
|
||||
"settingChat.inputTemplate.placeholder": "القالب المُعالج مسبقًا {{text}} سيتم استبداله بالمعلومات المُدخلة في الوقت الحقيقي",
|
||||
"settingChat.inputTemplate.title": "معالجة مُدخلات المستخدم",
|
||||
"settingChat.submit": "تحديث تفضيلات الدردشة",
|
||||
"settingChat.title": "إعدادات الدردشة",
|
||||
"settingChatAppearance.fontSize.desc": "حجم خط الرسائل",
|
||||
"settingChatAppearance.fontSize.marks.normal": "قياسي",
|
||||
"settingChatAppearance.fontSize.desc": "حجم خط محتوى الدردشة",
|
||||
"settingChatAppearance.fontSize.marks.normal": "عادي",
|
||||
"settingChatAppearance.fontSize.title": "حجم الخط",
|
||||
"settingChatAppearance.highlighterTheme.title": "سمة تمييز الكود",
|
||||
"settingChatAppearance.mermaidTheme.title": "سمة Mermaid",
|
||||
"settingChatAppearance.highlighterTheme.title": "موضوع تمييز الكود",
|
||||
"settingChatAppearance.mermaidTheme.title": "موضوع حورية البحر",
|
||||
"settingChatAppearance.title": "مظهر الدردشة",
|
||||
"settingChatAppearance.transitionMode.desc": "اختر كيفية ظهور رسائل الدردشة",
|
||||
"settingChatAppearance.transitionMode.desc": "رسوم انتقال رسائل الدردشة",
|
||||
"settingChatAppearance.transitionMode.options.fadeIn": "تلاشي",
|
||||
"settingChatAppearance.transitionMode.options.none.desc": "يعتمد هذا على طريقة إخراج استجابة النموذج؛ يرجى اختباره بنفسك.",
|
||||
"settingChatAppearance.transitionMode.options.none.desc": "يعتمد هذا على طريقة إخراج استجابة النموذج، يرجى الاختبار بنفسك.",
|
||||
"settingChatAppearance.transitionMode.options.none.value": "بدون",
|
||||
"settingChatAppearance.transitionMode.options.smooth": "سلس",
|
||||
"settingChatAppearance.transitionMode.title": "رسوم الانتقال",
|
||||
"settingCommon.devMode.desc": "تمكين عرض الميزات والخيارات المتعلقة بالمطورين",
|
||||
"settingCommon.devMode.desc": "عند التفعيل، ستظهر الميزات والخيارات الخاصة بالمطورين",
|
||||
"settingCommon.devMode.title": "وضع المطور",
|
||||
"settingCommon.lang.autoMode": "اتباع النظام",
|
||||
"settingCommon.lang.title": "اللغة",
|
||||
"settingCommon.liteMode.desc": "تبسيط الواجهة وإخفاء الميزات المتقدمة",
|
||||
"settingCommon.liteMode.desc": "عند التفعيل، سيتم تبسيط الواجهة وإخفاء الميزات المتقدمة",
|
||||
"settingCommon.liteMode.title": "الوضع المبسط",
|
||||
"settingCommon.responseLanguage.auto": "اتباع النظام",
|
||||
"settingCommon.responseLanguage.desc": "اختر لغة رد الوكيل",
|
||||
"settingCommon.responseLanguage.auto": "اتباع إعدادات النظام",
|
||||
"settingCommon.responseLanguage.desc": "تحديد اللغة التي يستخدمها الذكاء الاصطناعي في الردود",
|
||||
"settingCommon.responseLanguage.placeholder": "اختر لغة الرد",
|
||||
"settingCommon.responseLanguage.title": "لغة الرد",
|
||||
"settingCommon.themeMode.auto": "تلقائي",
|
||||
"settingCommon.themeMode.dark": "داكن",
|
||||
"settingCommon.themeMode.light": "فاتح",
|
||||
"settingCommon.themeMode.title": "السمة",
|
||||
"settingCommon.themeMode.title": "الموضوع",
|
||||
"settingCommon.title": "الإعدادات العامة",
|
||||
"settingGroup.description.placeholder": "أدخل وصف المجموعة",
|
||||
"settingGroup.description.title": "وصف المجموعة",
|
||||
"settingGroup.name.placeholder": "أدخل اسم المجموعة",
|
||||
"settingGroup.name.title": "اسم المجموعة",
|
||||
"settingGroup.scene.desc": "اختر سيناريو المجموعة",
|
||||
"settingGroup.description.placeholder": "يرجى إدخال وصف الفريق",
|
||||
"settingGroup.description.title": "وصف الفريق",
|
||||
"settingGroup.name.placeholder": "يرجى إدخال اسم الفريق",
|
||||
"settingGroup.name.title": "اسم الفريق",
|
||||
"settingGroup.scene.desc": "اختر سيناريو الفريق",
|
||||
"settingGroup.scene.options.casual": "غير رسمي",
|
||||
"settingGroup.scene.options.productive": "إنتاجي",
|
||||
"settingGroup.scene.title": "سيناريو المجموعة",
|
||||
"settingGroup.submit": "تحديث المجموعة",
|
||||
"settingGroup.systemPrompt.placeholder": "يرجى إدخال موجه النظام الرئيسي",
|
||||
"settingGroup.systemPrompt.title": "موجه النظام الرئيسي",
|
||||
"settingGroup.scene.title": "سيناريو الفريق",
|
||||
"settingGroup.submit": "تحديث الفريق",
|
||||
"settingGroup.systemPrompt.placeholder": "يرجى إدخال كلمة تلميح نظام المضيف",
|
||||
"settingGroup.systemPrompt.title": "كلمة تلميح نظام المضيف",
|
||||
"settingGroup.title": "معلومات المجموعة",
|
||||
"settingGroupChat.allowDM.desc": "عند الإيقاف، لا يزال بإمكانك إرسال رسائل مباشرة إلى الوكيل",
|
||||
"settingGroupChat.allowDM.title": "السماح بالرسائل المباشرة من الوكيل",
|
||||
"settingGroupChat.enableSupervisor.desc": "تمكين ميزة المنسق لإدارة محادثات المجموعة",
|
||||
"settingGroupChat.enableSupervisor.title": "تمكين المنسق",
|
||||
"settingGroupChat.maxResponseInRow.desc": "حدد عدد الرسائل المتتالية التي يمكن للعضو الرد بها. اضبط على 0 لتعطيل هذا الحد.",
|
||||
"settingGroupChat.allowDM.desc": "عند الإيقاف، لا يزال بإمكانك إرسال رسائل خاصة إلى المساعد يدويًا",
|
||||
"settingGroupChat.allowDM.title": "السماح للمساعد بإرسال رسائل خاصة",
|
||||
"settingGroupChat.enableSupervisor.desc": "تفعيل ميزة المشرف على المجموعة، حيث يتولى المشرف إدارة سير المحادثات داخل الفريق",
|
||||
"settingGroupChat.enableSupervisor.title": "تفعيل المشرف",
|
||||
"settingGroupChat.maxResponseInRow.desc": "اختر عدد الرسائل التي يمكن للأعضاء الرد عليها بشكل متتالي. تعيين القيمة إلى 0 لتعطيل هذا القيد.",
|
||||
"settingGroupChat.maxResponseInRow.title": "عدد الردود المتتالية",
|
||||
"settingGroupChat.model.desc": "أعضاء المجموعة غير متأثرين. بعض النماذج لا يمكن استخدامها كنموذج منسق.",
|
||||
"settingGroupChat.model.title": "نموذج المنسق",
|
||||
"settingGroupChat.orchestratorTitle": "المنسق",
|
||||
"settingGroupChat.responseOrder.desc": "يرد الوكلاء بناءً على ترتيبهم في الدردشة",
|
||||
"settingGroupChat.model.desc": "لن يتأثر حديث أعضاء المجموعة. بعض النماذج لا يمكن استخدامها كنماذج مشرف.",
|
||||
"settingGroupChat.model.title": "نموذج المضيف",
|
||||
"settingGroupChat.orchestratorTitle": "إعدادات المضيف",
|
||||
"settingGroupChat.responseOrder.desc": "سيقوم الوكلاء بالرد وفقًا للترتيب المحدد في المحادثة",
|
||||
"settingGroupChat.responseOrder.options.natural": "طبيعي",
|
||||
"settingGroupChat.responseOrder.options.sequential": "تسلسلي",
|
||||
"settingGroupChat.responseOrder.placeholder": "اختر ترتيب الرد",
|
||||
"settingGroupChat.responseOrder.title": "ترتيب الرد",
|
||||
"settingGroupChat.responseSpeed.desc": "التحكم في وتيرة المحادثة العامة",
|
||||
"settingGroupChat.responseOrder.options.sequential": "تتابعي",
|
||||
"settingGroupChat.responseOrder.placeholder": "اختر ترتيب الردود",
|
||||
"settingGroupChat.responseOrder.title": "ترتيب الردود",
|
||||
"settingGroupChat.responseSpeed.desc": "التحكم في سرعة سير المحادثة بشكل عام",
|
||||
"settingGroupChat.responseSpeed.options.fast": "سريع",
|
||||
"settingGroupChat.responseSpeed.options.medium": "متوسط",
|
||||
"settingGroupChat.responseSpeed.options.slow": "بطيء",
|
||||
"settingGroupChat.responseSpeed.placeholder": "اختر سرعة الرد",
|
||||
"settingGroupChat.responseSpeed.title": "سرعة الرد",
|
||||
"settingGroupChat.revealDM.desc": "عرض الرسائل الخاصة المرسلة إلى أعضاء آخرين لك.",
|
||||
"settingGroupChat.revealDM.title": "عرض الرسائل الخاصة",
|
||||
"settingGroupChat.revealDM.desc": "اجعل محتوى الرسائل الخاصة المرسلة إلى الأعضاء الآخرين مرئيًا لك.",
|
||||
"settingGroupChat.revealDM.title": "عرض محتوى الرسائل الخاصة",
|
||||
"settingGroupChat.submit": "تحديث الإعدادات",
|
||||
"settingGroupChat.systemPrompt.desc": "موجه نظام مخصص لمضيف دردشة المجموعة. قد يؤثر على سلوك المضيف الافتراضي.",
|
||||
"settingGroupChat.systemPrompt.placeholder": "يرجى إدخال موجه نظام مخصص للمضيف...",
|
||||
"settingGroupChat.systemPrompt.title": "موجه نظام المضيف",
|
||||
"settingGroupChat.systemPrompt.desc": "كلمة تلميح نظام مخصصة لمضيف محادثة الدردشة الجماعية. قد تؤثر على سلوك المضيف الافتراضي.",
|
||||
"settingGroupChat.systemPrompt.placeholder": "يرجى إدخال كلمة تلميح نظام المضيف المخصصة...",
|
||||
"settingGroupChat.systemPrompt.title": "كلمة تلميح نظام المضيف",
|
||||
"settingGroupChat.title": "إعدادات الدردشة",
|
||||
"settingGroupMembers.addToGroup": "إضافة إلى المجموعة",
|
||||
"settingGroupMembers.availableAgents": "الوكلاء المتاحون",
|
||||
"settingGroupMembers.addToGroup": "انضم إلى المجموعة",
|
||||
"settingGroupMembers.availableAgents": "المساعدون المتاحون",
|
||||
"settingGroupMembers.createMember": "إنشاء عضو",
|
||||
"settingGroupMembers.defaultAgent": "وكيل مخصص",
|
||||
"settingGroupMembers.disableHost": "تعطيل المنسق",
|
||||
"settingGroupMembers.edit": "تعديل العضو",
|
||||
"settingGroupMembers.empty": "لا يوجد أعضاء في هذه المجموعة بعد. انقر على + لإضافة أعضاء.",
|
||||
"settingGroupMembers.enableHost": "تمكين المنسق",
|
||||
"settingGroupMembers.groupHost": "المنسق",
|
||||
"settingGroupMembers.defaultAgent": "المساعد المخصص",
|
||||
"settingGroupMembers.disableHost": "تعطيل مساعد المضيف",
|
||||
"settingGroupMembers.edit": "تعديل الأعضاء",
|
||||
"settingGroupMembers.empty": "لا يوجد أعضاء في هذا الفريق حاليًا. انقر على زر + لإضافة أعضاء.",
|
||||
"settingGroupMembers.enableHost": "تمكين مساعد المضيف",
|
||||
"settingGroupMembers.groupHost": "مضيف المجموعة",
|
||||
"settingGroupMembers.groupMembers": "أعضاء المجموعة",
|
||||
"settingGroupMembers.host.description": "مع وجود منسق، يمكن للمجموعة العمل تلقائيًا بشكل أكبر — مثالي للمهام المفتوحة.",
|
||||
"settingGroupMembers.host.title": "المنسق",
|
||||
"settingGroupMembers.noAvailableAgents": "لا يوجد وكلاء متاحون",
|
||||
"settingGroupMembers.host.description": "عندما يكون المضيف في المجموعة، ستعمل الدردشة الجماعية بشكل تلقائي، مناسب للمهام الإبداعية.",
|
||||
"settingGroupMembers.host.title": "المضيف",
|
||||
"settingGroupMembers.noAvailableAgents": "لا يوجد مساعدين متاحين",
|
||||
"settingGroupMembers.noDescription": "لا يوجد وصف",
|
||||
"settingGroupMembers.noMembersInGroup": "لا يوجد أعضاء في المجموعة",
|
||||
"settingGroupMembers.owner": "أنت (المالك)",
|
||||
"settingGroupMembers.remove": "إزالة العضو",
|
||||
"settingGroupMembers.removeFromGroup": "إزالة من المجموعة",
|
||||
"settingGroupMembers.removeFromGroup": "إخراج من المجموعة",
|
||||
"settingGroupMembers.you": "أنت",
|
||||
"settingImage.defaultCount.desc": "تحديد عدد الصور الافتراضي الذي يتم إنشاؤه عند بدء مهمة جديدة في لوحة توليد الصور.",
|
||||
"settingImage.defaultCount.desc": "اضبط عدد الصور الافتراضي عند إنشاء مهمة جديدة في لوحة توليد الصور.",
|
||||
"settingImage.defaultCount.label": "عدد الصور الافتراضي",
|
||||
"settingImage.defaultCount.title": "فن الذكاء الاصطناعي",
|
||||
"settingModel.enableMaxTokens.title": "تفعيل حد الرموز القصوى",
|
||||
"settingModel.enableReasoningEffort.title": "تفعيل ضبط جهد الاستدلال",
|
||||
"settingModel.frequencyPenalty.desc": "كلما زادت القيمة، زادت تنوع وغنى المفردات؛ وكلما انخفضت، أصبحت اللغة أبسط وأكثر مباشرة.",
|
||||
"settingModel.frequencyPenalty.title": "غنى المفردات",
|
||||
"settingModel.maxTokens.desc": "الحد الأقصى لعدد الرموز المستخدمة في كل تفاعل",
|
||||
"settingModel.maxTokens.title": "حد الرموز القصوى",
|
||||
"settingModel.model.desc": "نموذج {{provider}}",
|
||||
"settingImage.defaultCount.title": "إعدادات الرسم بالذكاء الاصطناعي",
|
||||
"settingModel.enableMaxTokens.title": "تمكين الحد الأقصى للردود",
|
||||
"settingModel.enableReasoningEffort.title": "تمكين ضبط قوة الاستدلال",
|
||||
"settingModel.frequencyPenalty.desc": "كلما زادت القيمة، كانت المفردات أكثر تنوعًا؛ وكلما انخفضت القيمة، كانت المفردات أكثر بساطة ووضوحًا",
|
||||
"settingModel.frequencyPenalty.title": "تنوع المفردات",
|
||||
"settingModel.maxTokens.desc": "عدد الرموز الأقصى المستخدمة في التفاعل الواحد",
|
||||
"settingModel.maxTokens.title": "الحد الأقصى للردود",
|
||||
"settingModel.model.desc": "{{provider}} نموذج",
|
||||
"settingModel.model.title": "النموذج",
|
||||
"settingModel.params.title": "إعدادات متقدمة",
|
||||
"settingModel.presencePenalty.desc": "كلما زادت القيمة، زاد الميل لاستخدام تعبيرات متنوعة وتجنب تكرار المفاهيم؛ وكلما انخفضت، زاد الميل لتكرار المفاهيم أو السرد، مما يؤدي إلى تعبير أكثر اتساقًا.",
|
||||
"settingModel.presencePenalty.desc": "كلما زادت القيمة، زادت الميل إلى استخدام تعبيرات مختلفة، مما يتجنب تكرار المفاهيم؛ وكلما انخفضت القيمة، زادت الميل إلى استخدام المفاهيم أو السرد المتكرر، مما يجعل التعبير أكثر اتساقًا",
|
||||
"settingModel.presencePenalty.title": "تنوع التعبير",
|
||||
"settingModel.reasoningEffort.desc": "القيم الأعلى تعزز القدرة على الاستدلال ولكن قد تزيد من وقت الاستجابة واستهلاك الرموز.",
|
||||
"settingModel.reasoningEffort.desc": "كلما زادت القيمة، زادت قوة الاستدلال، ولكن قد يؤدي ذلك إلى زيادة وقت الاستجابة واستهلاك الرموز",
|
||||
"settingModel.reasoningEffort.options.high": "عالي",
|
||||
"settingModel.reasoningEffort.options.low": "منخفض",
|
||||
"settingModel.reasoningEffort.options.medium": "متوسط",
|
||||
"settingModel.reasoningEffort.title": "جهد الاستدلال",
|
||||
"settingModel.reasoningEffort.title": "قوة الاستدلال",
|
||||
"settingModel.submit": "تحديث إعدادات النموذج",
|
||||
"settingModel.temperature.desc": "كلما زادت القيمة، أصبحت الردود أكثر إبداعًا وخيالًا؛ وكلما انخفضت، أصبحت أكثر دقة وانضباطًا.",
|
||||
"settingModel.temperature.desc": "كلما زادت القيمة، كانت الإجابات أكثر إبداعًا وخيالًا؛ وكلما انخفضت القيمة، كانت الإجابات أكثر دقة",
|
||||
"settingModel.temperature.title": "مستوى الإبداع",
|
||||
"settingModel.temperature.warning": "إذا تم ضبط مستوى الإبداع على قيمة عالية جدًا، فقد تصبح المخرجات غير مفهومة.",
|
||||
"settingModel.temperature.warning": "إذا كانت قيمة مستوى الإبداع مرتفعة جدًا، قد تحتوي المخرجات على تشويش",
|
||||
"settingModel.title": "إعدادات النموذج",
|
||||
"settingModel.topP.desc": "عدد الاحتمالات التي يتم أخذها في الاعتبار؛ القيمة الأعلى تقبل المزيد من الإجابات المحتملة، بينما القيمة الأقل تميل لاختيار الإجابة الأكثر احتمالاً. لا يُنصح بتغييرها مع مستوى الإبداع.",
|
||||
"settingModel.topP.title": "الانفتاح على الأفكار",
|
||||
"settingOpening.openingMessage.desc": "الرسالة الافتتاحية التي تظهر عند بدء المحادثة، وتُستخدم لتقديم ميزات الوكيل",
|
||||
"settingOpening.openingMessage.placeholder": "مرحبًا، أنا وكيلك المخصص. يمكنك البدء في الدردشة معي فورًا، أو الانتقال إلى إعدادات الوكيل لإكمال معلوماتي.",
|
||||
"settingOpening.openingMessage.title": "الرسالة الافتتاحية",
|
||||
"settingOpening.openingQuestions.desc": "أسئلة إرشادية تظهر في بداية المحادثة",
|
||||
"settingModel.topP.desc": "عدد الاحتمالات التي يتم أخذها في الاعتبار، كلما زادت القيمة، زادت احتمالية قبول إجابات متعددة؛ وكلما انخفضت القيمة، زادت الميل لاختيار الإجابة الأكثر احتمالًا. لا يُنصح بتغييرها مع مستوى الإبداع",
|
||||
"settingModel.topP.title": "مستوى الانفتاح الفكري",
|
||||
"settingOpening.openingMessage.desc": "رسالة الافتتاح عند بدء المحادثة، تستخدم لتعريف وظائف المساعد",
|
||||
"settingOpening.openingMessage.placeholder": "مرحبًا، أنا المساعد المخصص، يمكنك بدء المحادثة معي على الفور، أو يمكنك الذهاب إلى إعدادات المساعد لإكمال معلوماتي.",
|
||||
"settingOpening.openingMessage.title": "رسالة الافتتاح",
|
||||
"settingOpening.openingQuestions.desc": "الأسئلة الإرشادية المعروضة عند بدء المحادثة",
|
||||
"settingOpening.openingQuestions.empty": "أضف أسئلة افتتاحية لمساعدة المستخدمين على بدء المحادثة بسرعة",
|
||||
"settingOpening.openingQuestions.placeholder": "يرجى إدخال سؤال",
|
||||
"settingOpening.openingQuestions.placeholder": "أدخل السؤال",
|
||||
"settingOpening.openingQuestions.repeat": "السؤال موجود بالفعل",
|
||||
"settingOpening.openingQuestions.title": "الأسئلة الافتتاحية",
|
||||
"settingOpening.title": "إعدادات البداية",
|
||||
"settingPlugin.title": "قائمة المهارات",
|
||||
"settingSystem.accessCode.desc": "تم تفعيل الوصول المشفر من قبل المسؤول",
|
||||
"settingSystem.accessCode.placeholder": "أدخل كلمة مرور الوصول",
|
||||
"settingSystem.accessCode.title": "كلمة مرور الوصول",
|
||||
"settingOpening.openingQuestions.title": "أسئلة الافتتاح",
|
||||
"settingOpening.title": "إعداد الافتتاح",
|
||||
"settingPlugin.title": "قائمة الإضافات",
|
||||
"settingSystem.accessCode.desc": "قام المسؤول بتمكين الوصول المشفر",
|
||||
"settingSystem.accessCode.placeholder": "الرجاء إدخال كلمة المرور",
|
||||
"settingSystem.accessCode.title": "كلمة المرور",
|
||||
"settingSystem.oauth.info.desc": "تم تسجيل الدخول",
|
||||
"settingSystem.oauth.info.title": "معلومات الحساب",
|
||||
"settingSystem.oauth.signin.action": "تسجيل الدخول",
|
||||
"settingSystem.oauth.signin.desc": "سجّل الدخول باستخدام SSO لفتح التطبيق",
|
||||
"settingSystem.oauth.signin.title": "تسجيل الدخول إلى حسابك",
|
||||
"settingSystem.oauth.signin.desc": "قم بتسجيل الدخول باستخدام SSO لفتح التطبيق",
|
||||
"settingSystem.oauth.signin.title": "تسجيل الدخول إلى الحساب",
|
||||
"settingSystem.oauth.signout.action": "تسجيل الخروج",
|
||||
"settingSystem.oauth.signout.confirm": "هل تريد تأكيد تسجيل الخروج؟",
|
||||
"settingSystem.oauth.signout.confirm": "هل ترغب في تأكيد الخروج؟",
|
||||
"settingSystem.oauth.signout.success": "تم تسجيل الخروج بنجاح",
|
||||
"settingSystem.title": "إعدادات النظام",
|
||||
"settingTTS.openai.sttModel": "نموذج OpenAI لتحويل الكلام إلى نص",
|
||||
"settingTTS.openai.sttModel": "نموذج تحويل النص إلى كلام من OpenAI",
|
||||
"settingTTS.openai.title": "OpenAI",
|
||||
"settingTTS.openai.ttsModel": "نموذج OpenAI لتحويل النص إلى كلام",
|
||||
"settingTTS.showAllLocaleVoice.desc": "إذا تم إيقافه، سيتم عرض الأصوات المتوفرة للغة الحالية فقط",
|
||||
"settingTTS.showAllLocaleVoice.title": "عرض جميع الأصوات حسب اللغة",
|
||||
"settingTTS.stt": "إعدادات التعرف على الكلام",
|
||||
"settingTTS.sttAutoStop.desc": "عند الإيقاف، لن يتوقف التعرف على الكلام تلقائيًا ويتطلب النقر يدويًا للإيقاف",
|
||||
"settingTTS.sttAutoStop.title": "إيقاف تلقائي للتعرف على الكلام",
|
||||
"settingTTS.sttLocale.desc": "لغة إدخال الصوت، يمكن أن تحسن دقة التعرف على الكلام",
|
||||
"settingTTS.sttLocale.title": "لغة التعرف على الكلام",
|
||||
"settingTTS.sttService.desc": "حيث أن 'المتصفح' هو خدمة التعرف على الكلام الأصلية في المتصفح",
|
||||
"settingTTS.sttService.title": "خدمة التعرف على الكلام",
|
||||
"settingTTS.openai.ttsModel": "نموذج توليد الكلام من OpenAI",
|
||||
"settingTTS.showAllLocaleVoice.desc": "إذا تم إيقافه، سيتم عرض مصادر الصوت الخاصة باللغة الحالية فقط",
|
||||
"settingTTS.showAllLocaleVoice.title": "عرض جميع مصادر الصوت للغات",
|
||||
"settingTTS.stt": "إعدادات التحويل من الصوت إلى نص",
|
||||
"settingTTS.sttAutoStop.desc": "عند الإيقاف، لن يتم إيقاف تحويل الصوت إلى نص تلقائيًا، وسيتطلب الأمر النقر على زر الإيقاف يدويًا",
|
||||
"settingTTS.sttAutoStop.title": "إيقاف تحويل الصوت إلى نص تلقائيًا",
|
||||
"settingTTS.sttLocale.desc": "لغة الصوت المدخلة، يمكن أن يساعد هذا الخيار في زيادة دقة تحويل الصوت إلى نص",
|
||||
"settingTTS.sttLocale.title": "لغة تحويل الصوت إلى نص",
|
||||
"settingTTS.sttService.desc": "حيث يكون المتصفح هو خدمة التحويل الصوتي الأصلية",
|
||||
"settingTTS.sttService.title": "خدمة تحويل الصوت إلى نص",
|
||||
"settingTTS.submit": "تحديث خدمة الصوت",
|
||||
"settingTTS.title": "خدمة الصوت",
|
||||
"settingTTS.tts": "إعدادات تحويل النص إلى كلام",
|
||||
"settingTTS.ttsService.desc": "إذا كنت تستخدم خدمة OpenAI لتحويل النص إلى كلام، تأكد من تفعيل خدمة نموذج OpenAI",
|
||||
"settingTTS.ttsService.title": "خدمة تحويل النص إلى كلام",
|
||||
"settingTTS.voice.desc": "اختر صوتًا للوكيل الحالي، حيث تدعم خدمات TTS المختلفة أصواتًا مختلفة",
|
||||
"settingTTS.tts": "إعدادات توليد الكلام",
|
||||
"settingTTS.ttsService.desc": "إذا كنت تستخدم خدمة توليد الكلام من OpenAI، يجب التأكد من تمكين خدمة نموذج OpenAI",
|
||||
"settingTTS.ttsService.title": "خدمة توليد الكلام",
|
||||
"settingTTS.voice.desc": "حدد صوتًا للمساعد الحالي، تختلف مصادر الصوت المدعومة بحسب خدمة توليد الكلام",
|
||||
"settingTTS.voice.preview": "معاينة الصوت",
|
||||
"settingTTS.voice.title": "صوت تحويل النص إلى كلام",
|
||||
"settingTTS.voice.title": "مصدر توليد الكلام",
|
||||
"startConversation": "ابدأ المحادثة",
|
||||
"storage.actions.export.button": "تصدير",
|
||||
"storage.actions.export.exportType.agent": "تصدير إعدادات الوكيل",
|
||||
"storage.actions.export.exportType.agentWithMessage": "تصدير الوكيل والرسائل",
|
||||
"storage.actions.export.exportType.all": "تصدير الإعدادات العامة وجميع بيانات الوكلاء",
|
||||
"storage.actions.export.exportType.allAgent": "تصدير جميع إعدادات الوكلاء",
|
||||
"storage.actions.export.exportType.allAgentWithMessage": "تصدير جميع الوكلاء والرسائل",
|
||||
"storage.actions.export.exportType.globalSetting": "تصدير الإعدادات العامة",
|
||||
"storage.actions.export.exportType.agent": "تصدير إعدادات المساعد",
|
||||
"storage.actions.export.exportType.agentWithMessage": "تصدير المساعد والرسائل",
|
||||
"storage.actions.export.exportType.all": "تصدير الإعدادات العالمية وجميع بيانات المساعدين",
|
||||
"storage.actions.export.exportType.allAgent": "تصدير جميع إعدادات المساعدين",
|
||||
"storage.actions.export.exportType.allAgentWithMessage": "تصدير جميع المساعدين والرسائل",
|
||||
"storage.actions.export.exportType.globalSetting": "تصدير الإعدادات العالمية",
|
||||
"storage.actions.export.title": "تصدير البيانات",
|
||||
"storage.actions.import.button": "استيراد",
|
||||
"storage.actions.import.title": "استيراد البيانات",
|
||||
"storage.actions.title": "عمليات متقدمة",
|
||||
"storage.desc": "استخدام التخزين الحالي في المتصفح",
|
||||
"storage.desc": "حجم التخزين في المتصفح الحالي",
|
||||
"storage.embeddings.used": "تخزين المتجهات",
|
||||
"storage.title": "تخزين البيانات",
|
||||
"storage.used": "استخدام التخزين",
|
||||
"submitAgentModal.button": "إرسال الوكيل",
|
||||
"submitAgentModal.identifier": "معرّف الوكيل",
|
||||
"submitAgentModal.metaMiss": "يرجى إكمال معلومات الوكيل قبل الإرسال. يجب أن تتضمن الاسم والوصف والوسوم.",
|
||||
"submitAgentModal.placeholder": "أدخل معرّفًا فريدًا للوكيل، مثل: web-development",
|
||||
"submitAgentModal.success": "تم إرسال الوكيل بنجاح",
|
||||
"submitAgentModal.tooltips": "مشاركة في مجتمع الوكلاء",
|
||||
"sync.device.deviceName.hint": "أضف اسمًا لسهولة التعرف",
|
||||
"sync.device.deviceName.placeholder": "أدخل اسم الجهاز",
|
||||
"storage.used": "حجم التخزين",
|
||||
"submitAgentModal.button": "تقديم المساعد",
|
||||
"submitAgentModal.identifier": "معرف المساعد (identifier)",
|
||||
"submitAgentModal.metaMiss": "يرجى استكمال معلومات المساعد قبل التقديم، يجب أن تتضمن الاسم والوصف والعلامة",
|
||||
"submitAgentModal.placeholder": "الرجاء إدخال معرف المساعد، يجب أن يكون فريدًا، مثل تطوير الويب",
|
||||
"submitAgentModal.success": "تم إرسال المساعد بنجاح",
|
||||
"submitAgentModal.tooltips": "مشاركة في مجتمع المساعدين",
|
||||
"submitFooter.reset": "إعادة تعيين",
|
||||
"submitFooter.submit": "حفظ",
|
||||
"submitFooter.unSaved": "تغييرات غير محفوظة",
|
||||
"submitFooter.unSavedWarning": "هناك تغييرات غير محفوظة حالياً",
|
||||
"sync.device.deviceName.hint": "أضف اسمًا للتعرف بشكل أفضل",
|
||||
"sync.device.deviceName.placeholder": "الرجاء إدخال اسم الجهاز",
|
||||
"sync.device.deviceName.title": "اسم الجهاز",
|
||||
"sync.device.title": "معلومات الجهاز",
|
||||
"sync.device.unknownBrowser": "متصفح غير معروف",
|
||||
"sync.device.unknownOS": "نظام تشغيل غير معروف",
|
||||
"sync.warning.tip": "بعد فترة طويلة من الاختبار المجتمعي، قد لا تلبي مزامنة WebRTC احتياجات مزامنة البيانات العامة بشكل موثوق. يرجى <1>نشر خادم الإشارة</1> قبل الاستخدام.",
|
||||
"sync.webrtc.channelName.desc": "سيستخدم WebRTC هذا الاسم لإنشاء قناة مزامنة. تأكد من أن الاسم فريد.",
|
||||
"sync.webrtc.channelName.placeholder": "أدخل اسم قناة المزامنة",
|
||||
"sync.webrtc.channelName.shuffle": "توليد عشوائي",
|
||||
"sync.device.unknownOS": "نظام التشغيل غير معروف",
|
||||
"sync.warning.tip": "بعد فترة اختبار عامة طويلة، قد لا يكون تزامن WebRTC مستقرًا بما يكفي لتلبية احتياجات التزامن العامة. يرجى <1>نشر خادم الإشارة</1> بنفسك قبل الاستخدام.",
|
||||
"sync.webrtc.channelName.desc": "سيستخدم WebRTC هذا الاسم لإنشاء قناة مزامنة، يرجى التأكد من فرادة اسم القناة",
|
||||
"sync.webrtc.channelName.placeholder": "الرجاء إدخال اسم قناة المزامنة",
|
||||
"sync.webrtc.channelName.shuffle": "توليف عشوائي",
|
||||
"sync.webrtc.channelName.title": "اسم قناة المزامنة",
|
||||
"sync.webrtc.channelPassword.desc": "أضف كلمة مرور لضمان خصوصية القناة. يمكن فقط للأجهزة التي تملك كلمة المرور الصحيحة الانضمام.",
|
||||
"sync.webrtc.channelPassword.placeholder": "أدخل كلمة مرور قناة المزامنة",
|
||||
"sync.webrtc.channelPassword.desc": "إضافة كلمة مرور لضمان خصوصية القناة، يمكن للأجهزة الانضمام إلى القناة فقط عند إدخال كلمة المرور الصحيحة",
|
||||
"sync.webrtc.channelPassword.placeholder": "الرجاء إدخال كلمة مرور قناة المزامنة",
|
||||
"sync.webrtc.channelPassword.title": "كلمة مرور قناة المزامنة",
|
||||
"sync.webrtc.desc": "الاتصال بالبيانات في الوقت الحقيقي من نظير إلى نظير يتطلب أن تكون جميع الأجهزة متصلة بالإنترنت.",
|
||||
"sync.webrtc.enabled.invalid": "يرجى ملء خادم الإشارة واسم قناة المزامنة قبل التفعيل.",
|
||||
"sync.webrtc.enabled.title": "تفعيل المزامنة",
|
||||
"sync.webrtc.signaling.desc": "سيستخدم WebRTC هذا العنوان للمزامنة",
|
||||
"sync.webrtc.signaling.placeholder": "أدخل عنوان خادم الإشارة",
|
||||
"sync.webrtc.desc": "اتصال البيانات النقطي الفوري يتطلب تواجد الأجهزة معًا للمزامنة",
|
||||
"sync.webrtc.enabled.invalid": "الرجاء ملء اسم خادم الإشارة واسم القناة المتزامنة قبل تمكينها",
|
||||
"sync.webrtc.enabled.title": "تمكين المزامنة",
|
||||
"sync.webrtc.signaling.desc": "سيستخدم WebRTC هذا العنوان للتزامن",
|
||||
"sync.webrtc.signaling.placeholder": "الرجاء إدخال عنوان خادم الإشارة",
|
||||
"sync.webrtc.signaling.title": "خادم الإشارة",
|
||||
"sync.webrtc.title": "مزامنة WebRTC",
|
||||
"sync.webrtc.title": "WebRTC مزامنة",
|
||||
"systemAgent.agentMeta.label": "النموذج",
|
||||
"systemAgent.agentMeta.modelDesc": "النموذج المخصص لتوليد اسم الوكيل، وصفه، صورته، ووسومه",
|
||||
"systemAgent.agentMeta.title": "مساعد توليد معلومات الوكيل",
|
||||
"systemAgent.agentMeta.modelDesc": "يحدد النموذج المستخدم لإنشاء اسم المساعد ووصفه وصورته وعلامته",
|
||||
"systemAgent.agentMeta.title": "مساعد إنشاء معلومات المساعد",
|
||||
"systemAgent.customPrompt.addPrompt": "إضافة موجه مخصص",
|
||||
"systemAgent.customPrompt.desc": "عند تعبئته، سيستخدم الوكيل النظامي الموجه المخصص عند توليد المحتوى",
|
||||
"systemAgent.customPrompt.placeholder": "يرجى إدخال موجه مخصص",
|
||||
"systemAgent.customPrompt.title": "موجه مخصص",
|
||||
"systemAgent.customPrompt.desc": "بعد ملئه، سيستخدم المساعد النظامي الموجه المخصص عند إنشاء المحتوى",
|
||||
"systemAgent.customPrompt.placeholder": "أدخل كلمة الموجه المخصصة",
|
||||
"systemAgent.customPrompt.title": "كلمة الموجه المخصصة",
|
||||
"systemAgent.generationTopic.label": "النموذج",
|
||||
"systemAgent.generationTopic.modelDesc": "النموذج المخصص لتسمية مواضيع فن الذكاء الاصطناعي تلقائيًا",
|
||||
"systemAgent.generationTopic.title": "وكيل تسمية مواضيع فن الذكاء الاصطناعي",
|
||||
"systemAgent.helpInfo": "عند إنشاء وكيل جديد، سيتم استخدام إعدادات الوكيل الافتراضية كقيم مسبقة.",
|
||||
"systemAgent.generationTopic.modelDesc": "نموذج مخصص لتسمية موضوعات الرسم بالذكاء الاصطناعي تلقائيًا",
|
||||
"systemAgent.generationTopic.title": "مساعد تسمية مواضيع الرسم بالذكاء الاصطناعي",
|
||||
"systemAgent.helpInfo": "عند إنشاء مساعد جديد، سيتم استخدام إعدادات المساعد الافتراضية كقيم افتراضية.",
|
||||
"systemAgent.historyCompress.label": "النموذج",
|
||||
"systemAgent.historyCompress.modelDesc": "تحديد النموذج المستخدم لضغط سجل المحادثة",
|
||||
"systemAgent.historyCompress.title": "وكيل ضغط سجل المحادثة",
|
||||
"systemAgent.historyCompress.modelDesc": "حدد النموذج المستخدم لضغط تاريخ المحادثة",
|
||||
"systemAgent.historyCompress.title": "مساعد ضغط سجل المحادثة",
|
||||
"systemAgent.queryRewrite.label": "النموذج",
|
||||
"systemAgent.queryRewrite.modelDesc": "تحديد النموذج المستخدم لتحسين استفسارات المستخدم",
|
||||
"systemAgent.queryRewrite.title": "وكيل إعادة صياغة استعلام المكتبة",
|
||||
"systemAgent.queryRewrite.modelDesc": "نموذج مخصص لتحسين أسئلة المستخدمين",
|
||||
"systemAgent.queryRewrite.title": "مساعد إعادة صياغة الأسئلة في مركز الموارد",
|
||||
"systemAgent.thread.label": "النموذج",
|
||||
"systemAgent.thread.modelDesc": "النموذج المخصص لإعادة تسمية المواضيع الفرعية تلقائيًا",
|
||||
"systemAgent.thread.title": "وكيل التسمية التلقائية للمواضيع الفرعية",
|
||||
"systemAgent.title": "وكلاء النظام",
|
||||
"systemAgent.thread.modelDesc": "نموذج مخصص لإعادة تسمية الموضوعات الفرعية تلقائيًا",
|
||||
"systemAgent.thread.title": "مساعد التسمية التلقائية للمواضيع الفرعية",
|
||||
"systemAgent.title": "مساعد النظام",
|
||||
"systemAgent.topic.label": "النموذج",
|
||||
"systemAgent.topic.modelDesc": "النموذج المخصص لإعادة تسمية المواضيع تلقائيًا",
|
||||
"systemAgent.topic.title": "وكيل التسمية التلقائية للمواضيع",
|
||||
"systemAgent.topic.modelDesc": "يحدد النموذج المستخدم لإعادة تسمية الموضوع تلقائيًا",
|
||||
"systemAgent.topic.title": "مساعد التسمية التلقائية للمواضيع",
|
||||
"systemAgent.translation.label": "النموذج",
|
||||
"systemAgent.translation.modelDesc": "تحديد النموذج المستخدم للترجمة",
|
||||
"systemAgent.translation.title": "وكيل ترجمة الرسائل",
|
||||
"systemAgent.translation.modelDesc": "النموذج المحدد للاستخدام في الترجمة",
|
||||
"systemAgent.translation.title": "مساعد ترجمة محتوى الرسائل",
|
||||
"tab.about": "حول",
|
||||
"tab.agent": "خدمة الوكيل",
|
||||
"tab.agent": "المساعد الافتراضي",
|
||||
"tab.apikey": "إدارة مفاتيح API",
|
||||
"tab.chatAppearance": "مظهر المحادثة",
|
||||
"tab.common": "المظهر",
|
||||
"tab.experiment": "تجريبي",
|
||||
"tab.experiment": "تجربة",
|
||||
"tab.hotkey": "اختصارات لوحة المفاتيح",
|
||||
"tab.image": "خدمة توليد الصور",
|
||||
"tab.image": "خدمة الرسم",
|
||||
"tab.llm": "نموذج اللغة",
|
||||
"tab.memory": "الذاكرة",
|
||||
"tab.memory": "إعدادات الذاكرة",
|
||||
"tab.profile": "حسابي",
|
||||
"tab.provider": "مزود خدمة الذكاء الاصطناعي",
|
||||
"tab.proxy": "وكيل الشبكة",
|
||||
"tab.security": "الأمان",
|
||||
"tab.stats": "التحليلات",
|
||||
"tab.stats": "إحصائيات البيانات",
|
||||
"tab.storage": "تخزين البيانات",
|
||||
"tab.sync": "مزامنة السحابة",
|
||||
"tab.tts": "تحويل النص إلى كلام",
|
||||
"tab.tts": "خدمة الكلام",
|
||||
"tab.usage": "إحصائيات الاستخدام",
|
||||
"tools.add": "إضافة مهارة",
|
||||
"tools.builtins.groupName": "المهارات المدمجة",
|
||||
"tools.disabled": "النموذج الحالي لا يدعم استدعاء الوظائف ولا يمكنه استخدام المهارة",
|
||||
"tools.add": "إضافة مكون إضافي",
|
||||
"tools.builtins.groupName": "الامتدادات المدمجة",
|
||||
"tools.disabled": "النموذج الحالي لا يدعم استدعاء الوظائف، ولا يمكن استخدام الإضافة",
|
||||
"tools.klavis.addServer": "إضافة خادم",
|
||||
"tools.klavis.authCompleted": "تم التحقق من الهوية",
|
||||
"tools.klavis.authFailed": "فشل التحقق من الهوية",
|
||||
"tools.klavis.authRequired": "التحقق من الهوية مطلوب",
|
||||
"tools.klavis.authCompleted": "اكتملت المصادقة",
|
||||
"tools.klavis.authFailed": "فشلت المصادقة",
|
||||
"tools.klavis.authRequired": "المصادقة مطلوبة",
|
||||
"tools.klavis.connected": "متصل",
|
||||
"tools.klavis.error": "خطأ",
|
||||
"tools.klavis.groupName": "أدوات Klavis",
|
||||
"tools.klavis.manage": "إدارة Klavis",
|
||||
"tools.klavis.manageTitle": "إدارة تكامل Klavis",
|
||||
"tools.klavis.noServers": "لا توجد خوادم متصلة",
|
||||
"tools.klavis.notEnabled": "خدمة Klavis غير مفعلة",
|
||||
"tools.klavis.oauthRequired": "يرجى إكمال التحقق من OAuth في النافذة الجديدة",
|
||||
"tools.klavis.pendingAuth": "في انتظار التحقق",
|
||||
"tools.klavis.noServers": "لا توجد خوادم متصلة حاليًا",
|
||||
"tools.klavis.notEnabled": "خدمة Klavis غير مفعّلة",
|
||||
"tools.klavis.oauthRequired": "يرجى إكمال مصادقة OAuth في نافذة جديدة",
|
||||
"tools.klavis.pendingAuth": "في انتظار المصادقة",
|
||||
"tools.klavis.serverCreated": "تم إنشاء الخادم بنجاح",
|
||||
"tools.klavis.serverCreatedFailed": "فشل في إنشاء الخادم",
|
||||
"tools.klavis.serverRemoved": "تمت إزالة الخادم",
|
||||
"tools.klavis.servers": "الخوادم",
|
||||
"tools.klavis.tools": "الأدوات",
|
||||
"tools.klavis.verifyAuth": "لقد أكملت التحقق",
|
||||
"tools.klavis.serverRemoved": "تم حذف الخادم",
|
||||
"tools.klavis.servers": "خوادم",
|
||||
"tools.klavis.tools": "أدوات",
|
||||
"tools.klavis.verifyAuth": "لقد أكملت المصادقة",
|
||||
"tools.notInstalled": "غير مثبت",
|
||||
"tools.notInstalledWarning": "هذه المهارة غير مثبتة حاليًا، مما قد يؤثر على وظائف الوكيل.",
|
||||
"tools.plugins.enabled": "مفعلة: {{num}}",
|
||||
"tools.plugins.groupName": "المهارات",
|
||||
"tools.plugins.noEnabled": "لا توجد مهارات مفعلة",
|
||||
"tools.plugins.store": "متجر المهارات",
|
||||
"tools.notInstalledWarning": "المكون الإضافي غير مثبت حاليًا، وقد يؤثر ذلك على استخدام المساعد",
|
||||
"tools.plugins.enabled": "ممكّنة {{num}}",
|
||||
"tools.plugins.groupName": "الإضافات",
|
||||
"tools.plugins.noEnabled": "لا توجد إضافات ممكّنة حاليًا",
|
||||
"tools.plugins.store": "متجر الإضافات",
|
||||
"tools.tabs.all": "الكل",
|
||||
"tools.tabs.installed": "مفعلة",
|
||||
"tools.title": "أدوات التوسعة"
|
||||
"tools.tabs.installed": "مفعّلة",
|
||||
"tools.title": "أدوات الامتداد"
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"duration.TPS": "TPS (الرموز في الثانية): عدد الرموز المُخرجة في الثانية",
|
||||
"duration.TTFT": "TTFT (الوقت حتى أول رمز): زمن استجابة أول رمز",
|
||||
"duration.completion": "زمن إتمام الإخراج",
|
||||
"duration.latency": "المدة",
|
||||
"duration.stage.end": "النهاية",
|
||||
"duration.stage.firstToken": "أول رمز",
|
||||
"duration.stage.start": "البداية",
|
||||
"table.columns.TTFT.tooltip": "الوقت حتى أول رمز، الوحدة: ثوانٍ",
|
||||
"table.columns.duration": "المدة",
|
||||
"table.columns.model": "النموذج",
|
||||
"table.columns.spend": "الاعتمادات",
|
||||
"table.columns.startTime": "تاريخ الإنشاء",
|
||||
"table.columns.totalTokens": "استخدام الرموز",
|
||||
"table.columns.type.enums.chat": "توليد نصوص",
|
||||
"table.columns.type.enums.imageGeneration": "توليد صور",
|
||||
"table.columns.type.title": "النوع",
|
||||
"table.desc": "تفاصيل استخدام الاعتمادات الحاسوبية لتوليد النصوص، التضمين، توليد الصور، وغيرها.",
|
||||
"table.more": "عرض التفاصيل",
|
||||
"table.title": "تفاصيل استخدام الاعتمادات الحاسوبية",
|
||||
"table.totalToken.input": "المدخلات",
|
||||
"table.totalToken.output": "المخرجات"
|
||||
}
|
||||
@@ -1,375 +1,8 @@
|
||||
{
|
||||
"balance.creditBalance": "رصيد الرصيد الإضافي",
|
||||
"balance.hobbyDesc": "{{hobby}} لا يشمل أرصدة الاشتراك، تحتاج إلى تكوين واجهة برمجة التطبيقات للنموذج أو شحن الرصيد",
|
||||
"balance.link.history": "سجل الشحن",
|
||||
"balance.link.usage": "عرض الاستخدام",
|
||||
"balance.plansUsage": "أرصدة الاشتراك",
|
||||
"balance.plansUsageDesc": "يتم استخدام أرصدة الاشتراك أولاً، ثم أرصدة الشحن",
|
||||
"balance.title": "الرصيد",
|
||||
"billing.amount": "المبلغ",
|
||||
"billing.closed": "مغلق",
|
||||
"billing.created": "تاريخ الدفع",
|
||||
"billing.draft": "مسودة",
|
||||
"billing.draftTooltip": "تم إنشاء هذه الفاتورة كمسودة بواسطة اشتراك جديد وسيتم خصمها تلقائيًا قريبًا",
|
||||
"billing.empty": "لا يوجد سجل فواتير",
|
||||
"billing.endDate": "تاريخ الانتهاء",
|
||||
"billing.history": "سجل الفواتير",
|
||||
"billing.orderNumber": "رقم الطلب",
|
||||
"billing.paid": "مدفوع",
|
||||
"billing.pay": "ادفع الآن",
|
||||
"billing.paymentGateway": "بوابة الدفع",
|
||||
"billing.paymentMethod": "طريقة الدفع",
|
||||
"billing.price": "سعر الاشتراك",
|
||||
"billing.startDate": "تاريخ البدء",
|
||||
"billing.status": "حالة المعاملة",
|
||||
"billing.subscriptionId": "معرّف الاشتراك",
|
||||
"billing.unpaid": "غير مدفوع",
|
||||
"billing.view": "عرض",
|
||||
"cancelPlan.alert": "ستستمر في الاستفادة من المزايا حتى انتهاء الخطة الحالية ({{date}}). يمكنك إعادة الاشتراك في أي وقت قبل انتهاء الصلاحية.",
|
||||
"cancelPlan.desc": "بعد الإلغاء، سيتم تخفيضك إلى النسخة المجانية عند انتهاء الخطة الحالية.",
|
||||
"cancelPlan.title": "إلغاء الاشتراك",
|
||||
"cancelSubscription": "إلغاء الاشتراك",
|
||||
"compare.hobbyCreditTooltip": "لا يشمل أرصدة الحوسبة الشهرية، تحتاج إلى تكوين واجهة برمجة التطبيقات الخاصة بك",
|
||||
"compare.monthlyCredit": "أرصدة الحوسبة الشهرية",
|
||||
"compare.title": "مقارنة الخطط",
|
||||
"compareAllPlans": "عرض جميع الخطط",
|
||||
"comparePlans": "عرض الخطط",
|
||||
"createSubscriptionError": "فشل في إنشاء الاشتراك",
|
||||
"currentPlan.cancelAlert": "سيتم إلغاء الاشتراك بعد {{canceledAt}}. لا يزال بإمكانك استعادته من \"إدارة الاشتراك\" قبل ذلك",
|
||||
"currentPlan.downgradeAlert": "سيتم تخفيض الخطة إلى {{plan}} بعد {{downgradedAt}}.",
|
||||
"currentPlan.management": "إدارة الاشتراك",
|
||||
"currentPlan.notIncluded": "غير مشمول في الخطة الحالية",
|
||||
"currentPlan.paymentExpired": "سينتهي هذا الاشتراك في {{expiredAt}}، يرجى التخطيط لاستخدامك وفقًا لذلك",
|
||||
"currentPlan.seeAllFeaturesAndComparePlans": "عرض جميع الميزات ومقارنة الخطط",
|
||||
"currentPlan.title": "الخطة الحالية",
|
||||
"discount.add": "إضافة",
|
||||
"discount.maxOff": "خصم يصل إلى {{percent}}٪",
|
||||
"discount.off": "{{percent}}٪ خصم",
|
||||
"discount.save": "توفير",
|
||||
"downgradePlans.alert": "ستستمر في الاستفادة من المزايا حتى انتهاء الخطة الحالية ({{date}}). ستصبح الخطة الجديدة سارية بعد انتهاء الخطة الحالية.",
|
||||
"downgradePlans.desc": "سيتم تطبيق تغيير الخطة بعد انتهاء الخطة الحالية.",
|
||||
"downgradePlans.success": "تم إلغاء الاشتراك بنجاح",
|
||||
"downgradePlans.title": "التحويل إلى {{plan}}",
|
||||
"funds.packages.expired": "منتهية",
|
||||
"funds.packages.expiresIn": "تنتهي خلال {{days}} يومًا",
|
||||
"funds.packages.expiresToday": "تنتهي اليوم",
|
||||
"funds.packages.expiringSoon": "ستنتهي قريبًا",
|
||||
"funds.packages.noPackages": "لا توجد حزم أرصدة",
|
||||
"funds.packages.purchaseFirst": "اشترِ أول حزمة أرصدة لك",
|
||||
"funds.packages.purchasedOn": "تم الشراء في {{date}}",
|
||||
"funds.packages.sort.amountAsc": "المبلغ: من الأقل إلى الأعلى",
|
||||
"funds.packages.sort.amountDesc": "المبلغ: من الأعلى إلى الأقل",
|
||||
"funds.packages.sort.balanceAsc": "الرصيد: من الأقل إلى الأعلى",
|
||||
"funds.packages.sort.balanceDesc": "الرصيد: من الأعلى إلى الأقل",
|
||||
"funds.packages.sort.newest": "الأحدث",
|
||||
"funds.packages.sort.oldest": "الأقدم",
|
||||
"funds.packages.tabs.active": "الحزم النشطة",
|
||||
"funds.packages.tabs.activeCount": "نشطة ({{count}})",
|
||||
"funds.packages.tabs.depleted": "المنتهية",
|
||||
"funds.packages.tabs.depletedCount": "منتهية ({{count}})",
|
||||
"funds.packages.tabs.expired": "المنتهية الصلاحية",
|
||||
"funds.packages.tabs.expiredCount": "منتهية الصلاحية ({{count}})",
|
||||
"funds.packages.title": "حزم الأرصدة الخاصة بي",
|
||||
"funds.topUp.cancel": "إلغاء",
|
||||
"funds.topUp.custom": "مخصص",
|
||||
"funds.topUp.maxAmountError": "لا يمكن أن يتجاوز مبلغ الشراء الواحد ${{max}}",
|
||||
"funds.topUp.purchaseError": "فشل الشراء، يرجى المحاولة لاحقًا",
|
||||
"funds.topUp.purchaseNow": "اشترِ الآن",
|
||||
"funds.topUp.selectPackage": "اختر الحزمة",
|
||||
"funds.topUp.subscribeFirst": "اشترك أولاً",
|
||||
"funds.topUp.success.credits": "+{{quantity}} أرصدة",
|
||||
"funds.topUp.success.title": "تم الشحن بنجاح",
|
||||
"funds.topUp.title": "شراء الأرصدة",
|
||||
"funds.topUp.total": "الإجمالي",
|
||||
"funds.topUp.unitPrice": "سعر الوحدة",
|
||||
"funds.topUp.unitPriceFormat": "${{price}} / 1M {{creditLabel}}",
|
||||
"funds.topUp.upgradePrefix": "الترقية إلى",
|
||||
"funds.topUp.upgradeSuffix": "لتوفير ${{savings}}",
|
||||
"funds.topUp.validityInfo": "صالح لمدة {{months}} أشهر",
|
||||
"header.desc": "إدارة الاستخدام والاشتراك",
|
||||
"header.title": "الفوترة",
|
||||
"keyMissMatch.button": "استعادة الاستخدام ومتابعة المحادثة",
|
||||
"keyMissMatch.description": "بسبب خلل مؤقت في النظام، تم تعطيل استخدام اشتراكك مؤقتًا. يرجى النقر على الزر أدناه لاستعادة الاستخدام ومتابعة المحادثة. إذا تكرر ذلك، يرجى التواصل معنا عبر البريد الإلكتروني (support@lobehub.com)",
|
||||
"keyMissMatch.title": "استعادة استخدام الاشتراك الآن",
|
||||
"limitation.chat.success.action": "متابعة المحادثة",
|
||||
"limitation.chat.success.desc": "تمت ترقية اشتراكك في {{plan}} بنجاح. استمتع بالدردشة مع الذكاء الاصطناعي. تتضمن خطتك الحالية:",
|
||||
"limitation.chat.success.title": "تمت الترقية بنجاح",
|
||||
"limitation.chat.topupSuccess.action": "متابعة المحادثة",
|
||||
"limitation.chat.topupSuccess.desc": "أرصدة الشحن الخاصة بك نشطة الآن. استمتع بالدردشة مع الذكاء الاصطناعي. تتضمن خطتك الحالية:",
|
||||
"limitation.chat.topupSuccess.title": "تم الشحن بنجاح",
|
||||
"limitation.expired.desc": "انتهت صلاحية أرصدة الحوسبة الخاصة بك في خطة {{plan}} بتاريخ {{expiredAt}}. قم بالترقية الآن للحصول على أرصدة جديدة.",
|
||||
"limitation.expired.title": "انتهت أرصدة الحوسبة",
|
||||
"limitation.hobby.action": "تم التكوين، تابع المحادثة",
|
||||
"limitation.hobby.configAPI": "تكوين API",
|
||||
"limitation.hobby.desc": "تم استهلاك أرصدة الحوسبة المجانية الخاصة بك. يرجى تكوين واجهة برمجة التطبيقات المخصصة للنموذج للمتابعة.",
|
||||
"limitation.hobby.docs": "عرض مستندات التكوين",
|
||||
"limitation.hobby.tip": "تأكد من التبديل إلى نموذج يستخدم مفتاح API مخصص",
|
||||
"limitation.hobby.title": "يرجى تكوين واجهة برمجة التطبيقات لخدمة النموذج",
|
||||
"limitation.image.success.action": "متابعة التوليد",
|
||||
"limitation.image.success.desc": "تمت ترقية اشتراكك في {{plan}} بنجاح. استمتع بتوليد الصور بالذكاء الاصطناعي. تتضمن خطتك الحالية:",
|
||||
"limitation.image.success.title": "تمت الترقية بنجاح",
|
||||
"limitation.image.topupSuccess.action": "متابعة التوليد",
|
||||
"limitation.image.topupSuccess.desc": "أرصدة الشحن الخاصة بك نشطة الآن. استمتع بتوليد الصور بالذكاء الاصطناعي. تتضمن خطتك الحالية:",
|
||||
"limitation.image.topupSuccess.title": "تم الشحن بنجاح",
|
||||
"limitation.limited.action": "الترقية الآن",
|
||||
"limitation.limited.advanceFeature": "قم بالترقية للاستمتاع بالميزات المميزة:",
|
||||
"limitation.limited.desc": "تم استهلاك أرصدة الحوسبة الخاصة بك في خطة {{plan}}. قم بالترقية الآن للحصول على المزيد من الأرصدة.",
|
||||
"limitation.limited.descUltimate": "تم استهلاك أرصدة الحوسبة الخاصة بك في خطة {{plan}}. يرجى شحن الأرصدة للمتابعة.",
|
||||
"limitation.limited.referralTip": "ادعُ مستخدمين جدد للتسجيل، وستحصل أنت وصديقك على {{reward}}M أرصدة لكل منكما",
|
||||
"limitation.limited.title": "تم استهلاك أرصدة الحوسبة",
|
||||
"limitation.limited.topup": "شحن الأرصدة",
|
||||
"limitation.limited.upgrade": "الترقية إلى خطة أعلى",
|
||||
"limitation.providers.lock.addNew": "اشترك الآن لإنشاء مزودي ذكاء اصطناعي مخصصين",
|
||||
"limitation.providers.lock.enableProvider": "اشترك الآن لتفعيل هذا المزود",
|
||||
"limitation.providers.lock.menuItem": "اشترك الآن لتكوين خدمة API مخصصة",
|
||||
"limitation.providers.mask.action": "الترقية الآن",
|
||||
"limitation.providers.mask.subTitle": "خدمة API المخصصة متاحة فقط للخطط المدفوعة. قم بالترقية الآن للاستفادة من خدمات النماذج العالمية",
|
||||
"limitation.providers.mask.title": "اشترك الآن لاستخدام خدمة API مخصصة",
|
||||
"limitation.providers.prompter.action": "الترقية الآن",
|
||||
"limitation.providers.prompter.subTitle": "خدمة API المخصصة متاحة فقط للخطط المدفوعة. قم بالترقية الآن للاستفادة من خدمات النماذج العالمية",
|
||||
"limitation.providers.prompter.title": "اشترك الآن لاستخدام خدمة API مخصصة",
|
||||
"limitation.providers.tooltip": "خدمة API المخصصة متاحة فقط للخطط المدفوعة",
|
||||
"modelPricing.button": "عرض مستندات التسعير",
|
||||
"modelPricing.desc": "يستخدم {{name}} الأرصدة لقياس استخدام نموذج الذكاء الاصطناعي. يوضح الجدول أدناه أرصدة الحوسبة لكل 1M رموز.",
|
||||
"modelPricing.title": "تسعير نموذج النص",
|
||||
"models.input": "إدخال",
|
||||
"models.intro": "مقدمة",
|
||||
"models.link": "عرض",
|
||||
"models.output": "إخراج",
|
||||
"models.title": "النماذج",
|
||||
"payDiffPrice": "دفع الفرق",
|
||||
"payment.error.actions.billing": "إدارة الفوترة",
|
||||
"payment.error.actions.home": "العودة إلى الصفحة الرئيسية",
|
||||
"payment.error.desc": "معرّف الاشتراك: {{id}} غير موجود. إذا كانت لديك أسئلة، يرجى التواصل معنا عبر البريد الإلكتروني",
|
||||
"payment.error.title": "فشل الاستعلام",
|
||||
"payment.result.title": "نتيجة الاشتراك",
|
||||
"payment.success.actions.startUsing": "ابدأ الاستخدام",
|
||||
"payment.success.actions.viewBill": "عرض سجل الفوترة",
|
||||
"payment.success.desc": "تم تفعيل خطة الاشتراك بنجاح",
|
||||
"payment.success.title": "تم الاشتراك بنجاح",
|
||||
"payment.switchSuccess.desc": "سيتم التبديل إلى خطة الاشتراك الجديدة تلقائيًا في {{switchAt}}",
|
||||
"payment.switchSuccess.title": "تم التبديل بنجاح",
|
||||
"payment.upgradeFailed.alert.reason.bank3DS": "يتطلب البنك الخاص بك التحقق ثلاثي الأبعاد 3DS، يرجى التأكيد مرة أخرى",
|
||||
"payment.upgradeFailed.alert.reason.inefficient": "رصيد البطاقة غير كافٍ",
|
||||
"payment.upgradeFailed.alert.reason.security": "رقابة أمان من نظام Stripe",
|
||||
"payment.upgradeFailed.alert.title": "أسباب شائعة لفشل الدفع التلقائي",
|
||||
"payment.upgradeFailed.desc": "فشل ترقية الاشتراك. يرجى التحقق والمحاولة مرة أخرى",
|
||||
"payment.upgradeFailed.title": "فشل الترقية",
|
||||
"payment.upgradeSuccess.desc": "تم ترقية خطة الاشتراك بنجاح",
|
||||
"payment.upgradeSuccess.title": "تمت الترقية بنجاح",
|
||||
"plans.btn.contact": "اتصل بنا",
|
||||
"plans.btn.noAction": "الخطة مقفلة",
|
||||
"plans.btn.payment": "شراء",
|
||||
"plans.btn.paymentDesc": "يدعم بطاقات الائتمان / Alipay / WeChat Pay",
|
||||
"plans.btn.paymentDescForZarinpal": "يدعم بطاقات الائتمان",
|
||||
"plans.btn.soon": "قريبًا",
|
||||
"plans.changePlan": "اختر خطة",
|
||||
"plans.cloud.history": "سجل محادثات غير محدود",
|
||||
"plans.cloud.sync": "مزامنة سحابية عالمية",
|
||||
"plans.cloud.title": "الخدمة السحابية",
|
||||
"plans.credit.api": "واجهة برمجة تطبيقات مخصصة",
|
||||
"plans.credit.apiDesc": "يتطلب إعداد واجهة برمجة التطبيقات الخاصة بك",
|
||||
"plans.credit.apiProvider": "يدعم أكثر من 20 مزودًا رئيسيًا للنماذج مثل OpenAI / Anthropic / OpenRouter",
|
||||
"plans.credit.buy": "شراء أرصدة الحوسبة",
|
||||
"plans.credit.buyDesc": "يدعم أيضًا الشراء حسب الطلب",
|
||||
"plans.credit.none": "لا توجد أرصدة حوسبة مدمجة",
|
||||
"plans.credit.tip": "{{credit}} رصيد مجاني شهريًا",
|
||||
"plans.credit.title": "أرصدة الحوسبة",
|
||||
"plans.credit.tooltip": "أرصدة الحوسبة الشهرية لرسائل النماذج",
|
||||
"plans.current": "الخطة الحالية",
|
||||
"plans.downgradePlan": "خطة التخفيض المستهدفة",
|
||||
"plans.downgradeTip": "لقد قمت بالفعل بتغيير الاشتراك. لا يمكنك تنفيذ عمليات أخرى حتى يكتمل التبديل",
|
||||
"plans.embeddingStorage.embeddings": "مدخلات",
|
||||
"plans.embeddingStorage.title": "تخزين المتجهات",
|
||||
"plans.embeddingStorage.tooltip": "تنتج صفحة مستند واحدة (1000-1500 حرف) حوالي إدخال متجه واحد. (تقدير باستخدام OpenAI Embeddings، وقد يختلف حسب النموذج)",
|
||||
"plans.features.agents": "سوق الوكلاء المختارين",
|
||||
"plans.features.ceAgents": "سوق وكلاء المجتمع",
|
||||
"plans.features.cePlugins": "سوق الإضافات المجتمعية",
|
||||
"plans.features.internet": "بحث ذكي على الإنترنت",
|
||||
"plans.features.plugins": "إضافات مميزة حصرية",
|
||||
"plans.features.showAll": "عرض جميع الميزات",
|
||||
"plans.features.title": "الميزات المميزة",
|
||||
"plans.fileStorage.title": "تخزين الملفات",
|
||||
"plans.fileStorage.tooltip": "تخزين الملفات والصور والبيانات الأخرى",
|
||||
"plans.free": "مجاني",
|
||||
"plans.freeTrail": "سجل للحصول على تجربة مجانية لـ {{name}}، لا حاجة لبطاقة ائتمان",
|
||||
"plans.includes": "تشمل المزايا:",
|
||||
"plans.includesExtra": "جميع مزايا {{name}}، بالإضافة إلى:",
|
||||
"plans.knowledgeBase.desc": "استخدم الملفات وقاعدة المعرفة في المحادثات",
|
||||
"plans.knowledgeBase.filetype": "يدعم PDF / MD / DOC / XLS / PPT وغيرها",
|
||||
"plans.knowledgeBase.title": "الملفات وقاعدة المعرفة",
|
||||
"plans.knowledgeBase.tooltip": "يدعم تحميل الملفات وميزات قاعدة المعرفة. قم بتحميل ملفات، صور، صوت، فيديو والمزيد. أنشئ قواعد معرفة لإدارة الملفات بسهولة. استخدمها في المحادثات لتجربة أغنى.",
|
||||
"plans.llm.customAPI": "خدمة واجهة برمجة التطبيقات المخصصة للنماذج العالمية",
|
||||
"plans.llm.messageRequest": "طلبات رسائل غير محدودة",
|
||||
"plans.llm.title": "خدمة النماذج",
|
||||
"plans.llm.tooltip": "أضف مزود واجهة برمجة التطبيقات الخاص بك مع الاستفادة من المزامنة السحابية",
|
||||
"plans.message.count": "حوالي {{number}} رسالة",
|
||||
"plans.message.more": "المزيد من النماذج في مقارنة الخطط",
|
||||
"plans.message.normalLLM": "نماذج قياسية",
|
||||
"plans.message.proLLM": "نماذج مميزة",
|
||||
"plans.message.tooltip": "تقدير بناءً على متوسط {{number}} رمز لكل رسالة",
|
||||
"plans.mostPicked": "الأكثر اختيارًا",
|
||||
"plans.navs.monthly": "شهريًا",
|
||||
"plans.navs.payonce": "دفع لمرة واحدة",
|
||||
"plans.navs.yearly": "سنويًا",
|
||||
"plans.payonce.cancel": "إلغاء",
|
||||
"plans.payonce.ok": "تأكيد الاختيار",
|
||||
"plans.payonce.popconfirm": "بعد الدفع لمرة واحدة، يجب الانتظار حتى انتهاء الاشتراك لتغيير الخطة أو دورة الفوترة. يرجى تأكيد اختيارك.",
|
||||
"plans.payonce.tooltip": "يتطلب الدفع لمرة واحدة الانتظار حتى انتهاء الاشتراك لتغيير الخطة أو دورة الفوترة",
|
||||
"plans.plan.enterprise.contactSales": "اتصل بالمبيعات",
|
||||
"plans.plan.enterprise.title": "الشركات",
|
||||
"plans.plan.free.desc": "للمستخدمين الجدد",
|
||||
"plans.plan.free.title": "مجاني",
|
||||
"plans.plan.hobby.desc": "للمستخدمين الذين لديهم واجهة برمجة تطبيقات خاصة بهم ويدفعون حسب الاستخدام",
|
||||
"plans.plan.hobby.title": "هواية",
|
||||
"plans.plan.premium.desc": "مصمم للمستخدمين المحترفين الذين يستخدمون الذكاء الاصطناعي بشكل متكرر",
|
||||
"plans.plan.premium.title": "مميز",
|
||||
"plans.plan.starter.desc": "للمستخدمين العرضيين للذكاء الاصطناعي",
|
||||
"plans.plan.starter.title": "مبتدئ",
|
||||
"plans.plan.ultimate.desc": "للمستخدمين الكثيفين الذين يحتاجون إلى محادثات ذكاء اصطناعي معقدة",
|
||||
"plans.plan.ultimate.title": "النهائي",
|
||||
"plans.storage.title": "تخزين البيانات",
|
||||
"plans.subscribe": "اشترك",
|
||||
"plans.support.hobby": "منتدى المجتمع",
|
||||
"plans.support.premium": "دعم عبر البريد الإلكتروني ذو أولوية",
|
||||
"plans.support.starter": "بريد إلكتروني ومنتدى المجتمع",
|
||||
"plans.support.title": "الدعم",
|
||||
"plans.support.ultimate": "دعم عبر الدردشة والبريد الإلكتروني ذو أولوية",
|
||||
"plans.target": "الخطة المستهدفة",
|
||||
"plans.unlimited": "غير محدود",
|
||||
"qa.desc": "إذا لم تجد إجابتك، تحقق من <1>وثائق المنتج</1> لمزيد من الأسئلة الشائعة، أو تواصل معنا.",
|
||||
"qa.detail": "عرض التفاصيل",
|
||||
"qa.list.credit.a": "أرصدة الحوسبة هي وحدة قياس يستخدمها {{cloud}} لقياس استخدام نماذج الذكاء الاصطناعي. تستهلك النماذج المختلفة كميات مختلفة من الأرصدة.",
|
||||
"qa.list.credit.q": "ما هي أرصدة الحوسبة؟",
|
||||
"qa.list.embeddings.a": "تخزين المتجهات لا يساوي حجم البيانات الأصلية، بل يُحسب بناءً على تحويل النصوص إلى متجهات. على سبيل المثال، ملف PDF من صفحة واحدة قد ينتج فقط إدخال متجه واحد.",
|
||||
"qa.list.embeddings.q": "كيف يتم حساب تخزين المتجهات؟",
|
||||
"qa.list.free.a": "{{name}} يلتزم بمبادئ المصدر المفتوح. يمكن للمطورين المحترفين استخدام جميع الميزات عبر النشر الذاتي. في {{cloud}}، نقدم {{credit}} رصيد مجاني شهريًا لجميع المستخدمين المسجلين.",
|
||||
"qa.list.free.q": "هل يمكن استخدام {{name}} مجانًا؟",
|
||||
"qa.list.limit.a": "خطط الاشتراك في {{cloud}} تشمل {{starter}}، {{premium}} و{{ultimate}}، وتوفر أرصدة مختلفة. إذا لم تكن الأرصدة كافية، يمكنك الترقية أو استخدام واجهة برمجة تطبيقات مخصصة.",
|
||||
"qa.list.limit.q": "ماذا أفعل إذا نفدت أرصدة الحوسبة؟",
|
||||
"qa.list.management.a": "من صفحة {{subscribe}}، يمكنك ترقية أو تخفيض خطتك، أو التبديل بين الفوترة الشهرية والسنوية. من خلال \"{{usage}}-{{management}}\" يمكنك إدارة الاشتراك عبر Stripe.",
|
||||
"qa.list.management.q": "كيف أغير أو ألغي اشتراكي؟",
|
||||
"qa.support.community": "دعم المجتمع",
|
||||
"qa.support.email": "دعم عبر البريد الإلكتروني",
|
||||
"qa.title": "الأسئلة الشائعة",
|
||||
"recurring.day": "يوميًا",
|
||||
"recurring.fullYear": "سنة كاملة",
|
||||
"recurring.monthly": "فواتير شهرية",
|
||||
"recurring.oneMonth": "شهر واحد",
|
||||
"recurring.oneYear": "سنة واحدة",
|
||||
"recurring.payonce": "دفع لمرة واحدة",
|
||||
"recurring.perMonth": "شهريًا",
|
||||
"recurring.perYear": "سنويًا",
|
||||
"recurring.sixMonth": "ستة أشهر",
|
||||
"recurring.threeMonth": "ثلاثة أشهر",
|
||||
"recurring.title": "دورة الفوترة",
|
||||
"recurring.yearly": "فواتير سنوية",
|
||||
"referral.copy.codeSuccess": "تم نسخ رمز الإحالة",
|
||||
"referral.copy.linkSuccess": "تم نسخ رابط الإحالة",
|
||||
"referral.edit.button": "تعديل",
|
||||
"referral.edit.cancel": "إلغاء",
|
||||
"referral.edit.hint": "يدعم 2-8 أحرف أو أرقام أو شرطات سفلية",
|
||||
"referral.edit.placeholder": "أدخل رمز الإحالة",
|
||||
"referral.edit.save": "حفظ",
|
||||
"referral.errors.alreadyBound": "لقد قمت بربط رمز الدعوة مسبقًا",
|
||||
"referral.errors.backfillExpired": "انتهت فترة الإكمال. لا يمكن الإكمال بعد 3 أيام من التسجيل",
|
||||
"referral.errors.codeExists": "رمز الإحالة مستخدم بالفعل، يرجى اختيار رمز آخر",
|
||||
"referral.errors.invalidCode": "رمز الدعوة غير موجود، يرجى التحقق والمحاولة مرة أخرى",
|
||||
"referral.errors.invalidFormat": "تنسيق رمز الإحالة غير صالح، يرجى إدخال 2-8 أحرف أو أرقام أو شرطات سفلية",
|
||||
"referral.errors.selfReferral": "لا يمكنك استخدام رمز الدعوة الخاص بك",
|
||||
"referral.errors.updateFailed": "فشل التحديث، يرجى المحاولة لاحقًا",
|
||||
"referral.inviteCode.description": "شارك رمز الإحالة الحصري الخاص بك لدعوة الأصدقاء للتسجيل",
|
||||
"referral.inviteCode.title": "رمز الإحالة الخاص بي",
|
||||
"referral.inviteLink.description": "انسخ الرابط وشاركه مع الأصدقاء. بعد التسجيل، ستحصل على مكافآت",
|
||||
"referral.inviteLink.title": "رابط الإحالة",
|
||||
"referral.rules.backfill.alreadyBound": "لقد قمت بربط رمز الدعوة مسبقًا",
|
||||
"referral.rules.backfill.description": "نسيت إدخال رمز الدعوة؟ يمكنك إكماله خلال 3 أيام من التسجيل",
|
||||
"referral.rules.backfill.expiredTip": "انتهت فترة الإكمال. لا يمكن الإكمال بعد 3 أيام من التسجيل",
|
||||
"referral.rules.backfill.link": "إكمال رمز الدعوة",
|
||||
"referral.rules.backfill.placeholder": "أدخل رمز الدعوة",
|
||||
"referral.rules.backfill.submit": "تأكيد الربط",
|
||||
"referral.rules.backfill.success": "تم ربط رمز الدعوة بنجاح",
|
||||
"referral.rules.backfill.title": "إكمال رمز الدعوة",
|
||||
"referral.rules.description": "تعرف على قواعد برنامج مكافآت الإحالة",
|
||||
"referral.rules.expiry": "صلاحية الرصيد: يتم مسح أرصدة الإحالة بعد 100 يوم من عدم النشاط",
|
||||
"referral.rules.missedCode": "فاتك إدخال رمز الدعوة: يمكنك <0>إكماله</0> خلال 3 أيام من التسجيل",
|
||||
"referral.rules.priority": "أولوية استهلاك الرصيد: الرصيد المجاني → رصيد الاشتراك → رصيد الإحالة → الرصيد المشحون",
|
||||
"referral.rules.registration": "طريقة التسجيل: يسجل المستخدمون المدعوون عبر رابط الإحالة أو بإدخال الرمز عند التسجيل",
|
||||
"referral.rules.reward": "المكافأة: يحصل كل من الداعي والمدعو على {{reward}}M رصيد",
|
||||
"referral.rules.title": "قواعد البرنامج",
|
||||
"referral.rules.validInvitation": "دعوة صالحة: يسجل المدعو باستخدام رمز الإحالة ويقوم بإجراء صالح واحد",
|
||||
"referral.rules.validOperation": "معايير الإجراء الصالح: إرسال رسالة واحدة أو إنشاء صورة واحدة",
|
||||
"referral.stats.availableBalance": "الرصيد المتاح",
|
||||
"referral.stats.description": "عرض إحصائيات الإحالة الخاصة بك",
|
||||
"referral.stats.title": "نظرة عامة على الإحالة",
|
||||
"referral.stats.totalInvites": "إجمالي الدعوات",
|
||||
"referral.stats.totalRewarded": "التحويلات الصالحة",
|
||||
"referral.stats.totalRewardedAmount": "إجمالي الأرباح",
|
||||
"referral.table.columns.createdAt": "وقت التسجيل",
|
||||
"referral.table.columns.inviteeEmail": "بريد المدعو",
|
||||
"referral.table.columns.inviterRewardAmount": "مكافأتي",
|
||||
"referral.table.columns.rewardedAt": "وقت المكافأة",
|
||||
"referral.table.columns.status": "الحالة",
|
||||
"referral.table.columns.suspectedReason": "سبب الشك",
|
||||
"referral.table.status.registered": "مسجل",
|
||||
"referral.table.status.revoked": "تم الإلغاء",
|
||||
"referral.table.status.rewarded": "تمت المكافأة",
|
||||
"referral.table.status.suspected": "يشتبه في وجود خلل",
|
||||
"referral.table.title": "سجل الإحالات",
|
||||
"sessionCard.title": "هل ترغب في مغادرة الخطة المجانية؟ قم بالترقية للاستمتاع بالميزات المميزة.",
|
||||
"summary.desc": "يشمل هذا المبلغ فقط نفقات خدمة الاشتراك.",
|
||||
"summary.dueBy": "مستحق في {{date}}",
|
||||
"summary.nextPayment": "الدفعة التالية",
|
||||
"summary.paymentInformation": "معلومات الفوترة",
|
||||
"summary.title": "ملخص الفوترة",
|
||||
"summary.usageThisMonth": "عرض استخدامك هذا الشهر.",
|
||||
"summary.viewBillingHistory": "عرض سجل المدفوعات",
|
||||
"switchPlan": "تبديل الخطة",
|
||||
"switchToMonthly.desc": "بعد التبديل، ستبدأ الفوترة الشهرية بعد انتهاء الخطة السنوية الحالية.",
|
||||
"switchToMonthly.title": "التبديل إلى الفوترة الشهرية",
|
||||
"switchToYearly.desc": "بعد التبديل، ستبدأ الفوترة السنوية فور دفع الفرق. تاريخ البدء يستمر من الخطة السابقة.",
|
||||
"switchToYearly.title": "التبديل إلى الفوترة السنوية",
|
||||
"tab.billing": "إدارة الفوترة",
|
||||
"tab.funds": "إدارة الأرصدة",
|
||||
"tab.plans": "خطط الاشتراك",
|
||||
"tab.referral": "مكافآت الإحالة",
|
||||
"tab.spend": "تفاصيل الأرصدة",
|
||||
"tab.usage": "إحصائيات الاستخدام",
|
||||
"upgrade": "ترقية",
|
||||
"upgradeNow": "قم بالترقية الآن",
|
||||
"upgradePlan": "ترقية الخطة",
|
||||
"upgradePlans.desc": "تسري ترقية الخطة فورًا بعد دفع الفرق. تاريخ البدء يستمر من الخطة السابقة.",
|
||||
"upgradePlans.title": "الترقية إلى {{plan}}",
|
||||
"usage.credit.addon.desc": "يتم إعادة تعيين الحصة في {{time}}",
|
||||
"usage.credit.addon.used": "أرصدة مشحونة",
|
||||
"usage.credit.desc": "استخدام الأرصدة للدردشة، توليد الصور، تحويل النص إلى كلام",
|
||||
"usage.credit.detail": "إحصائيات الاستخدام لآخر {{day}} يومًا",
|
||||
"usage.credit.free.desc": "يتم إعادة تعيين الحصة في {{time}}",
|
||||
"usage.credit.free.expired": "انتهت في {{date}}",
|
||||
"usage.credit.free.used": "أرصدة مجانية",
|
||||
"usage.credit.referral.desc": "أرصدة المكافآت من دعوة الأصدقاء",
|
||||
"usage.credit.referral.used": "أرصدة الإحالة",
|
||||
"usage.credit.subscription.desc": "يتم إعادة تعيين الحصة في {{time}}",
|
||||
"usage.credit.subscription.used": "أرصدة الاشتراك",
|
||||
"usage.credit.time.days": "{{days}} يومًا",
|
||||
"usage.credit.time.daysAndHours": "{{days}} يومًا و{{hours}} ساعة",
|
||||
"usage.credit.time.hours": "{{hours}} ساعة",
|
||||
"usage.credit.title": "استخدام أرصدة الحوسبة",
|
||||
"usage.overview.charge": "الرسوم",
|
||||
"usage.overview.included": "استخدام الخطة",
|
||||
"usage.overview.onDemand": "حسب الطلب",
|
||||
"usage.overview.product": "عنصر المنتج",
|
||||
"usage.overview.title": "نظرة عامة على الاستخدام",
|
||||
"usage.storage.desc": "يمكن تحرير تخزين البيانات يدويًا",
|
||||
"usage.storage.embeddings.used": "تخزين المتجهات",
|
||||
"usage.storage.file.used": "استخدام الملفات",
|
||||
"usage.storage.title": "تخزين البيانات",
|
||||
"usage.title": "استخدام هذا الشهر",
|
||||
"usage.used": "تم الاستخدام",
|
||||
"zarinpal.infoModal.desc": "بسبب المتطلبات التنظيمية، يرجى إكمال المعلومات الشخصية التالية قبل تقديم الطلب:",
|
||||
"zarinpal.infoModal.phone.label": "رقم الهاتف",
|
||||
"zarinpal.infoModal.phone.placeholder": "يرجى إدخال رقم الهاتف",
|
||||
"zarinpal.infoModal.phone.rule": "يرجى إدخال رقم هاتف صالح",
|
||||
"zarinpal.infoModal.submit": "شراء",
|
||||
"zarinpal.infoModal.title": "املأ المعلومات المطلوبة"
|
||||
"plans.plan.enterprise.title": "النسخة التجارية",
|
||||
"plans.plan.free.title": "النسخة المجانية",
|
||||
"plans.plan.hobby.title": "نسخة الخدمة الذاتية",
|
||||
"plans.plan.premium.title": "النسخة المتقدمة",
|
||||
"plans.plan.starter.title": "النسخة الأساسية",
|
||||
"plans.plan.ultimate.title": "النسخة الاحترافية"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"actions.confirmRemoveThread": "أنت على وشك حذف هذا الموضوع الفرعي. بمجرد حذفه، لا يمكن استعادته. يرجى المتابعة بحذر.",
|
||||
"actions.confirmRemoveThread": "سيتم حذف هذا الموضوع الفرعي، ولن يمكن استعادته بعد الحذف، يرجى توخي الحذر.",
|
||||
"newPortalThread.includeContext": "تضمين سياق الموضوع",
|
||||
"newPortalThread.title": "ابدأ موضوعًا فرعيًا جديدًا",
|
||||
"notSupportMultiModals": "المواضيع الفرعية لا تدعم حاليًا تحميل الملفات أو الصور. إذا كانت لديك أي طلبات، لا تتردد في ترك رسالة: <1>💬 منطقة النقاش</1>"
|
||||
"newPortalThread.title": "فتح موضوع فرعي جديد",
|
||||
"notSupportMultiModals": "الموضوعات الفرعية لا تدعم حاليًا تحميل الملفات/الصور، إذا كان لديك أي طلب، لا تتردد في ترك رسالة: <1>💬 قسم النقاش</1>"
|
||||
}
|
||||
|
||||
+72
-84
@@ -1,122 +1,110 @@
|
||||
{
|
||||
"agentGroupManagement.executeTask.agent": "تنفيذ الوكيل",
|
||||
"agentGroupManagement.executeTask.cancelled": "تم الإلغاء",
|
||||
"agentGroupManagement.executeTask.completed": "اكتمل التنفيذ",
|
||||
"agentGroupManagement.executeTask.completed": "اكتمل المهمة",
|
||||
"agentGroupManagement.executeTask.cost": "التكلفة",
|
||||
"agentGroupManagement.executeTask.failed": "فشل التنفيذ",
|
||||
"agentGroupManagement.executeTask.failed": "فشل المهمة",
|
||||
"agentGroupManagement.executeTask.interrupted": "تمت المقاطعة",
|
||||
"agentGroupManagement.executeTask.intervention.taskPlaceholder": "يرجى تقديم وصف مفصل للمهمة التي سيقوم بها الوكيل...",
|
||||
"agentGroupManagement.executeTask.intervention.taskPlaceholder": "يرجى وصف المهمة التي يحتاج الوكيل إلى تنفيذها بالتفصيل...",
|
||||
"agentGroupManagement.executeTask.intervention.timeout": "الحد الأقصى لمدة التنفيذ",
|
||||
"agentGroupManagement.executeTask.intervention.timeoutUnit": "دقائق",
|
||||
"agentGroupManagement.executeTask.intervention.unknownAgent": "وكيل غير معروف",
|
||||
"agentGroupManagement.executeTask.processing": "جارٍ المعالجة...",
|
||||
"agentGroupManagement.executeTask.steps": "خطوات التنفيذ",
|
||||
"agentGroupManagement.executeTask.processing": "جارٍ التنفيذ...",
|
||||
"agentGroupManagement.executeTask.steps": "عدد خطوات التنفيذ",
|
||||
"agentGroupManagement.executeTask.task": "محتوى المهمة",
|
||||
"agentGroupManagement.executeTask.thread": "معرّف السلسلة",
|
||||
"agentGroupManagement.executeTask.timeout": "انتهت مدة التنفيذ",
|
||||
"agentGroupManagement.executeTask.tokens": "استخدام الرموز",
|
||||
"agentGroupManagement.executeTask.thread": "معرّف الخيط",
|
||||
"agentGroupManagement.executeTask.timeout": "انتهت مهلة التنفيذ",
|
||||
"agentGroupManagement.executeTask.tokens": "استهلاك الرموز",
|
||||
"codeInterpreter-legacy.error": "خطأ في التنفيذ",
|
||||
"codeInterpreter-legacy.executing": "جارٍ التنفيذ...",
|
||||
"codeInterpreter-legacy.files": "الملفات:",
|
||||
"codeInterpreter-legacy.output": "الناتج:",
|
||||
"codeInterpreter-legacy.returnValue": "القيمة المرجعة:",
|
||||
"codeInterpreter-legacy.output": "المخرجات:",
|
||||
"codeInterpreter-legacy.returnValue": "قيمة الإرجاع:",
|
||||
"codeInterpreter.error": "خطأ في التنفيذ",
|
||||
"codeInterpreter.executing": "جارٍ التنفيذ...",
|
||||
"codeInterpreter.files": "الملفات:",
|
||||
"codeInterpreter.output": "الناتج:",
|
||||
"codeInterpreter.returnValue": "القيمة المرجعة:",
|
||||
"codeInterpreter.output": "الإخراج:",
|
||||
"codeInterpreter.returnValue": "قيمة الإرجاع:",
|
||||
"dalle.autoGenerate": "توليد تلقائي",
|
||||
"dalle.downloading": "روابط الصور التي تم إنشاؤها بواسطة DALL·E3 صالحة لمدة ساعة واحدة فقط، يتم تخزين الصور محليًا...",
|
||||
"dalle.downloading": "صلاحية روابط الصور المُولَّدة بواسطة DallE3 تدوم ساعة واحدة فقط، يتم تحميل الصور إلى الجهاز المحلي...",
|
||||
"dalle.generate": "توليد",
|
||||
"dalle.generating": "جارٍ التوليد...",
|
||||
"dalle.images": "الصور:",
|
||||
"dalle.prompt": "الموجه",
|
||||
"dalle.prompt": "كلمة تلميح",
|
||||
"lobe-gtd.actions.add": "إضافة",
|
||||
"lobe-gtd.actions.clearCompleted": "مسح المكتملة",
|
||||
"lobe-gtd.actions.placeholder": "أدخل مهمة...",
|
||||
"lobe-gtd.addTodo.placeholder": "أضف مهمة...",
|
||||
"lobe-gtd.clearTodos.cleared": "تم مسح {{count}} عنصر(عناصر)",
|
||||
"lobe-gtd.clearTodos.clearedCompleted": "تم مسح {{count}} عنصر(عناصر) مكتملة",
|
||||
"lobe-gtd.clearTodos.clearedCompleted_one": "تم مسح عنصر مكتمل واحد",
|
||||
"lobe-gtd.clearTodos.clearedCompleted_other": "تم مسح {{count}} عناصر مكتملة",
|
||||
"lobe-gtd.clearTodos.cleared_one": "تم مسح عنصر واحد",
|
||||
"lobe-gtd.clearTodos.cleared_other": "تم مسح {{count}} عناصر",
|
||||
"lobe-gtd.clearTodos.header": "مسح المهام",
|
||||
"lobe-gtd.clearTodos.label": "اختر ما تريد مسحه:",
|
||||
"lobe-gtd.actions.clearCompleted": "مسح المكتمل",
|
||||
"lobe-gtd.actions.placeholder": "أدخل مهمة للقيام بها...",
|
||||
"lobe-gtd.clearTodos.cleared": "تم مسح {{count}} عنصرًا",
|
||||
"lobe-gtd.clearTodos.clearedCompleted": "تم مسح {{count}} من العناصر المكتملة",
|
||||
"lobe-gtd.clearTodos.clearedCompleted_one": "تم مسح {{count}} من العناصر المكتملة",
|
||||
"lobe-gtd.clearTodos.clearedCompleted_other": "تم مسح {{count}} من العناصر المكتملة",
|
||||
"lobe-gtd.clearTodos.cleared_one": "تم مسح {{count}} عنصرًا",
|
||||
"lobe-gtd.clearTodos.cleared_other": "تم مسح {{count}} عنصرًا",
|
||||
"lobe-gtd.clearTodos.noItems": "لا توجد عناصر للمسح",
|
||||
"lobe-gtd.clearTodos.option.all": "مسح جميع العناصر (بما في ذلك المعلقة)",
|
||||
"lobe-gtd.clearTodos.option.completed": "مسح العناصر المكتملة فقط",
|
||||
"lobe-gtd.clearTodos.remaining": "{{count}} عنصر(عناصر) متبقية",
|
||||
"lobe-gtd.clearTodos.remaining_one": "عنصر واحد متبقٍ",
|
||||
"lobe-gtd.clearTodos.remaining_other": "{{count}} عناصر متبقية",
|
||||
"lobe-gtd.completeTodos.completed": "تم إكمال {{count}} عنصر(عناصر)",
|
||||
"lobe-gtd.completeTodos.completed_one": "تم إكمال عنصر واحد",
|
||||
"lobe-gtd.completeTodos.completed_other": "تم إكمال {{count}} عناصر",
|
||||
"lobe-gtd.createPlan.context.label": "السياق (اختياري)",
|
||||
"lobe-gtd.createPlan.context.placeholder": "الخلفية، القيود، الاعتبارات...",
|
||||
"lobe-gtd.createPlan.description.label": "الوصف",
|
||||
"lobe-gtd.createPlan.description.placeholder": "ملخص مختصر للخطة",
|
||||
"lobe-gtd.createPlan.goal.label": "الهدف",
|
||||
"lobe-gtd.createPlan.goal.placeholder": "ما الذي تريد تحقيقه؟",
|
||||
"lobe-gtd.clearTodos.remaining": "تبقّى {{count}} عنصرًا",
|
||||
"lobe-gtd.clearTodos.remaining_one": "تبقّى {{count}} عنصرًا",
|
||||
"lobe-gtd.clearTodos.remaining_other": "تبقّى {{count}} عنصرًا",
|
||||
"lobe-gtd.completeTodos.completed": "تم إكمال {{count}} عنصرًا",
|
||||
"lobe-gtd.completeTodos.completed_one": "تم إكمال {{count}} عنصرًا",
|
||||
"lobe-gtd.completeTodos.completed_other": "تم إكمال {{count}} عنصرًا",
|
||||
"lobe-gtd.createTodos.created": "تم إنشاء {{count}} مهمة",
|
||||
"lobe-gtd.createTodos.created_one": "تم إنشاء مهمة واحدة",
|
||||
"lobe-gtd.createTodos.created_other": "تم إنشاء {{count}} مهام",
|
||||
"lobe-gtd.createTodos.total": "الإجمالي: {{count}} عنصر(عناصر)",
|
||||
"lobe-gtd.createTodos.total_one": "الإجمالي: عنصر واحد",
|
||||
"lobe-gtd.createTodos.total_other": "الإجمالي: {{count}} عناصر",
|
||||
"lobe-gtd.removeTodos.removed": "تمت إزالة {{count}} عنصر(عناصر)",
|
||||
"lobe-gtd.removeTodos.removed_one": "تمت إزالة عنصر واحد",
|
||||
"lobe-gtd.removeTodos.removed_other": "تمت إزالة {{count}} عناصر",
|
||||
"lobe-gtd.status.done": "{{count}} مكتملة",
|
||||
"lobe-gtd.status.pending": "{{count}} معلقة",
|
||||
"lobe-gtd.todoItem.placeholder": "أدخل مهمة...",
|
||||
"lobe-gtd.createTodos.created_one": "تم إنشاء {{count}} مهمة",
|
||||
"lobe-gtd.createTodos.created_other": "تم إنشاء {{count}} مهمة",
|
||||
"lobe-gtd.createTodos.total": "المجموع: {{count}} عنصرًا",
|
||||
"lobe-gtd.createTodos.total_one": "المجموع: {{count}} عنصرًا",
|
||||
"lobe-gtd.createTodos.total_other": "المجموع: {{count}} عنصرًا",
|
||||
"lobe-gtd.removeTodos.removed": "تم حذف {{count}} عنصرًا",
|
||||
"lobe-gtd.removeTodos.removed_one": "تم حذف {{count}} عنصرًا",
|
||||
"lobe-gtd.removeTodos.removed_other": "تم حذف {{count}} عنصرًا",
|
||||
"lobe-gtd.status.done": "{{count}} مكتمل",
|
||||
"lobe-gtd.status.pending": "{{count}} قيد الانتظار",
|
||||
"lobe-gtd.todoList.empty": "قائمة المهام فارغة",
|
||||
"lobe-gtd.todoList.items": "{{count}} عنصر(عناصر)",
|
||||
"lobe-gtd.todoList.items_one": "عنصر واحد",
|
||||
"lobe-gtd.todoList.items_other": "{{count}} عناصر",
|
||||
"lobe-gtd.todoList.items": "{{count}} عنصرًا",
|
||||
"lobe-gtd.todoList.items_one": "{{count}} عنصرًا",
|
||||
"lobe-gtd.todoList.items_other": "{{count}} عنصرًا",
|
||||
"lobe-gtd.todoList.title": "قائمة المهام",
|
||||
"lobe-gtd.updateTodos.updated": "تم تحديث قائمة المهام",
|
||||
"lobe-knowledge-base.readKnowledge.meta.chars": "عدد الأحرف",
|
||||
"lobe-knowledge-base.readKnowledge.meta.lines": "عدد الأسطر",
|
||||
"lobe-knowledge-base.readKnowledge.meta.lines": "عدد السطور",
|
||||
"localFiles.editFile.newString": "استبدال بـ",
|
||||
"localFiles.editFile.oldString": "بحث عن",
|
||||
"localFiles.editFile.replaceAll": "استبدال جميع التكرارات",
|
||||
"localFiles.editFile.replaceFirst": "استبدال التكرار الأول فقط",
|
||||
"localFiles.editFile.oldString": "البحث عن",
|
||||
"localFiles.editFile.replaceAll": "استبدال جميع المطابقات",
|
||||
"localFiles.editFile.replaceFirst": "استبدال أول مطابقة فقط",
|
||||
"localFiles.file": "ملف",
|
||||
"localFiles.folder": "مجلد",
|
||||
"localFiles.moveFiles.itemsMoved": "تم نقل {{count}} عنصر(عناصر):",
|
||||
"localFiles.moveFiles.itemsMoved_one": "تم نقل عنصر واحد:",
|
||||
"localFiles.moveFiles.itemsMoved_other": "تم نقل {{count}} عناصر:",
|
||||
"localFiles.moveFiles.itemsToMove": "{{count}} عنصر(عناصر) للنقل:",
|
||||
"localFiles.moveFiles.itemsToMove_one": "عنصر واحد للنقل:",
|
||||
"localFiles.moveFiles.itemsToMove_other": "{{count}} عناصر للنقل:",
|
||||
"localFiles.moveFiles.itemsMoved": "تم نقل {{count}} عنصر:",
|
||||
"localFiles.moveFiles.itemsMoved_one": "تم نقل {{count}} عنصر:",
|
||||
"localFiles.moveFiles.itemsMoved_other": "تم نقل {{count}} عنصر:",
|
||||
"localFiles.moveFiles.itemsToMove": "{{count}} عنصر في انتظار النقل:",
|
||||
"localFiles.moveFiles.itemsToMove_one": "{{count}} عنصر في انتظار النقل:",
|
||||
"localFiles.moveFiles.itemsToMove_other": "{{count}} عنصر في انتظار النقل:",
|
||||
"localFiles.open": "فتح",
|
||||
"localFiles.openFile": "فتح ملف",
|
||||
"localFiles.openFolder": "فتح مجلد",
|
||||
"localFiles.read.more": "عرض المزيد",
|
||||
"localFiles.readFile": "قراءة الملف",
|
||||
"localFiles.readFileError": "فشل في قراءة الملف، يرجى التحقق من صحة المسار",
|
||||
"localFiles.readFileError": "فشل في قراءة الملف، يرجى التحقق من صحة مسار الملف",
|
||||
"localFiles.readFiles": "قراءة الملفات",
|
||||
"localFiles.readFilesError": "فشل في قراءة الملفات، يرجى التحقق من صحة المسار",
|
||||
"localFiles.readFilesError": "فشل في قراءة الملفات، يرجى التحقق من صحة مسار الملف",
|
||||
"localFiles.writeFile.characters": "أحرف",
|
||||
"localFiles.writeFile.preview": "معاينة المحتوى",
|
||||
"localFiles.writeFile.truncated": "مقتطع",
|
||||
"localFiles.writeFile.truncated": "تم الاقتطاع",
|
||||
"search.createNewSearch": "إنشاء سجل بحث جديد",
|
||||
"search.emptyResult": "لم يتم العثور على نتائج، يرجى تعديل الكلمات المفتاحية والمحاولة مرة أخرى",
|
||||
"search.genAiMessage": "إنشاء رسالة وكيل",
|
||||
"search.includedTooltip": "سيتم تضمين نتائج البحث الحالية في سياق المحادثة",
|
||||
"search.keywords": "الكلمات المفتاحية:",
|
||||
"search.scoreTooltip": "درجة الصلة؛ تشير الدرجة الأعلى إلى تطابق أقرب مع الكلمات المفتاحية",
|
||||
"search.emptyResult": "لم يتم العثور على نتائج، يرجى تعديل الكلمات الرئيسية والمحاولة مرة أخرى",
|
||||
"search.genAiMessage": "إنشاء رسالة مساعد",
|
||||
"search.includedTooltip": "ستدخل نتائج البحث الحالية في سياق المحادثة",
|
||||
"search.keywords": "الكلمات الرئيسية:",
|
||||
"search.scoreTooltip": "درجة الصلة، كلما كانت هذه الدرجة أعلى، كانت أكثر ارتباطًا بكلمات البحث",
|
||||
"search.searchBar.button": "بحث",
|
||||
"search.searchBar.placeholder": "كلمات مفتاحية",
|
||||
"search.searchBar.tooltip": "سيؤدي هذا إلى تحديث نتائج البحث وإنشاء رسالة ملخص جديدة",
|
||||
"search.searchCategory.placeholder": "فئة البحث",
|
||||
"search.searchBar.placeholder": "الكلمات الرئيسية",
|
||||
"search.searchBar.tooltip": "سيتم إعادة الحصول على نتائج البحث، وإنشاء رسالة ملخص جديدة",
|
||||
"search.searchCategory.placeholder": "ابحث عن الفئة",
|
||||
"search.searchCategory.title": "فئة البحث:",
|
||||
"search.searchCategory.value.files": "ملفات",
|
||||
"search.searchCategory.value.general": "عام",
|
||||
"search.searchCategory.value.images": "صور",
|
||||
"search.searchCategory.value.it": "تكنولوجيا المعلومات",
|
||||
"search.searchCategory.value.map": "خرائط",
|
||||
"search.searchCategory.value.map": "خريطة",
|
||||
"search.searchCategory.value.music": "موسيقى",
|
||||
"search.searchCategory.value.news": "أخبار",
|
||||
"search.searchCategory.value.science": "علوم",
|
||||
@@ -124,21 +112,21 @@
|
||||
"search.searchCategory.value.videos": "فيديوهات",
|
||||
"search.searchEngine.placeholder": "محرك البحث",
|
||||
"search.searchEngine.title": "محرك البحث:",
|
||||
"search.searchResult": "عدد عمليات البحث:",
|
||||
"search.searchTimeRange.title": "النطاق الزمني:",
|
||||
"search.searchResult": "عدد النتائج:",
|
||||
"search.searchTimeRange.title": "نطاق الوقت:",
|
||||
"search.searchTimeRange.value.anytime": "في أي وقت",
|
||||
"search.searchTimeRange.value.day": "خلال يوم",
|
||||
"search.searchTimeRange.value.month": "خلال شهر",
|
||||
"search.searchTimeRange.value.week": "خلال أسبوع",
|
||||
"search.searchTimeRange.value.year": "خلال سنة",
|
||||
"search.summary": "الملخص",
|
||||
"search.searchTimeRange.value.day": "خلال يوم واحد",
|
||||
"search.searchTimeRange.value.month": "خلال شهر واحد",
|
||||
"search.searchTimeRange.value.week": "خلال أسبوع واحد",
|
||||
"search.searchTimeRange.value.year": "خلال سنة واحدة",
|
||||
"search.summary": "ملخص",
|
||||
"search.summaryTooltip": "تلخيص المحتوى الحالي",
|
||||
"search.viewMoreResults": "عرض {{results}} نتيجة إضافية",
|
||||
"search.viewMoreResults": "عرض المزيد من {{results}} نتيجة",
|
||||
"updateArgs.duplicateKeyError": "يجب أن يكون مفتاح الحقل فريدًا",
|
||||
"updateArgs.form.add": "إضافة عنصر",
|
||||
"updateArgs.form.key": "مفتاح الحقل",
|
||||
"updateArgs.form.value": "قيمة الحقل",
|
||||
"updateArgs.formValidationFailed": "فشل التحقق من صحة النموذج، يرجى التحقق من تنسيق المعلمات",
|
||||
"updateArgs.keyRequired": "لا يمكن أن يكون مفتاح الحقل فارغًا",
|
||||
"updateArgs.stringifyError": "تعذر تحويل المعلمات إلى سلسلة، يرجى التحقق من تنسيق المعلمات"
|
||||
"updateArgs.stringifyError": "تعذر تسلسل المعلمات، يرجى التحقق من تنسيق المعلمات"
|
||||
}
|
||||
|
||||
+16
-16
@@ -1,37 +1,37 @@
|
||||
{
|
||||
"actions.addNewTopic": "ابدأ موضوعًا جديدًا",
|
||||
"actions.autoRename": "إعادة تسمية ذكية",
|
||||
"actions.confirmRemoveAll": "أنت على وشك حذف جميع المواضيع. لا يمكن التراجع عن هذا الإجراء.",
|
||||
"actions.confirmRemoveTopic": "أنت على وشك حذف هذا الموضوع. لا يمكن التراجع عن هذا الإجراء.",
|
||||
"actions.confirmRemoveUnstarred": "أنت على وشك حذف المواضيع غير المميزة. لا يمكن التراجع عن هذا الإجراء.",
|
||||
"actions.duplicate": "نسخ",
|
||||
"actions.export": "تصدير المواضيع",
|
||||
"actions.confirmRemoveAll": "سيتم حذف جميع المواضيع، ولن يمكن استعادتها بعد الحذف، يرجى توخي الحذر.",
|
||||
"actions.confirmRemoveTopic": "سيتم حذف هذا الموضوع، ولن يمكن استعادته بعد الحذف، يرجى توخي الحذر.",
|
||||
"actions.confirmRemoveUnstarred": "سيتم حذف المواضيع غير المفضلة، ولن يمكن استعادتها بعد الحذف، يرجى توخي الحذر.",
|
||||
"actions.duplicate": "إنشاء نسخة",
|
||||
"actions.export": "تصدير الموضوع",
|
||||
"actions.import": "استيراد المحادثة",
|
||||
"actions.openInNewWindow": "فتح في نافذة جديدة",
|
||||
"actions.openInNewWindow": "افتح في نافذة مستقلة",
|
||||
"actions.removeAll": "حذف جميع المواضيع",
|
||||
"actions.removeUnstarred": "حذف المواضيع غير المميزة",
|
||||
"actions.removeUnstarred": "حذف المواضيع غير المفضلة",
|
||||
"defaultTitle": "موضوع افتراضي",
|
||||
"displayItems": "عرض العناصر",
|
||||
"duplicateLoading": "جارٍ نسخ الموضوع...",
|
||||
"duplicateLoading": "يتم نسخ الموضوع...",
|
||||
"duplicateSuccess": "تم نسخ الموضوع بنجاح",
|
||||
"favorite": "مفضل",
|
||||
"groupMode.ascMessages": "ترتيب حسب عدد الرسائل تصاعديًا",
|
||||
"groupMode.ascMessages": "ترتيب حسب إجمالي عدد الرسائل",
|
||||
"groupMode.byTime": "تجميع حسب الوقت",
|
||||
"groupMode.descMessages": "ترتيب حسب عدد الرسائل تنازليًا",
|
||||
"groupMode.descMessages": "ترتيب عكسي حسب إجمالي عدد الرسائل",
|
||||
"groupMode.flat": "بدون تجميع",
|
||||
"groupTitle.byTime.month": "هذا الشهر",
|
||||
"groupTitle.byTime.today": "اليوم",
|
||||
"groupTitle.byTime.week": "هذا الأسبوع",
|
||||
"groupTitle.byTime.yesterday": "أمس",
|
||||
"guide.desc": "انقر على الزر في اليسار لحفظ المحادثة الحالية كموضوع محفوظ وبدء محادثة جديدة.",
|
||||
"guide.desc": "انقر على زر الإرسال على اليسار لحفظ المحادثة الحالية كموضوع تاريخي وبدء جولة جديدة من المحادثة",
|
||||
"guide.title": "قائمة المواضيع",
|
||||
"importError": "فشل في الاستيراد",
|
||||
"importInvalidFormat": "تنسيق الملف غير صالح. يرجى التأكد من أنه ملف JSON صالح.",
|
||||
"importInvalidFormat": "تنسيق الملف غير صالح، يرجى التأكد من أنه ملف JSON صالح",
|
||||
"importLoading": "جارٍ استيراد المحادثة...",
|
||||
"importSuccess": "تم استيراد {{count}} رسالة بنجاح",
|
||||
"loadMore": "تحميل المزيد",
|
||||
"searchPlaceholder": "ابحث في المواضيع...",
|
||||
"searchResultEmpty": "لم يتم العثور على نتائج.",
|
||||
"loadMore": "المزيد",
|
||||
"searchPlaceholder": "ابحث عن موضوع...",
|
||||
"searchResultEmpty": "لا توجد نتائج للبحث",
|
||||
"temp": "مؤقت",
|
||||
"title": "الموضوع"
|
||||
"title": "موضوع"
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"chat": {
|
||||
"chat.avatar": "الصورة الرمزية",
|
||||
"chat.placeholder": "...",
|
||||
"tokenTag.overload": "زيادة التحميل",
|
||||
"tokenTag.remained": "المتبقي",
|
||||
"tokenTag.used": "المستخدم"
|
||||
},
|
||||
"common": {
|
||||
"common.cancel": "إلغاء",
|
||||
"common.confirm": "تأكيد",
|
||||
"common.delete": "حذف",
|
||||
"common.edit": "تعديل"
|
||||
},
|
||||
"editableMessage": {
|
||||
"editableMessage.addProps": "إضافة خصائص",
|
||||
"editableMessage.delete": "حذف",
|
||||
"editableMessage.input": "المدخلات",
|
||||
"editableMessage.inputPlaceholder": "يرجى إدخال محتوى مدخلات تجريبي",
|
||||
"editableMessage.output": "المخرجات",
|
||||
"editableMessage.outputPlaceholder": "يرجى إدخال محتوى مخرجات تجريبي",
|
||||
"editableMessage.system": "النظام"
|
||||
},
|
||||
"emojiPicker": {
|
||||
"emojiPicker.delete": "حذف",
|
||||
"emojiPicker.draggerDesc": "انقر أو اسحب الصورة إلى هذه المنطقة للتحميل",
|
||||
"emojiPicker.emoji": "رموز تعبيرية",
|
||||
"emojiPicker.fileTypeError": "يمكنك تحميل ملفات الصور فقط!",
|
||||
"emojiPicker.upload": "تحميل",
|
||||
"emojiPicker.uploadBtn": "قص وتحميل"
|
||||
},
|
||||
"form": {
|
||||
"form.reset": "إعادة تعيين",
|
||||
"form.submit": "إرسال",
|
||||
"form.unsavedChanges": "تغييرات غير محفوظة",
|
||||
"form.unsavedWarning": "لديك تغييرات غير محفوظة. هل أنت متأكد أنك تريد المغادرة؟"
|
||||
},
|
||||
"hotkey": {
|
||||
"hotkey.conflict": "هذا الاختصار يتعارض مع اختصار موجود.",
|
||||
"hotkey.invalidCombination": "يجب أن يتضمن الاختصار مفتاح تعديل (Ctrl أو Alt أو Shift) ومفتاح عادي واحد فقط.",
|
||||
"hotkey.placeholder": "اضغط على المفاتيح لتسجيل الاختصار",
|
||||
"hotkey.reset": "إعادة التعيين إلى الوضع الافتراضي"
|
||||
},
|
||||
"messageModal": {
|
||||
"messageModal.cancel": "إلغاء",
|
||||
"messageModal.confirm": "تأكيد",
|
||||
"messageModal.edit": "تعديل"
|
||||
},
|
||||
"sideNav": {
|
||||
"sideNav.collapse": "طي الشريط الجانبي",
|
||||
"sideNav.demoActiveLabel": "نشط",
|
||||
"sideNav.demoFeatureAutoCollapseDesc": "اسحب أسفل العتبة للطي الذكي",
|
||||
"sideNav.demoFeatureAutoCollapseTitle": "الطي التلقائي",
|
||||
"sideNav.demoFeaturePerformanceDesc": "بدون رسوم متحركة لأداء أفضل",
|
||||
"sideNav.demoFeaturePerformanceTitle": "الأداء",
|
||||
"sideNav.demoFeatureResizeDesc": "اسحب لتعديل عرض اللوحة",
|
||||
"sideNav.demoFeatureResizeTitle": "تعديل مرن",
|
||||
"sideNav.demoFeatureSmartHandleDesc": "مرر لإظهار زر التبديل",
|
||||
"sideNav.demoFeatureSmartHandleTitle": "مقبض ذكي",
|
||||
"sideNav.demoFeaturesTitle": "الميزات",
|
||||
"sideNav.demoHint": "جرّب سحب حافة اللوحة واستخدام زر التبديل ->",
|
||||
"sideNav.demoSubtitle": "لوحة جانبية بأسلوب مساحة العمل مع إمكانية تغيير الحجم بالسحب",
|
||||
"sideNav.demoTitle": "عرض توضيحي لـ DraggableSideNav",
|
||||
"sideNav.expand": "توسيع الشريط الجانبي"
|
||||
}
|
||||
}
|
||||
+134
-134
@@ -1,261 +1,261 @@
|
||||
{
|
||||
"guide.agents.replaceBtn": "تحديث",
|
||||
"guide.agents.title": "توصيات الوكلاء الجدد:",
|
||||
"guide.defaultMessage": "أنا وكيلك {{appName}}. ابدأ بأي فكرة.<br />تحتاج إلى وكيل أكثر تخصصًا؟ انقر على <plus /> لإنشاء واحد.",
|
||||
"guide.defaultMessageWithoutCreate": "مرحبًا بك في {{appName}}. جملة واحدة تكفي—فقط حدد هدفك.",
|
||||
"guide.groupActivities.analysis.codeReview.description": "مناقشات تقنية ومراجعات جماعية لتغييرات وتنفيذات الشيفرة",
|
||||
"guide.agents.replaceBtn": "تبديل مجموعة",
|
||||
"guide.agents.title": "مساعدون جدد مقترحون:",
|
||||
"guide.defaultMessage": "أنا مساعدك الذكي الشخصي {{appName}}، كيف يمكنني مساعدتك اليوم؟<br />إذا كنت بحاجة إلى مساعد أكثر تخصصًا أو مخصصًا، يمكنك النقر على <plus /> لإنشاء مساعد مخصص",
|
||||
"guide.defaultMessageWithoutCreate": "أنا مساعدك الذكي الشخصي {{appName}}، كيف يمكنني مساعدتك اليوم؟",
|
||||
"guide.groupActivities.analysis.codeReview.description": "مناقشة تقنية ومراجعة جماعية لتغييرات وتنفيذات الشيفرة",
|
||||
"guide.groupActivities.analysis.codeReview.emoji": "💻",
|
||||
"guide.groupActivities.analysis.codeReview.prompt": "دعنا نراجع بعض الشيفرات معًا. هل يمكنك مساعدتنا في تحليلها وتحديد مجالات التحسين؟",
|
||||
"guide.groupActivities.analysis.codeReview.title": "مراجعة الشيفرة",
|
||||
"guide.groupActivities.analysis.investment.description": "تحليل الأسواق، مناقشة استراتيجيات الاستثمار، ومشاركة الرؤى المالية",
|
||||
"guide.groupActivities.analysis.investment.description": "تحليل السوق، مناقشة استراتيجيات الاستثمار ومشاركة الرؤى المالية",
|
||||
"guide.groupActivities.analysis.investment.emoji": "📈",
|
||||
"guide.groupActivities.analysis.investment.prompt": "دعنا نحلل السوق معًا. هل يمكنك مساعدتنا في مناقشة الاستراتيجيات ومشاركة الرؤى؟",
|
||||
"guide.groupActivities.analysis.investment.title": "نادي الاستثمار",
|
||||
"guide.groupActivities.analysis.research.description": "استكشاف المفاهيم العلمية، إجراء التجارب، ومشاركة الاكتشافات",
|
||||
"guide.groupActivities.analysis.research.description": "استكشاف المفاهيم العلمية، إجراء التجارب ومشاركة الاكتشافات",
|
||||
"guide.groupActivities.analysis.research.emoji": "🔬",
|
||||
"guide.groupActivities.analysis.research.prompt": "دعنا نستكشف العلم معًا! هل يمكنك مساعدتنا في إجراء التجارب ومشاركة النتائج؟",
|
||||
"guide.groupActivities.analysis.research.prompt": "دعنا نستكشف العلوم معًا! هل يمكنك مساعدتنا في إجراء التجارب ومشاركة النتائج؟",
|
||||
"guide.groupActivities.analysis.research.title": "معرض العلوم",
|
||||
"guide.groupActivities.analysis.study.description": "جلسات دراسة تعاونية لمناقشة المفاهيم وحل المشكلات معًا",
|
||||
"guide.groupActivities.analysis.study.emoji": "📚",
|
||||
"guide.groupActivities.analysis.study.prompt": "دعنا نشكل مجموعة دراسة. هل يمكنك مساعدتنا في فهم هذه المفاهيم وحل المشكلات معًا؟",
|
||||
"guide.groupActivities.analysis.study.title": "مجموعة الدراسة",
|
||||
"guide.groupActivities.brainstorm.artWorkshop.description": "إنشاء، نقد، وتقدير أشكال الفن البصري والرقمي",
|
||||
"guide.groupActivities.analysis.study.prompt": "دعنا نشكل مجموعة دراسة. هل يمكنك مساعدتنا في فهم المفاهيم وحل المشكلات؟",
|
||||
"guide.groupActivities.analysis.study.title": "مجموعة دراسة",
|
||||
"guide.groupActivities.brainstorm.artWorkshop.description": "إنشاء، نقد وتقدير الفنون البصرية والرقمية بمختلف أشكالها",
|
||||
"guide.groupActivities.brainstorm.artWorkshop.emoji": "🖼️",
|
||||
"guide.groupActivities.brainstorm.artWorkshop.prompt": "دعنا نقيم ورشة فنية! هل يمكنك مساعدتنا في الإبداع، النقد، والاستمتاع بأشكال الفن المختلفة؟",
|
||||
"guide.groupActivities.brainstorm.artWorkshop.title": "ورشة الفن",
|
||||
"guide.groupActivities.brainstorm.debate.description": "مناقشات منظمة وجدالات حول مواضيع متنوعة وأحداث جارية",
|
||||
"guide.groupActivities.brainstorm.artWorkshop.prompt": "دعنا نقيم ورشة فنية! هل يمكنك مساعدتنا في الإبداع والنقد وتقدير الفنون؟",
|
||||
"guide.groupActivities.brainstorm.artWorkshop.title": "ورشة فنية",
|
||||
"guide.groupActivities.brainstorm.debate.description": "نقاشات منظمة وجدلية حول مواضيع مختلفة وقضايا راهنة",
|
||||
"guide.groupActivities.brainstorm.debate.emoji": "⚖️",
|
||||
"guide.groupActivities.brainstorm.debate.prompt": "دعنا نجري مناظرة منظمة. هل يمكنك مساعدتنا في تنظيم نقاش منطقي حول هذا الموضوع؟",
|
||||
"guide.groupActivities.brainstorm.debate.prompt": "دعنا نقيم مناظرة منظمة. هل يمكنك مساعدتنا في تنظيم نقاش منطقي حول هذا الموضوع؟",
|
||||
"guide.groupActivities.brainstorm.debate.title": "نادي المناظرة",
|
||||
"guide.groupActivities.brainstorm.designReview.description": "جلسات تغذية راجعة تعاونية حول مفاهيم التصميم والنماذج الأولية والأعمال الإبداعية",
|
||||
"guide.groupActivities.brainstorm.designReview.description": "جلسات تعاونية لتقديم الملاحظات على المفاهيم والنماذج الأولية والأعمال الإبداعية",
|
||||
"guide.groupActivities.brainstorm.designReview.emoji": "🎨",
|
||||
"guide.groupActivities.brainstorm.designReview.prompt": "نحتاج إلى مراجعة بعض التصاميم. هل يمكنك مساعدتنا في تقديم ملاحظات بناءة حول المفاهيم والنماذج؟",
|
||||
"guide.groupActivities.brainstorm.designReview.prompt": "نحتاج إلى مراجعة بعض التصاميم. هل يمكنك مساعدتنا في تقديم ملاحظات بناءة؟",
|
||||
"guide.groupActivities.brainstorm.designReview.title": "مراجعة التصميم",
|
||||
"guide.groupActivities.brainstorm.ideation.description": "توليد أفكار تعاوني وحل إبداعي للمشكلات من وجهات نظر متعددة",
|
||||
"guide.groupActivities.brainstorm.ideation.description": "توليد أفكار إبداعية وحلول مبتكرة من خلال التعاون متعدد الزوايا",
|
||||
"guide.groupActivities.brainstorm.ideation.emoji": "🧠",
|
||||
"guide.groupActivities.brainstorm.ideation.prompt": "دعنا نبدأ جلسة عصف ذهني للمشروع. هل يمكنك مساعدتنا في توليد الأفكار والحلول؟",
|
||||
"guide.groupActivities.brainstorm.ideation.title": "العصف الذهني",
|
||||
"guide.groupActivities.game.debateClub.description": "مناقشات منظمة وجدالات حول مواضيع متنوعة وأحداث جارية",
|
||||
"guide.groupActivities.brainstorm.ideation.title": "عصف ذهني",
|
||||
"guide.groupActivities.game.debateClub.description": "نقاشات منظمة وجدلية حول مواضيع مختلفة وقضايا راهنة",
|
||||
"guide.groupActivities.game.debateClub.emoji": "⚖️",
|
||||
"guide.groupActivities.game.debateClub.prompt": "دعنا نجري مناظرة منظمة. هل يمكنك مساعدتنا في تنظيم نقاش منطقي حول هذا الموضوع؟",
|
||||
"guide.groupActivities.game.debateClub.prompt": "دعنا نقيم مناظرة منظمة. هل يمكنك مساعدتنا في تنظيم نقاش منطقي حول هذا الموضوع؟",
|
||||
"guide.groupActivities.game.debateClub.title": "نادي المناظرة",
|
||||
"guide.groupActivities.game.gameNight.description": "ألعاب وأنشطة تفاعلية ممتعة لتعزيز الروابط والاستمتاع الجماعي",
|
||||
"guide.groupActivities.game.gameNight.description": "ألعاب وأنشطة تفاعلية ممتعة لبناء روح الفريق والاستمتاع",
|
||||
"guide.groupActivities.game.gameNight.emoji": "🎲",
|
||||
"guide.groupActivities.game.gameNight.prompt": "ليلة الألعاب قد بدأت! هل يمكنك مساعدتنا في تنظيم ألعاب تفاعلية ممتعة للجميع؟",
|
||||
"guide.groupActivities.game.gameNight.prompt": "حان وقت ليلة الألعاب! هل يمكنك مساعدتنا في تنظيم ألعاب ممتعة لبناء الفريق؟",
|
||||
"guide.groupActivities.game.gameNight.title": "ليلة الألعاب",
|
||||
"guide.groupActivities.game.modelUN.description": "محاكاة مناظرات الأمم المتحدة والمفاوضات الدبلوماسية حول القضايا العالمية",
|
||||
"guide.groupActivities.game.modelUN.emoji": "🌍",
|
||||
"guide.groupActivities.game.modelUN.prompt": "دعنا نحاكي مناظرة في الأمم المتحدة. هل يمكنك مساعدتنا في إعداد مفاوضة دبلوماسية حول القضايا العالمية؟",
|
||||
"guide.groupActivities.game.modelUN.prompt": "دعنا نحاكي مناظرة في الأمم المتحدة. هل يمكنك مساعدتنا في إعداد مفاوضات دبلوماسية؟",
|
||||
"guide.groupActivities.game.modelUN.title": "نموذج الأمم المتحدة",
|
||||
"guide.groupActivities.game.werewolf.description": "لعبة خصم اجتماعي يستخدم فيها اللاعبون الاستراتيجية والنقاش لاكتشاف المستذئب",
|
||||
"guide.groupActivities.game.werewolf.description": "لعبة استنتاج اجتماعي حيث يحاول اللاعبون كشف المستذئبين من خلال النقاش والاستراتيجية",
|
||||
"guide.groupActivities.game.werewolf.emoji": "🐺",
|
||||
"guide.groupActivities.game.werewolf.prompt": "دعنا نلعب لعبة المستذئب! هل يمكنك مساعدتنا في وضع القواعد وتنظيم اللعبة؟",
|
||||
"guide.groupActivities.game.werewolf.prompt": "دعنا نلعب لعبة المستذئب! هل يمكنك مساعدتنا في إعداد القواعد وإدارة اللعبة؟",
|
||||
"guide.groupActivities.game.werewolf.title": "لعبة المستذئب",
|
||||
"guide.groupActivities.general.brainstorm.description": "توليد أفكار تعاوني وحل إبداعي للمشكلات من وجهات نظر متعددة",
|
||||
"guide.groupActivities.general.brainstorm.description": "توليد أفكار إبداعية وحلول مبتكرة من خلال التعاون متعدد الزوايا",
|
||||
"guide.groupActivities.general.brainstorm.emoji": "🧠",
|
||||
"guide.groupActivities.general.brainstorm.prompt": "دعنا نبدأ جلسة عصف ذهني للمشروع. هل يمكنك مساعدتنا في توليد الأفكار والحلول؟",
|
||||
"guide.groupActivities.general.brainstorm.title": "العصف الذهني",
|
||||
"guide.groupActivities.general.debate.description": "مناقشات منظمة وجدالات حول مواضيع متنوعة وأحداث جارية",
|
||||
"guide.groupActivities.general.brainstorm.title": "عصف ذهني",
|
||||
"guide.groupActivities.general.debate.description": "نقاشات منظمة وجدلية حول مواضيع مختلفة وقضايا راهنة",
|
||||
"guide.groupActivities.general.debate.emoji": "⚖️",
|
||||
"guide.groupActivities.general.debate.prompt": "دعنا نجري مناظرة منظمة. هل يمكنك مساعدتنا في تنظيم نقاش منطقي حول هذا الموضوع؟",
|
||||
"guide.groupActivities.general.debate.prompt": "دعنا نقيم مناظرة منظمة. هل يمكنك مساعدتنا في تنظيم نقاش منطقي حول هذا الموضوع؟",
|
||||
"guide.groupActivities.general.debate.title": "نادي المناظرة",
|
||||
"guide.groupActivities.general.languagePractice.description": "ممارسة التحدث وتعلم لغات جديدة مع متحدثين أصليين",
|
||||
"guide.groupActivities.general.languagePractice.description": "ممارسة المحادثة وتعلم لغات جديدة مع متحدثين أصليين",
|
||||
"guide.groupActivities.general.languagePractice.emoji": "🗣️",
|
||||
"guide.groupActivities.general.languagePractice.prompt": "دعنا نتدرب على لغة جديدة معًا. هل يمكنك مساعدتنا في تعلمها والتحدث بها؟",
|
||||
"guide.groupActivities.general.languagePractice.title": "ممارسة اللغة",
|
||||
"guide.groupActivities.general.languagePractice.prompt": "دعنا نتدرب على لغة جديدة معًا. هل يمكنك مساعدتنا في التعلم والممارسة؟",
|
||||
"guide.groupActivities.general.languagePractice.title": "تمرين اللغة",
|
||||
"guide.groupActivities.general.studyGroup.description": "جلسات دراسة تعاونية لمناقشة المفاهيم وحل المشكلات معًا",
|
||||
"guide.groupActivities.general.studyGroup.emoji": "📚",
|
||||
"guide.groupActivities.general.studyGroup.prompt": "دعنا نشكل مجموعة دراسة. هل يمكنك مساعدتنا في فهم هذه المفاهيم وحل المشكلات معًا؟",
|
||||
"guide.groupActivities.general.studyGroup.title": "مجموعة الدراسة",
|
||||
"guide.groupActivities.planning.cookingClass.description": "تعلم ومشاركة مهارات الطبخ والوصفات والتقاليد الطهوية",
|
||||
"guide.groupActivities.general.studyGroup.prompt": "دعنا نشكل مجموعة دراسة. هل يمكنك مساعدتنا في فهم المفاهيم وحل المشكلات؟",
|
||||
"guide.groupActivities.general.studyGroup.title": "مجموعة دراسة",
|
||||
"guide.groupActivities.planning.cookingClass.description": "تعلم ومشاركة مهارات الطبخ والوصفات والتقاليد الغذائية",
|
||||
"guide.groupActivities.planning.cookingClass.emoji": "👨🍳",
|
||||
"guide.groupActivities.planning.cookingClass.prompt": "دعنا نأخذ درسًا في الطبخ! هل يمكنك مساعدتنا في تعلم وصفات وتقنيات جديدة معًا؟",
|
||||
"guide.groupActivities.planning.cookingClass.title": "درس الطبخ",
|
||||
"guide.groupActivities.planning.fitnessChallenge.description": "تحديد أهداف لياقة جماعية، مشاركة التمارين، وتحفيز بعضنا البعض",
|
||||
"guide.groupActivities.planning.cookingClass.prompt": "دعنا نبدأ درس طبخ! هل يمكنك مساعدتنا في تعلم وصفات ومهارات جديدة؟",
|
||||
"guide.groupActivities.planning.cookingClass.title": "صف الطبخ",
|
||||
"guide.groupActivities.planning.fitnessChallenge.description": "تحديد أهداف لياقة جماعية، مشاركة التمارين وتحفيز بعضنا البعض",
|
||||
"guide.groupActivities.planning.fitnessChallenge.emoji": "💪",
|
||||
"guide.groupActivities.planning.fitnessChallenge.prompt": "دعنا نبدأ تحدي اللياقة! هل يمكنك مساعدتنا في تحديد الأهداف والبقاء متحفزين؟",
|
||||
"guide.groupActivities.planning.fitnessChallenge.prompt": "دعنا نبدأ تحدي اللياقة! هل يمكنك مساعدتنا في تحديد الأهداف وتحفيز بعضنا البعض؟",
|
||||
"guide.groupActivities.planning.fitnessChallenge.title": "تحدي اللياقة",
|
||||
"guide.groupActivities.planning.planningPoker.description": "تقنية تقدير مرنة باستخدام بطاقات لتقدير مهام المشروع وحجم العمل",
|
||||
"guide.groupActivities.planning.planningPoker.emoji": "🃏",
|
||||
"guide.groupActivities.planning.planningPoker.prompt": "نحن نستخدم تخطيط البوكر للمشروع. هل يمكنك مساعدتنا في تقدير المهام باستخدام تقنيات أجايل؟",
|
||||
"guide.groupActivities.planning.planningPoker.prompt": "نحن نخطط باستخدام لعبة التخطيط. هل يمكنك مساعدتنا في تقدير المهام باستخدام تقنيات مرنة؟",
|
||||
"guide.groupActivities.planning.planningPoker.title": "تخطيط البوكر",
|
||||
"guide.groupActivities.planning.travelPlanning.description": "تخطيط الرحلات، مشاركة تجارب السفر، واكتشاف وجهات جديدة",
|
||||
"guide.groupActivities.planning.travelPlanning.description": "تخطيط الرحلات، مشاركة التجارب واكتشاف وجهات جديدة",
|
||||
"guide.groupActivities.planning.travelPlanning.emoji": "✈️",
|
||||
"guide.groupActivities.planning.travelPlanning.prompt": "دعنا نخطط لرحلة معًا! هل يمكنك مساعدتنا في البحث عن وجهات وإنشاء جدول؟",
|
||||
"guide.groupActivities.planning.travelPlanning.prompt": "دعنا نخطط لرحلة معًا! هل يمكنك مساعدتنا في البحث عن وجهات وتنظيم الرحلة؟",
|
||||
"guide.groupActivities.planning.travelPlanning.title": "تخطيط السفر",
|
||||
"guide.groupActivities.product.codeReview.description": "مناقشات تقنية ومراجعات جماعية لتغييرات وتنفيذات الشيفرة",
|
||||
"guide.groupActivities.product.codeReview.description": "مناقشة تقنية ومراجعة جماعية لتغييرات وتنفيذات الشيفرة",
|
||||
"guide.groupActivities.product.codeReview.emoji": "💻",
|
||||
"guide.groupActivities.product.codeReview.prompt": "دعنا نراجع بعض الشيفرات معًا. هل يمكنك مساعدتنا في تحليلها وتحديد مجالات التحسين؟",
|
||||
"guide.groupActivities.product.codeReview.title": "مراجعة الشيفرة",
|
||||
"guide.groupActivities.product.designReview.description": "جلسات تغذية راجعة تعاونية حول مفاهيم التصميم والنماذج الأولية والأعمال الإبداعية",
|
||||
"guide.groupActivities.product.designReview.description": "جلسات تعاونية لتقديم الملاحظات على المفاهيم والنماذج الأولية والأعمال الإبداعية",
|
||||
"guide.groupActivities.product.designReview.emoji": "🎨",
|
||||
"guide.groupActivities.product.designReview.prompt": "نحتاج إلى مراجعة بعض التصاميم. هل يمكنك مساعدتنا في تقديم ملاحظات بناءة حول المفاهيم والنماذج؟",
|
||||
"guide.groupActivities.product.designReview.prompt": "نحتاج إلى مراجعة بعض التصاميم. هل يمكنك مساعدتنا في تقديم ملاحظات بناءة؟",
|
||||
"guide.groupActivities.product.designReview.title": "مراجعة التصميم",
|
||||
"guide.groupActivities.product.sprintPlanning.description": "تقنية تقدير مرنة باستخدام بطاقات لتقدير مهام المشروع وحجم العمل",
|
||||
"guide.groupActivities.product.sprintPlanning.emoji": "🃏",
|
||||
"guide.groupActivities.product.sprintPlanning.prompt": "نحن نستخدم تخطيط البوكر للمشروع. هل يمكنك مساعدتنا في تقدير المهام باستخدام تقنيات أجايل؟",
|
||||
"guide.groupActivities.product.sprintPlanning.prompt": "نحن نخطط باستخدام لعبة التخطيط. هل يمكنك مساعدتنا في تقدير المهام باستخدام تقنيات مرنة؟",
|
||||
"guide.groupActivities.product.sprintPlanning.title": "تخطيط البوكر",
|
||||
"guide.groupActivities.product.techExchange.description": "مناقشة التقنيات الناشئة والابتكارات والاتجاهات الصناعية",
|
||||
"guide.groupActivities.product.techExchange.description": "مناقشة التقنيات الناشئة والابتكار واتجاهات الصناعة",
|
||||
"guide.groupActivities.product.techExchange.emoji": "🚀",
|
||||
"guide.groupActivities.product.techExchange.prompt": "دعنا نجري تبادلًا تقنيًا! هل يمكنك مساعدتنا في مناقشة التقنيات والاتجاهات الجديدة؟",
|
||||
"guide.groupActivities.product.techExchange.prompt": "دعنا نبدأ تبادلًا تقنيًا! هل يمكنك مساعدتنا في مناقشة التقنيات والاتجاهات الجديدة؟",
|
||||
"guide.groupActivities.product.techExchange.title": "تبادل تقني",
|
||||
"guide.groupActivities.title": "توصيات استخدام الدردشة الجماعية",
|
||||
"guide.groupActivities.writing.bookClub.description": "مناقشات أدبية وتحليل للكتب والقصص والأدب",
|
||||
"guide.groupActivities.title": "اقتراحات لاستخدام الدردشة الجماعية",
|
||||
"guide.groupActivities.writing.bookClub.description": "مناقشة وتحليل الكتب والقصص والأعمال الأدبية",
|
||||
"guide.groupActivities.writing.bookClub.emoji": "📖",
|
||||
"guide.groupActivities.writing.bookClub.prompt": "دعنا نبدأ مناقشة نادي الكتاب. هل يمكنك مساعدتنا في تحليل الكتاب واستكشاف موضوعاته؟",
|
||||
"guide.groupActivities.writing.bookClub.prompt": "دعنا نبدأ مناقشة نادي الكتاب. هل يمكنك مساعدتنا في تحليل هذا الكتاب ومناقشة مواضيعه؟",
|
||||
"guide.groupActivities.writing.bookClub.title": "نادي الكتاب",
|
||||
"guide.groupActivities.writing.movieClub.description": "مشاهدة ومناقشة الأفلام والوثائقيات والوسائط البصرية معًا",
|
||||
"guide.groupActivities.writing.movieClub.emoji": "🎬",
|
||||
"guide.groupActivities.writing.movieClub.prompt": "دعنا نبدأ مناقشة نادي الأفلام. هل يمكنك مساعدتنا في تحليل الفيلم واستكشاف موضوعاته؟",
|
||||
"guide.groupActivities.writing.movieClub.title": "نادي الأفلام",
|
||||
"guide.groupActivities.writing.musicSession.description": "جلسات تعاونية لإنشاء الموسيقى ومشاركتها وتقديرها",
|
||||
"guide.groupActivities.writing.movieClub.prompt": "دعنا نبدأ مناقشة نادي السينما. هل يمكنك مساعدتنا في تحليل هذا الفيلم ومناقشة مواضيعه؟",
|
||||
"guide.groupActivities.writing.movieClub.title": "نادي السينما",
|
||||
"guide.groupActivities.writing.musicSession.description": "جلسات تعاونية لإنشاء ومشاركة وتقدير الموسيقى",
|
||||
"guide.groupActivities.writing.musicSession.emoji": "🎵",
|
||||
"guide.groupActivities.writing.musicSession.prompt": "دعنا نقيم جلسة موسيقية! هل يمكنك مساعدتنا في إنشاء الموسيقى والاستمتاع بها معًا؟",
|
||||
"guide.groupActivities.writing.musicSession.prompt": "دعنا نقيم جلسة موسيقية! هل يمكنك مساعدتنا في الإبداع والاستمتاع بالموسيقى؟",
|
||||
"guide.groupActivities.writing.musicSession.title": "جلسة موسيقية",
|
||||
"guide.groupActivities.writing.studyGroup.description": "جلسات دراسة تعاونية لمناقشة المفاهيم وحل المشكلات معًا",
|
||||
"guide.groupActivities.writing.studyGroup.emoji": "📚",
|
||||
"guide.groupActivities.writing.studyGroup.prompt": "دعنا نشكل مجموعة دراسة. هل يمكنك مساعدتنا في فهم هذه المفاهيم وحل المشكلات معًا؟",
|
||||
"guide.groupActivities.writing.studyGroup.title": "مجموعة الدراسة",
|
||||
"guide.groupMessage": "مرحبًا بك في المجموعات. في محادثة مشتركة واحدة، يمكن للوكلاء دفع المهمة قدمًا معًا.",
|
||||
"guide.groupTemplates.analysis.description": "رؤى مستندة إلى البيانات وتحليل بحثي معمق",
|
||||
"guide.groupActivities.writing.studyGroup.prompt": "دعنا نشكل مجموعة دراسة. هل يمكنك مساعدتنا في فهم المفاهيم وحل المشكلات؟",
|
||||
"guide.groupActivities.writing.studyGroup.title": "مجموعة دراسة",
|
||||
"guide.groupMessage": "مرحبًا بك في الدردشة الجماعية! تعاون مع عدة مساعدين ذكيين في مساحة محادثة مشتركة.",
|
||||
"guide.groupTemplates.analysis.description": "رؤى مستندة إلى البيانات وتحليلات معمقة",
|
||||
"guide.groupTemplates.analysis.members": [
|
||||
{
|
||||
"avatar": "📊",
|
||||
"backgroundColor": "#E8F8F5",
|
||||
"plugins": ["steam"],
|
||||
"systemRole": "أنت ماهر في معالجة البيانات وتفسيرها، وتكشف الأنماط والاتجاهات من خلال الرسوم البيانية والتحليل الإحصائي.",
|
||||
"systemRole": "أنت بارع في معالجة البيانات وتفسيرها، وتكشف عن الأنماط والاتجاهات من خلال الرسوم البيانية والتحليلات الإحصائية.",
|
||||
"title": "محلل بيانات"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑🔬",
|
||||
"backgroundColor": "#E8F5FF",
|
||||
"systemRole": "أنت خبير في البحث، متخصص في جمع المعلومات والتحليل العميق من زوايا متعددة.",
|
||||
"title": "أخصائي أبحاث"
|
||||
"systemRole": "أنت خبير بحثي، مسؤول عن جمع المعلومات وإجراء دراسات معمقة، وتستطيع تحليل القضايا من عدة أبعاد.",
|
||||
"title": "خبير بحثي"
|
||||
},
|
||||
{
|
||||
"avatar": "📈",
|
||||
"backgroundColor": "#FFF7E8",
|
||||
"systemRole": "أنت خبير في الإحصاء، متمكن من الأساليب والنماذج الإحصائية المختلفة، وتستخرج رؤى تجارية قيّمة من البيانات.",
|
||||
"title": "خبير إحصاء"
|
||||
"systemRole": "أنت خبير إحصائي، تتقن مختلف الأساليب والنماذج الإحصائية، وتستخلص رؤى تجارية قيّمة من البيانات.",
|
||||
"title": "خبير إحصائي"
|
||||
},
|
||||
{
|
||||
"avatar": "🧮",
|
||||
"backgroundColor": "#F0F8FF",
|
||||
"systemRole": "أنت محلل كمي، تركز على النمذجة وتقييم المخاطر باستخدام الأساليب الرياضية لحل المشكلات المعقدة.",
|
||||
"systemRole": "أنت محلل كمي، متخصص في النمذجة الكمية وتقييم المخاطر، وتستخدم الأساليب الرياضية لحل المشكلات المعقدة.",
|
||||
"title": "محلل كمي"
|
||||
}
|
||||
],
|
||||
"guide.groupTemplates.analysis.title": "فريق التحليل",
|
||||
"guide.groupTemplates.brainstorm.description": "تفكير إبداعي من زوايا متعددة لإطلاق إمكانيات لا نهائية",
|
||||
"guide.groupTemplates.brainstorm.description": "تفكير إبداعي متعدد الزوايا لإطلاق إمكانيات لا محدودة",
|
||||
"guide.groupTemplates.brainstorm.members": [
|
||||
{
|
||||
"avatar": "🧠",
|
||||
"backgroundColor": "#E8F5FF",
|
||||
"systemRole": "أنت مخرج إبداعي، ماهر في توجيه الرؤية الإبداعية من منظور شامل وتحويل الأفكار المجردة إلى خطط قابلة للتنفيذ.",
|
||||
"title": "المخرج الإبداعي"
|
||||
"systemRole": "أنت مدير إبداعي، بارع في توجيه الرؤية الإبداعية من منظور شامل، وتحويل المفاهيم المجردة إلى أفكار قابلة للتنفيذ.",
|
||||
"title": "المدير الإبداعي"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑🔬",
|
||||
"backgroundColor": "#FFF7E8",
|
||||
"systemRole": "أنت خبير في الابتكار، تركز على اكتشاف حلول جديدة وأفكار خارجة عن المألوف.",
|
||||
"systemRole": "أنت خبير ابتكار، مسؤول عن اكتشاف حلول جديدة وأفكار خارجة عن المألوف، وتجيد التفكير خارج الصندوق.",
|
||||
"title": "خبير ابتكار"
|
||||
},
|
||||
{
|
||||
"avatar": "🎨",
|
||||
"backgroundColor": "#F6E8FF",
|
||||
"systemRole": "أنت خبير في التفكير التصميمي، تتناول المشكلات من منظور تجربة المستخدم والعرض البصري، مع التركيز على التعبير البصري.",
|
||||
"title": "مفكر تصميمي"
|
||||
"systemRole": "أنت خبير في التفكير التصميمي، تنظر إلى المشكلات من زاوية تجربة المستخدم والعرض البصري، وتركز على التعبير الإبداعي المرئي.",
|
||||
"title": "خبير التفكير التصميمي"
|
||||
}
|
||||
],
|
||||
"guide.groupTemplates.brainstorm.title": "مجموعة العصف الذهني",
|
||||
"guide.groupTemplates.game.description": "العب ألعاب نصية جماعية مثل المستذئب وSpyfall",
|
||||
"guide.groupTemplates.brainstorm.title": "فريق العصف الذهني",
|
||||
"guide.groupTemplates.game.description": "استمتع بألعاب نصية جماعية مثل لعبة المستذئبين ومن هو الجاسوس",
|
||||
"guide.groupTemplates.game.members": [
|
||||
{
|
||||
"avatar": "🧠",
|
||||
"backgroundColor": "#E8F5FF",
|
||||
"systemRole": "أنت منظم ألعاب، ماهر في تنظيم الألعاب النصية الجماعية وتوجيه اللاعبين خلال اللعب.",
|
||||
"title": "منظم ألعاب"
|
||||
"systemRole": "أنت مضيف ألعاب، بارع في تنظيم الألعاب النصية الجماعية وتوجيه اللاعبين خلال اللعبة.",
|
||||
"title": "مضيف اللعبة"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑🔬",
|
||||
"backgroundColor": "#FFF7E8",
|
||||
"systemRole": "أنت بارع في المشاركة في الألعاب النصية الجماعية وتلعب وفقًا للقواعد.",
|
||||
"systemRole": "أنت بارع في المشاركة في الألعاب النصية الجماعية، وتلعب وفقًا لقواعد اللعبة.",
|
||||
"title": "لاعب"
|
||||
},
|
||||
{
|
||||
"avatar": "🎨",
|
||||
"backgroundColor": "#F6E8FF",
|
||||
"systemRole": "أنت بارع في المشاركة في الألعاب النصية الجماعية وتلعب وفقًا للقواعد.",
|
||||
"systemRole": "أنت بارع في المشاركة في الألعاب النصية الجماعية، وتلعب وفقًا لقواعد اللعبة.",
|
||||
"title": "لاعب"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑🎨",
|
||||
"backgroundColor": "#F6E8FF",
|
||||
"systemRole": "أنت بارع في المشاركة في الألعاب النصية الجماعية وتلعب وفقًا للقواعد.",
|
||||
"systemRole": "أنت بارع في المشاركة في الألعاب النصية الجماعية، وتلعب وفقًا لقواعد اللعبة.",
|
||||
"title": "لاعب"
|
||||
}
|
||||
],
|
||||
"guide.groupTemplates.game.title": "غرفة الألعاب",
|
||||
"guide.groupTemplates.planning.description": "تخطيط استراتيجي وإدارة مشاريع برؤية شاملة",
|
||||
"guide.groupTemplates.game.title": "قاعة الألعاب",
|
||||
"guide.groupTemplates.planning.description": "تخطيط استراتيجي وإدارة مشاريع شاملة",
|
||||
"guide.groupTemplates.planning.members": [
|
||||
{
|
||||
"avatar": "📋",
|
||||
"backgroundColor": "#E8F5FF",
|
||||
"systemRole": "أنت مسؤول عن التخطيط العام للمشروع، ومراقبة التقدم، وتنسيق الموارد لضمان التسليم في الوقت المحدد وبجودة عالية.",
|
||||
"systemRole": "أنت مسؤول عن التخطيط العام للمشروع، وضبط الجدول الزمني، وتنسيق الموارد لضمان إنجاز المشروع بجودة عالية وفي الوقت المحدد.",
|
||||
"title": "الطاهي"
|
||||
},
|
||||
{
|
||||
"avatar": "🎯",
|
||||
"backgroundColor": "#FFF7E8",
|
||||
"systemRole": "أنت مسؤول عن التخطيط الاستراتيجي طويل المدى، وتحليل الفرص السوقية، وتحديد الأهداف، ورسم طريق النجاح.",
|
||||
"title": "خبير توريد المكونات"
|
||||
"systemRole": "أنت مسؤول عن وضع الخطط الاستراتيجية طويلة المدى، وتحليل الفرص السوقية، وتحديد الأهداف ومسارات التنفيذ.",
|
||||
"title": "خبير شراء المكونات"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑🎨",
|
||||
"backgroundColor": "#F0F8FF",
|
||||
"systemRole": "أنت مسؤول عن خطط التنفيذ التفصيلية، وتنسيق الموارد بين الأقسام لضمان إمكانية التنفيذ.",
|
||||
"title": "خبير البحث والتطوير في الطهي"
|
||||
"systemRole": "أنت مسؤول عن إعداد خطط تنفيذية مفصلة، وتنسيق الموارد بين الأقسام المختلفة لضمان قابلية تنفيذ الخطة.",
|
||||
"title": "خبير تطوير الأطعمة"
|
||||
}
|
||||
],
|
||||
"guide.groupTemplates.planning.title": "مجموعة البحث والتطوير في الطهي",
|
||||
"guide.groupTemplates.product.description": "تصميم وتطوير المنتجات لبناء منتجات عالية الجودة",
|
||||
"guide.groupTemplates.planning.title": "فريق تطوير الأطعمة",
|
||||
"guide.groupTemplates.product.description": "تصميم وتطوير المنتجات لإنشاء منتجات عالية الجودة",
|
||||
"guide.groupTemplates.product.members": [
|
||||
{
|
||||
"avatar": "🎨",
|
||||
"backgroundColor": "#F6E8FF",
|
||||
"systemRole": "أنت مصمم، ماهر في تصميم أنواع مختلفة من المنتجات بناءً على المتطلبات.",
|
||||
"systemRole": "أنت مصمم، بارع في تصميم أنواع مختلفة من المنتجات، وتعمل وفقًا لمتطلبات المنتج.",
|
||||
"title": "مصمم"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑",
|
||||
"backgroundColor": "#E8F5FF",
|
||||
"systemRole": "أنت مدير منتج، مسؤول عن التخطيط والتصميم والتطوير والصيانة لضمان الجودة وتجربة المستخدم.",
|
||||
"systemRole": "أنت مدير منتج، مسؤول عن تخطيط وتصميم وتطوير وصيانة المنتج، وتضمن جودة المنتج وتجربة المستخدم.",
|
||||
"title": "مدير منتج"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑💻",
|
||||
"backgroundColor": "#E8F8F5",
|
||||
"systemRole": "أنت مهندس برمجيات شامل ذو خبرة، ماهر في تطوير أنواع مختلفة من المنتجات حسب المتطلبات.",
|
||||
"systemRole": "أنت مهندس برمجيات شامل ذو خبرة، بارع في تطوير أنواع مختلفة من المنتجات، وتعمل وفقًا لمتطلبات المنتج.",
|
||||
"title": "مهندس برمجيات شامل"
|
||||
}
|
||||
],
|
||||
"guide.groupTemplates.product.title": "مجموعة تطوير المنتجات",
|
||||
"guide.groupTemplates.product.title": "فريق تطوير المنتجات",
|
||||
"guide.groupTemplates.writing.description": "إنشاء وتحرير المحتوى لصياغة نصوص عالية الجودة",
|
||||
"guide.groupTemplates.writing.members": [
|
||||
{
|
||||
"avatar": "✍️",
|
||||
"backgroundColor": "#F6E8FF",
|
||||
"systemRole": "أنت ماهر في الكتابة بأنماط مختلفة ويمكنك تعديل نبرة الصوت لتناسب الجماهير والمواقف المختلفة.",
|
||||
"systemRole": "أنت بارع في كتابة أنواع مختلفة من المحتوى، وتستطيع تعديل أسلوب الكتابة حسب السياق والجمهور المستهدف.",
|
||||
"title": "كاتب محتوى"
|
||||
},
|
||||
{
|
||||
"avatar": "🧑🎨",
|
||||
"backgroundColor": "#E8F8F5",
|
||||
"systemRole": "أنت محرر، مسؤول عن التدقيق والتحسين وصقل النصوص لضمان الدقة والطلاقة والاحترافية.",
|
||||
"systemRole": "أنت محرر، مسؤول عن تدقيق النصوص وتحريرها وتحسينها، لضمان دقة المحتوى وسلاسته واحترافيته.",
|
||||
"title": "محرر"
|
||||
}
|
||||
],
|
||||
"guide.groupTemplates.writing.title": "دائرة الكُتّاب",
|
||||
"guide.groupTemplates.writing.title": "دائرة الكتابة",
|
||||
"guide.questions.moreBtn": "اعرف المزيد",
|
||||
"guide.questions.title": "جرب أن تسأل:",
|
||||
"guide.welcome.afternoon": "مساء الخير",
|
||||
@@ -263,50 +263,50 @@
|
||||
"guide.welcome.night": "مساء الخير",
|
||||
"guide.welcome.noon": "نهارك سعيد",
|
||||
"header": "مرحبًا بك",
|
||||
"pickAgent": "أو اختر من قوالب الوكلاء أدناه",
|
||||
"pickAgent": "أو اختر من قوالب المساعدين التالية",
|
||||
"skip": "تخطي الإنشاء",
|
||||
"slogan.desc1": "هنا، الوكلاء دائمًا في الخدمة. يمكن للأفكار التعاون والتطور.",
|
||||
"slogan.desc2": "أنشئ وكيلك الأول ولنبدأ الآن~",
|
||||
"slogan.title": "امنح نفسك عقلًا أذكى",
|
||||
"slogan.desc1": "فعّل طاقة العقول، وأطلق شرارة الإبداع. مساعدك الذكي دائمًا هنا.",
|
||||
"slogan.desc2": "أنشئ أول مساعد لك، ولنبدأ الرحلة ~",
|
||||
"slogan.title": "امنح نفسك عقلًا أكثر ذكاءً",
|
||||
"welcomeMessages": {
|
||||
"1": "مرحبًا بعودتك 😊",
|
||||
"10": "أقصى إنتاجية~",
|
||||
"11": "في خدمتك!",
|
||||
"12": "شكرًا لانتظارك ☕",
|
||||
"13": "لنبدأ ✅",
|
||||
"14": "هل لديك أسئلة جديدة؟",
|
||||
"15": "لقد عملت بجد اليوم!",
|
||||
"16": "جارٍ تحميل الإلهام",
|
||||
"17": "مشحون بالكامل ⚡",
|
||||
"18": "هيا بنا! 🚀",
|
||||
"19": "أفكاري متزامنة.",
|
||||
"2": "مرحبًا، أنا هنا",
|
||||
"20": "الإلهام قادم",
|
||||
"21": "بانتظار إشارتك",
|
||||
"22": "عدنا إلى وضع الكفاءة العالية!",
|
||||
"23": "في وضع الاستعداد",
|
||||
"24": "جاهز للتحدي",
|
||||
"25": "أفكار جديدة تتشكل",
|
||||
"26": "الطريق واضح—لننطلق!",
|
||||
"27": "النظام يعمل، جاهز للمساعدة 💡",
|
||||
"28": "جارٍ تحميل الطاقة الإيجابية",
|
||||
"29": "تولَّ القيادة، من الآن 🎵",
|
||||
"3": "كل شيء جاهز!",
|
||||
"30": "تعزيز الكفاءة …",
|
||||
"31": "أهداف اليوم على المسار 🎯",
|
||||
"32": "دع أفكارك تتألق ✨",
|
||||
"33": "تم تحديث المهام",
|
||||
"34": "كل شيء جاهز",
|
||||
"35": "وضع التسريع: مفعل",
|
||||
"36": "حسنًا! لنبدأ 😎",
|
||||
"37": "أنا هنا بانتظارك",
|
||||
"38": "واصل العمل الجيد!",
|
||||
"39": "لا تنسَ أن تأخذ استراحة~ 💤",
|
||||
"3": "أنا جاهز!",
|
||||
"4": "سعيد برؤيتك",
|
||||
"5": "هل أنت مستعد للبدء؟",
|
||||
"6": "دعني أساعدك في مهام اليوم",
|
||||
"7": "استمر في التقدم!",
|
||||
"8": "لنبدأ 💪",
|
||||
"9": "هيا نبدأ العمل 🏃♂️"
|
||||
"6": "دعني أساعدك اليوم",
|
||||
"7": "لنواصل التقدم!",
|
||||
"8": "لننجزها معًا 💪",
|
||||
"9": "لنبدأ العمل 🏃♂️",
|
||||
"10": "أقصى إنتاجية الآن~",
|
||||
"11": "في خدمتك!",
|
||||
"12": "شكرًا لانتظارك ☕",
|
||||
"13": "لنبدأ الآن ✅",
|
||||
"14": "هل لديك سؤال جديد؟",
|
||||
"15": "عمل رائع اليوم!",
|
||||
"16": "جاري تحميل الإلهام",
|
||||
"17": "متصل بكامل الطاقة ⚡",
|
||||
"18": "انطلاق! 🚀",
|
||||
"19": "أفكاري تواكبك الآن.",
|
||||
"20": "الإلهام قادم",
|
||||
"21": "بانتظار إشارتك",
|
||||
"22": "وضع الإنتاجية مفعل!",
|
||||
"23": "في وضع الاستعداد",
|
||||
"24": "جاهز للتحدي",
|
||||
"25": "أفكار جديدة قيد التكوين",
|
||||
"26": "الطريق واضح، لننطلق!",
|
||||
"27": "النظام جاهز لمساعدتك 💡",
|
||||
"28": "جاري تحميل مزاج جيد",
|
||||
"29": "تحكم بالإيقاع من الآن 🎵",
|
||||
"30": "رفع الكفاءة …",
|
||||
"31": "هدف اليوم قيد الإنجاز 🎯",
|
||||
"32": "دع الإلهام يتألق ✨",
|
||||
"33": "تم تحديث المهام",
|
||||
"34": "كل شيء جاهز",
|
||||
"35": "وضع السرعة مفعل",
|
||||
"36": "هيا نبدأ 😎",
|
||||
"37": "أنا هنا بانتظارك",
|
||||
"38": "استمر في الأداء الرائع!",
|
||||
"39": "لا تنسَ أن تأخذ قسطًا من الراحة~ 💤"
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user