heflc-skill 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # heflc-skill
2
+
3
+ > 一条命令安装 AI Skill 到所有编辑器。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install -g heflc-skill
9
+ ```
10
+
11
+ 或不安装直接用:
12
+
13
+ ```bash
14
+ npx heflc-skill <command>
15
+ ```
16
+
17
+ ## 使用
18
+
19
+ ```bash
20
+ # 查看可用的 Skill
21
+ heflc-skill list
22
+
23
+ # 安装指定 Skill
24
+ heflc-skill install tech-branding
25
+
26
+ # 安装全部 Skill
27
+ heflc-skill install --all
28
+
29
+ # 更新已安装的 Skill
30
+ heflc-skill update
31
+
32
+ # 查看本机编辑器和已安装状态
33
+ heflc-skill doctor
34
+
35
+ # 卸载指定 Skill
36
+ heflc-skill uninstall tech-branding
37
+ ```
38
+
39
+ ## 支持的编辑器
40
+
41
+ 自动检测本机安装的编辑器,将 Skill 注入全局配置:
42
+
43
+ | 编辑器 | Skill 路径 |
44
+ |--------|-----------|
45
+ | Claude Code | ~/.claude/skills/&lt;name&gt;/SKILL.md |
46
+ | Cursor | ~/.cursor/skills/&lt;name&gt;/SKILL.md |
47
+ | Trae | ~/.trae/skills/&lt;name&gt;/SKILL.md |
48
+ | Gemini | ~/.gemini/antigravity/skills/&lt;name&gt;/SKILL.md |
49
+
50
+ ## 环境变量
51
+
52
+ | 变量 | 说明 | 默认值 |
53
+ |------|------|--------|
54
+ | GITHUB_TOKEN | GitHub API token(可选,提高速率限制) | 无 |
55
+ | HEFLC_SKILL_OWNER | 覆盖仓库拥有者 | {owner} |
56
+ | HEFLC_SKILL_REPO | 覆盖仓库名 | {repo} |
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+
3
+ // bin/heflc-skill.js
4
+ // CLI 入口,注册所有命令
5
+
6
+ import { Command } from 'commander';
7
+ import { listCommand } from '../src/commands/list.js';
8
+ import { installCommand } from '../src/commands/install.js';
9
+ import { uninstallCommand } from '../src/commands/uninstall.js';
10
+ import { updateCommand } from '../src/commands/update.js';
11
+ import { doctorCommand } from '../src/commands/doctor.js';
12
+
13
+ const program = new Command();
14
+
15
+ program
16
+ .name('heflc-skill')
17
+ .description('下载并安装 AI Skill 到本机编辑器')
18
+ .version('1.0.0');
19
+
20
+ program
21
+ .command('list')
22
+ .description('列出所有可用的 Skill')
23
+ .action(listCommand);
24
+
25
+ program
26
+ .command('install [name]')
27
+ .description('安装指定 Skill 到所有检测到的编辑器')
28
+ .option('-a, --all', '安装全部 Skill')
29
+ .action(installCommand);
30
+
31
+ program
32
+ .command('uninstall <name>')
33
+ .description('从所有编辑器中卸载指定 Skill')
34
+ .action(uninstallCommand);
35
+
36
+ program
37
+ .command('update [name]')
38
+ .description('更新已安装的 Skill(不指定名称则更新全部)')
39
+ .action(updateCommand);
40
+
41
+ program
42
+ .command('doctor')
43
+ .description('检查编辑器检测状态和已安装的 Skill')
44
+ .action(doctorCommand);
45
+
46
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "heflc-skill",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "CLI tool to install AI Skills into editors (Claude Code, Cursor, Trae, Gemini)",
6
+ "bin": {
7
+ "heflc-skill": "./bin/heflc-skill.js"
8
+ },
9
+ "engines": {
10
+ "node": ">=18.0.0"
11
+ },
12
+ "keywords": ["ai", "skill", "cli", "claude", "cursor", "trae"],
13
+ "license": "MIT",
14
+ "dependencies": {
15
+ "chalk": "^5.3.0",
16
+ "commander": "^12.0.0",
17
+ "ora": "^8.0.0"
18
+ }
19
+ }
@@ -0,0 +1,44 @@
1
+ // src/commands/doctor.js
2
+ // 诊断本机编辑器和已安装的 skill 状态
3
+
4
+ import chalk from 'chalk';
5
+ import { detectEditors, listInstalledSkills } from '../editors.js';
6
+
7
+ /**
8
+ * 执行 doctor 命令
9
+ */
10
+ export async function doctorCommand() {
11
+ const editors = detectEditors();
12
+
13
+ // 打印编辑器检测结果
14
+ console.log('编辑器检测:\n');
15
+ for (const editor of editors) {
16
+ if (editor.detected) {
17
+ console.log(` ${chalk.green('✓')} ${editor.name} ${chalk.gray(`(${editor.detectFullPath})`)}`);
18
+ } else {
19
+ console.log(` ${chalk.gray('✗')} ${chalk.gray(editor.name)} ${chalk.gray('(未检测到)')}`);
20
+ }
21
+ }
22
+
23
+ // 打印已安装的 skill
24
+ const activeEditors = editors.filter((e) => e.detected);
25
+ if (activeEditors.length === 0) {
26
+ console.log(chalk.yellow('\n未检测到任何支持的编辑器。'));
27
+ return;
28
+ }
29
+
30
+ console.log('\n已安装的 Skill:\n');
31
+ for (const editor of activeEditors) {
32
+ const skills = listInstalledSkills(editor);
33
+ console.log(` ${chalk.bold(editor.name)}:`);
34
+ if (skills.length === 0) {
35
+ console.log(` ${chalk.gray('(无)')}`);
36
+ } else {
37
+ for (const skill of skills) {
38
+ console.log(` ${chalk.green('✓')} ${skill}`);
39
+ }
40
+ }
41
+ }
42
+
43
+ console.log(`\n使用 ${chalk.green('heflc-skill list')} 查看可安装的 Skill。`);
44
+ }
@@ -0,0 +1,93 @@
1
+ // src/commands/install.js
2
+ // 安装 skill 到所有检测到的编辑器
3
+
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import { listRemoteSkills, downloadSkill } from '../github.js';
7
+ import { detectEditors, writeSkillFile, getSkillFilePath } from '../editors.js';
8
+
9
+ /**
10
+ * 打印编辑器检测结果
11
+ * @param {Array} editors - detectEditors() 返回值
12
+ */
13
+ function printEditorStatus(editors) {
14
+ console.log('检测到以下编辑器:');
15
+ for (const editor of editors) {
16
+ if (editor.detected) {
17
+ console.log(` ${chalk.green('✓')} ${editor.name}`);
18
+ } else {
19
+ console.log(` ${chalk.gray('✗')} ${chalk.gray(editor.name)} ${chalk.gray('(未检测到)')}`);
20
+ }
21
+ }
22
+ console.log();
23
+ }
24
+
25
+ /**
26
+ * 安装单个 skill 到所有检测到的编辑器
27
+ * @param {string} skillName - skill 名称
28
+ * @param {Array} activeEditors - 已检测到的编辑器列表
29
+ */
30
+ async function installOne(skillName, activeEditors) {
31
+ const spinner = ora(`正在下载 ${skillName} ...`).start();
32
+
33
+ try {
34
+ const content = await downloadSkill(skillName);
35
+ spinner.succeed(`已下载 ${chalk.cyan(skillName)}`);
36
+
37
+ for (const editor of activeEditors) {
38
+ try {
39
+ writeSkillFile(editor, skillName, content);
40
+ const filePath = getSkillFilePath(editor, skillName);
41
+ console.log(` ${chalk.green('✓')} ${filePath}`);
42
+ } catch (err) {
43
+ console.log(` ${chalk.red('✗')} ${editor.name}: ${err.message}`);
44
+ }
45
+ }
46
+ } catch (error) {
47
+ spinner.fail(chalk.red(`${skillName}: ${error.message}`));
48
+ }
49
+ }
50
+
51
+ /**
52
+ * 执行 install 命令
53
+ * @param {string|undefined} name - skill 名称,undefined 时需要 --all
54
+ * @param {object} options - 命令选项
55
+ */
56
+ export async function installCommand(name, options) {
57
+ // 检测编辑器
58
+ const editors = detectEditors();
59
+ printEditorStatus(editors);
60
+
61
+ const activeEditors = editors.filter((e) => e.detected);
62
+ if (activeEditors.length === 0) {
63
+ console.log(chalk.yellow('未检测到任何支持的编辑器,无法安装。'));
64
+ process.exit(1);
65
+ }
66
+
67
+ // 确定要安装的 skill 列表
68
+ let skillNames;
69
+ if (options.all) {
70
+ const spinner = ora('正在获取所有 Skill ...').start();
71
+ try {
72
+ skillNames = await listRemoteSkills();
73
+ spinner.succeed(`找到 ${skillNames.length} 个 Skill`);
74
+ } catch (error) {
75
+ spinner.fail(chalk.red(error.message));
76
+ process.exit(1);
77
+ }
78
+ } else if (name) {
79
+ skillNames = [name];
80
+ } else {
81
+ console.log(chalk.red('请指定 skill 名称,或使用 --all 安装全部。'));
82
+ console.log(`用法: heflc-skill install <name>`);
83
+ console.log(` heflc-skill install --all`);
84
+ process.exit(1);
85
+ }
86
+
87
+ // 逐个安装
88
+ for (const skillName of skillNames) {
89
+ await installOne(skillName, activeEditors);
90
+ }
91
+
92
+ console.log(chalk.green('\n安装完成!'));
93
+ }
@@ -0,0 +1,35 @@
1
+ // src/commands/list.js
2
+ // 列出集中仓库中所有可用的 skill
3
+
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import { listRemoteSkills } from '../github.js';
7
+
8
+ /**
9
+ * 执行 list 命令
10
+ */
11
+ export async function listCommand() {
12
+ const spinner = ora('正在获取可用的 Skill 列表...').start();
13
+
14
+ try {
15
+ const skills = await listRemoteSkills();
16
+
17
+ if (skills.length === 0) {
18
+ spinner.warn('集中仓库中暂无可用的 Skill。');
19
+ return;
20
+ }
21
+
22
+ spinner.succeed(`找到 ${skills.length} 个可用的 Skill:\n`);
23
+
24
+ for (const name of skills) {
25
+ console.log(` ${chalk.cyan(name)}`);
26
+ }
27
+
28
+ console.log(
29
+ `\n使用 ${chalk.green('heflc-skill install <name>')} 安装指定 Skill。`
30
+ );
31
+ } catch (error) {
32
+ spinner.fail(chalk.red(error.message));
33
+ process.exit(1);
34
+ }
35
+ }
@@ -0,0 +1,45 @@
1
+ // src/commands/uninstall.js
2
+ // 从所有编辑器中卸载指定 skill
3
+
4
+ import chalk from 'chalk';
5
+ import { detectEditors, removeSkillFile, getSkillFilePath } from '../editors.js';
6
+
7
+ /**
8
+ * 执行 uninstall 命令
9
+ * @param {string} name - 要卸载的 skill 名称
10
+ */
11
+ export async function uninstallCommand(name) {
12
+ if (!name) {
13
+ console.log(chalk.red('请指定要卸载的 skill 名称。'));
14
+ console.log(`用法: heflc-skill uninstall <name>`);
15
+ process.exit(1);
16
+ }
17
+
18
+ const editors = detectEditors();
19
+ const activeEditors = editors.filter((e) => e.detected);
20
+
21
+ if (activeEditors.length === 0) {
22
+ console.log(chalk.yellow('未检测到任何编辑器。'));
23
+ process.exit(1);
24
+ }
25
+
26
+ console.log(`正在卸载 ${chalk.cyan(name)} ...\n`);
27
+
28
+ let removedCount = 0;
29
+ for (const editor of activeEditors) {
30
+ const filePath = getSkillFilePath(editor, name);
31
+ const removed = removeSkillFile(editor, name);
32
+ if (removed) {
33
+ console.log(` ${chalk.green('✓')} 已删除 ${filePath}`);
34
+ removedCount++;
35
+ } else {
36
+ console.log(` ${chalk.gray('-')} ${editor.name}: 未安装该 skill`);
37
+ }
38
+ }
39
+
40
+ if (removedCount > 0) {
41
+ console.log(chalk.green(`\n卸载完成,已从 ${removedCount} 个编辑器中移除。`));
42
+ } else {
43
+ console.log(chalk.yellow('\n该 skill 未安装在任何编辑器中。'));
44
+ }
45
+ }
@@ -0,0 +1,81 @@
1
+ // src/commands/update.js
2
+ // 更新已安装的 skill(重新从 GitHub 下载最新版覆盖)
3
+
4
+ import chalk from 'chalk';
5
+ import ora from 'ora';
6
+ import { detectEditors, listInstalledSkills } from '../editors.js';
7
+ import { downloadSkill } from '../github.js';
8
+ import { writeSkillFile, getSkillFilePath } from '../editors.js';
9
+
10
+ /**
11
+ * 更新单个 skill 到所有检测到的编辑器
12
+ * @param {string} skillName - skill 名称
13
+ * @param {Array} activeEditors - 已检测到的编辑器列表
14
+ */
15
+ async function updateOne(skillName, activeEditors) {
16
+ const spinner = ora(`正在更新 ${skillName} ...`).start();
17
+
18
+ try {
19
+ const content = await downloadSkill(skillName);
20
+ spinner.succeed(`已下载 ${chalk.cyan(skillName)}`);
21
+
22
+ for (const editor of activeEditors) {
23
+ try {
24
+ writeSkillFile(editor, skillName, content);
25
+ const filePath = getSkillFilePath(editor, skillName);
26
+ console.log(` ${chalk.green('✓')} ${filePath}`);
27
+ } catch (err) {
28
+ console.log(` ${chalk.red('✗')} ${editor.name}: ${err.message}`);
29
+ }
30
+ }
31
+ } catch (error) {
32
+ spinner.fail(chalk.red(`${skillName}: ${error.message}`));
33
+ }
34
+ }
35
+
36
+ /**
37
+ * 执行 update 命令
38
+ * @param {string|undefined} name - 指定更新的 skill 名称,不传则更新全部已安装的
39
+ */
40
+ export async function updateCommand(name) {
41
+ const editors = detectEditors();
42
+ const activeEditors = editors.filter((e) => e.detected);
43
+
44
+ if (activeEditors.length === 0) {
45
+ console.log(chalk.yellow('未检测到任何编辑器。'));
46
+ process.exit(1);
47
+ }
48
+
49
+ if (name) {
50
+ // 更新指定 skill
51
+ console.log(`正在更新 ${chalk.cyan(name)} ...\n`);
52
+ await updateOne(name, activeEditors);
53
+ console.log(chalk.green('\n更新完成!'));
54
+ return;
55
+ }
56
+
57
+ // 扫描所有编辑器,收集已安装的 skill(去重)
58
+ const installedSet = new Set();
59
+ for (const editor of activeEditors) {
60
+ const skills = listInstalledSkills(editor);
61
+ for (const skill of skills) {
62
+ installedSet.add(skill);
63
+ }
64
+ }
65
+
66
+ if (installedSet.size === 0) {
67
+ console.log(chalk.yellow('未发现任何已安装的 Skill。'));
68
+ console.log(`使用 ${chalk.green('heflc-skill install <name>')} 安装。`);
69
+ return;
70
+ }
71
+
72
+ const installedNames = [...installedSet];
73
+ console.log(`发现 ${installedNames.length} 个已安装的 Skill:${chalk.cyan(installedNames.join(', '))}\n`);
74
+
75
+ // 逐个更新
76
+ for (const skillName of installedNames) {
77
+ await updateOne(skillName, activeEditors);
78
+ }
79
+
80
+ console.log(chalk.green('\n全部更新完成!'));
81
+ }
package/src/config.js ADDED
@@ -0,0 +1,18 @@
1
+ // src/config.js
2
+ // 集中仓库配置,支持环境变量覆盖
3
+
4
+ const config = {
5
+ // GitHub 仓库拥有者(组织名或用户名)
6
+ repoOwner: process.env.HEFLC_SKILL_OWNER || 'rendaoxian',
7
+
8
+ // GitHub 仓库名
9
+ repoName: process.env.HEFLC_SKILL_REPO || 'heflc-skills',
10
+
11
+ // GitHub API token(可选,提高速率限制到 5000 次/小时)
12
+ githubToken: process.env.GITHUB_TOKEN || null,
13
+
14
+ // GitHub API 基础地址
15
+ apiBase: 'https://api.github.com',
16
+ };
17
+
18
+ export default config;
package/src/editors.js ADDED
@@ -0,0 +1,123 @@
1
+ // src/editors.js
2
+ // 编辑器检测与路径映射
3
+
4
+ import { existsSync, readdirSync, mkdirSync, writeFileSync, rmSync } from 'fs';
5
+ import { join, dirname } from 'path';
6
+ import { homedir } from 'os';
7
+
8
+ /**
9
+ * 支持的编辑器列表
10
+ * 新增编辑器只需往数组里加一条记录
11
+ */
12
+ const EDITORS = [
13
+ {
14
+ name: 'Claude Code',
15
+ detectPath: '.claude',
16
+ skillPath: '.claude/skills/{name}/SKILL.md',
17
+ },
18
+ {
19
+ name: 'Cursor',
20
+ detectPath: '.cursor',
21
+ skillPath: '.cursor/skills/{name}/SKILL.md',
22
+ },
23
+ {
24
+ name: 'Trae',
25
+ detectPath: '.trae',
26
+ skillPath: '.trae/skills/{name}/SKILL.md',
27
+ },
28
+ {
29
+ name: 'Gemini',
30
+ detectPath: '.gemini',
31
+ skillPath: '.gemini/antigravity/skills/{name}/SKILL.md',
32
+ },
33
+ ];
34
+
35
+ /**
36
+ * 获取用户 home 目录(跨平台)
37
+ * @returns {string} home 目录绝对路径
38
+ */
39
+ function getHomeDir() {
40
+ return homedir();
41
+ }
42
+
43
+ /**
44
+ * 检测本机安装了哪些编辑器
45
+ * @returns {Array<{name: string, detected: boolean, detectFullPath: string, skillPathTemplate: string}>}
46
+ */
47
+ export function detectEditors() {
48
+ const home = getHomeDir();
49
+ return EDITORS.map((editor) => {
50
+ const detectFullPath = join(home, editor.detectPath);
51
+ return {
52
+ name: editor.name,
53
+ detected: existsSync(detectFullPath),
54
+ detectFullPath,
55
+ skillPathTemplate: editor.skillPath,
56
+ };
57
+ });
58
+ }
59
+
60
+ /**
61
+ * 获取指定 skill 在某个编辑器中的完整文件路径
62
+ * @param {object} editor - detectEditors() 返回的编辑器对象
63
+ * @param {string} skillName - skill 名称
64
+ * @returns {string} 完整文件路径
65
+ */
66
+ export function getSkillFilePath(editor, skillName) {
67
+ const home = getHomeDir();
68
+ const relativePath = editor.skillPathTemplate.replace('{name}', skillName);
69
+ return join(home, relativePath);
70
+ }
71
+
72
+ /**
73
+ * 将 skill 内容写入指定编辑器的 skills 目录
74
+ * @param {object} editor - 编辑器对象
75
+ * @param {string} skillName - skill 名称
76
+ * @param {string} content - SKILL.md 文件内容
77
+ */
78
+ export function writeSkillFile(editor, skillName, content) {
79
+ const filePath = getSkillFilePath(editor, skillName);
80
+ const dir = dirname(filePath);
81
+ mkdirSync(dir, { recursive: true });
82
+ writeFileSync(filePath, content, 'utf-8');
83
+ }
84
+
85
+ /**
86
+ * 从指定编辑器中删除 skill
87
+ * @param {object} editor - 编辑器对象
88
+ * @param {string} skillName - skill 名称
89
+ * @returns {boolean} 是否成功删除
90
+ */
91
+ export function removeSkillFile(editor, skillName) {
92
+ const filePath = getSkillFilePath(editor, skillName);
93
+ const dir = dirname(filePath);
94
+ if (existsSync(dir)) {
95
+ rmSync(dir, { recursive: true, force: true });
96
+ return true;
97
+ }
98
+ return false;
99
+ }
100
+
101
+ /**
102
+ * 扫描某个编辑器中已安装的 skill 列表
103
+ * @param {object} editor - 编辑器对象
104
+ * @returns {string[]} 已安装的 skill 名称数组
105
+ */
106
+ export function listInstalledSkills(editor) {
107
+ const home = getHomeDir();
108
+ const parts = editor.skillPathTemplate.split('{name}');
109
+ const skillsDir = join(home, parts[0]);
110
+
111
+ if (!existsSync(skillsDir)) {
112
+ return [];
113
+ }
114
+
115
+ try {
116
+ const entries = readdirSync(skillsDir, { withFileTypes: true });
117
+ return entries
118
+ .filter((entry) => entry.isDirectory())
119
+ .map((entry) => entry.name);
120
+ } catch {
121
+ return [];
122
+ }
123
+ }
package/src/github.js ADDED
@@ -0,0 +1,79 @@
1
+ // src/github.js
2
+ // GitHub REST API 封装
3
+
4
+ import config from './config.js';
5
+
6
+ /**
7
+ * 构造 GitHub API 请求头
8
+ * @returns {object} fetch headers
9
+ */
10
+ function getHeaders() {
11
+ const headers = {
12
+ Accept: 'application/vnd.github.v3+json',
13
+ 'User-Agent': 'heflc-skill-cli',
14
+ };
15
+ if (config.githubToken) {
16
+ headers.Authorization = `token ${config.githubToken}`;
17
+ }
18
+ return headers;
19
+ }
20
+
21
+ /**
22
+ * 统一错误处理
23
+ * @param {Response} response - fetch response
24
+ * @param {string} context - 错误上下文描述
25
+ */
26
+ async function handleResponse(response, context) {
27
+ if (response.ok) {
28
+ return response.json();
29
+ }
30
+
31
+ if (response.status === 404) {
32
+ throw new Error(`未找到:${context}。请用 heflc-skill list 查看可用的 skill。`);
33
+ }
34
+ if (response.status === 403) {
35
+ throw new Error(
36
+ 'GitHub API 请求频率超限。请稍后再试,或设置环境变量 GITHUB_TOKEN 提高限额。'
37
+ );
38
+ }
39
+ throw new Error(`GitHub API 请求失败 (${response.status}):${context}`);
40
+ }
41
+
42
+ /**
43
+ * 列出集中仓库中所有可用的 skill(顶层目录)
44
+ * @returns {Promise<string[]>} skill 名称数组
45
+ */
46
+ export async function listRemoteSkills() {
47
+ const url = `${config.apiBase}/repos/${config.repoOwner}/${config.repoName}/contents/`;
48
+ let response;
49
+ try {
50
+ response = await fetch(url, { headers: getHeaders(), signal: AbortSignal.timeout(15000) });
51
+ } catch (err) {
52
+ throw new Error('无法连接 GitHub API,请检查网络连接或配置代理。');
53
+ }
54
+ const data = await handleResponse(response, '集中仓库');
55
+
56
+ return data
57
+ .filter((item) => item.type === 'dir')
58
+ .map((item) => item.name);
59
+ }
60
+
61
+ /**
62
+ * 下载指定 skill 的 SKILL.md 文件内容
63
+ * @param {string} skillName - skill 名称(即仓库中的目录名)
64
+ * @returns {Promise<string>} SKILL.md 的文本内容
65
+ */
66
+ export async function downloadSkill(skillName) {
67
+ const url = `${config.apiBase}/repos/${config.repoOwner}/${config.repoName}/contents/${skillName}/SKILL.md`;
68
+ let response;
69
+ try {
70
+ response = await fetch(url, { headers: getHeaders(), signal: AbortSignal.timeout(15000) });
71
+ } catch (err) {
72
+ throw new Error('无法连接 GitHub API,请检查网络连接或配置代理。');
73
+ }
74
+ const data = await handleResponse(response, `skill "${skillName}"`);
75
+
76
+ // GitHub API 返回 Base64 编码的文件内容
77
+ const content = Buffer.from(data.content, 'base64').toString('utf-8');
78
+ return content;
79
+ }