This commit is contained in:
insile 2025-05-07 20:51:38 +08:00
parent 1762119081
commit e38950e283
8 changed files with 303 additions and 203 deletions

View file

@ -1,6 +1,6 @@
# OpenWords
**OpenWords** 是一个用于背单词和单词管理的 Obsidian 插件, 安装后插件入口是左侧工具栏上的一个按钮再加上两个绑定命令, 主要功能有生成索引, 背单词, 默写单词, 添加双链等, 其中背单词的核心逻辑是 SuperMemo 2 间隔重复算法, 而单词文件使用 OpenText 中的单词库. 插件完全依赖单词文件及其属性, 没有表格, Json 等外部存储, 启动时会读取所有单词缓存, 更改时会即时写入相应的单词文件并更新缓存. 插件没有设计过多的搜索功能, 提倡使用 Obsidian 内置的搜索功能
**OpenWords** 是一个用于背单词和单词管理的与 [OpenText](https://opentext.net.cn) 配套的 Obsidian 插件, 安装后插件入口是左侧工具栏上的一个按钮再加上两个绑定命令, 主要功能有生成索引, 背单词, 默写单词, 添加双链等, 其中单词文件使用 OpenText 中的单词库, 而背单词的核心逻辑是 SuperMemo 2 间隔重复算法. 插件完全依赖单词文件及其属性, 没有表格, Json 等外部存储, 启动时会读取所有单词缓存, 更改时会即时写入相应的单词文件并更新缓存. 插件没有设计过多的搜索功能, 提倡使用 Obsidian 内置的搜索功能. 如果您认为本插件有很大帮助, 欢迎微信赞赏支持
![p7](README/p7.png)
@ -10,7 +10,7 @@
## 单词
单词的格式属性及组织形式以 [OpenText](https://opentext.net.cn) 中的单词库为参考基准. 单词库是仓库中的一个文件夹, 其中按首字母分类储存所有单词文件, 并且仅存储单词文件, 单词即为文件名, 元数据使用文件 YAML 属性, 其中复选框和标签用于确定插件运行的作用域, 数字和日期是 SM 2 的计算参数. 所有单词指单词库路径中的所有文件, 作用域单词指目前主要集中精力学习的单词也是一些插件功能的作用范围. 单词索引是为了更快访问的一系列单词双链文件, 详见生成索引. 目前没有设计批量增加单词的功能, 需要手动仿照格式创建文件确定属性
单词的格式属性及组织形式以 OpenText 中的单词库为参考基准. 单词库是仓库中的一个文件夹, 其中按首字母分类储存所有单词文件, 并且仅存储单词文件, 单词即为文件名, 元数据使用文件 YAML 属性, 其中复选框和标签用于确定插件运行的作用域, 数字和日期是 SM 2 的计算参数. 所有单词指单词库路径中的所有文件, 作用域单词指目前主要集中精力学习的单词也是一些插件功能的作用范围. 单词索引是为了更快访问的一系列单词双链文件, 详见生成索引. 目前没有设计批量增加单词的功能, 需要手动仿照格式创建文件确定属性
- 复选框: `掌握` , 确定插件作用域, 单词被掌握意味着不会被插件处理
- 标签: `级别/小学`, `级别/中考`, `级别/高考四级`, `级别/考研`, `级别/六级`, `级别/雅思`, `级别/托福`, `级别/GRE`, 确定插件作用域, 标签意味着当前主要精力范围, 设置中没有勾选意味着不会被插件处理
- 数字: `重复次数`, 连续正确回答的次数, 初始值为 0
@ -66,3 +66,49 @@
重置作用域单词的重复次数, 间隔, 易记因子, 到期日为默认值, 该功能运行较慢无法回撤, 请谨慎使用
## SuperMemo 2
```js
function supermemo(item, grade) {
let nextInterval;
let nextRepetition;
let nextEfactor;
// 回忆成绩 >= 3 表示成功记住
if (grade >= 3) {
if (item.repetition === 0) {
// 第一次成功记住:间隔为 1 天
nextInterval = 1;
nextRepetition = 1;
}
else if (item.repetition === 1) {
// 第二次:间隔为 6 天
nextInterval = 6;
nextRepetition = 2;
}
else {
// 之后:使用前一次间隔 × 易度因子
nextInterval = Math.round(item.interval * item.efactor);
nextRepetition = item.repetition + 1;
}
} else {
// 回忆失败:重复次数归零,间隔重置为 1 天
nextInterval = 1;
nextRepetition = 0;
}
// 更新易度因子efactor用 SuperMemo 原始公式调整
nextEfactor = item.efactor + (0.1 - (5 - grade) * (0.08 + (5 - grade) * 0.02));
// 保证 efactor 不低于 1.3(防止间隔变得太短)
if (nextEfactor < 1.3)
nextEfactor = 1.3;
return {
interval: nextInterval,
repetition: nextRepetition,
efactor: nextEfactor,
};
}
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 461 KiB

143
main.ts
View file

@ -1,7 +1,7 @@
import { App, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, TFile, Setting, MarkdownRenderer, normalizePath } from 'obsidian';
import { supermemo, SuperMemoItem, SuperMemoGrade } from 'supermemo';
import posTagger from 'wink-pos-tagger';
import dayjs from "dayjs";
import { supermemo, SuperMemoItem, SuperMemoGrade } from 'supermemo';
// 插件设置
@ -45,8 +45,8 @@ export default class OpenWords extends Plugin {
settings: OpenWordsSettings; // 插件设置
settingsSnapshot: OpenWordsSettings; // 插件设置快照
statusBarItem: HTMLElement; // 状态栏元素
alllCards: Map<string, CardInfo> = new Map(); // 存储所有单词的元数据
allCards: Map<string, CardInfo> = new Map(); // 存储作用域单词的元数据
allCards: Map<string, CardInfo> = new Map(); // 存储所有单词的元数据
enabledCards: Map<string, CardInfo> = new Map(); // 存储作用域单词的元数据
newCards: Map<string, CardInfo> = new Map(); // 存储新单词的元数据
dueCards: Map<string, CardInfo> = new Map(); // 存储旧单词的元数据
tagger = new posTagger(); // 词性标注器实例
@ -57,7 +57,7 @@ export default class OpenWords extends Plugin {
await this.loadSettings();
this.statusBarItem = this.addStatusBarItem();
this.addSettingTab(new OpenWordsSettingTab(this.app, this));
this.addRibbonIcon('slack', 'OpenWords', async (evt: MouseEvent) => {
this.addRibbonIcon('slack', 'OpenWords', async () => {
new LearningTypeModal(this.app, this).open();
});
@ -89,9 +89,10 @@ export default class OpenWords extends Plugin {
this.registerEvent(this.app.vault.on("delete", (file: TFile) => {
if (file.path.endsWith(".md") && file.path.startsWith(this.settings.folderPath)) {
this.allCards.delete(file.basename);
this.enabledCards.delete(file.basename);
this.newCards.delete(file.basename);
this.dueCards.delete(file.basename);
this.statusBarItem.setText(`${this.newCards.size} + ${this.dueCards.size} = ${this.allCards.size}`);
this.statusBarItem.setText(`${this.newCards.size} + ${this.dueCards.size} = ${this.enabledCards.size}`);
}
}));
// 监听单词文件缓存修改事件
@ -108,11 +109,12 @@ export default class OpenWords extends Plugin {
// 加载单词元数据
async loadWordMetadata(file: TFile) {
const allCards = this.allCards;
const enabledCards = this.enabledCards;
const newCards = this.newCards;
const dueCards = this.dueCards;
// 先删除旧的单词元数据
allCards.delete(file.basename);
enabledCards.delete(file.basename);
newCards.delete(file.basename);
dueCards.delete(file.basename);
@ -126,8 +128,7 @@ export default class OpenWords extends Plugin {
}
const tags: string[] = frontMatter.tags || [];
const isMastered = frontMatter. === true;
console.log(frontMatter)
const isMastered = frontMatter["掌握"] === true;
const isEnabled =
(this.settings.enableWords1 && tags.includes('级别/小学')) ||
(this.settings.enableWords2 && tags.includes('级别/中考')) ||
@ -141,20 +142,20 @@ export default class OpenWords extends Plugin {
const card: CardInfo = {
front: file.basename,
path: file.path,
dueDate: frontMatter.到期日,
interval: frontMatter.间隔,
efactor: frontMatter.易记因子 * 0.01,
repetition: frontMatter.重复次数,
dueDate: frontMatter["到期日"],
interval: frontMatter["间隔"],
efactor: frontMatter["易记因子"] * 0.01,
repetition: frontMatter["重复次数"],
isMastered: isMastered,
};
const isMasteredOld = this.alllCards.get(card.front)?.isMastered;
this.alllCards.set(card.front, card);
const isMasteredOld = allCards.get(card.front)?.isMastered;
allCards.set(card.front, card);
// 再添加新的单词元数据
if (isEnabled && !isMastered) {
allCards.set(card.front, card);
if (frontMatter. === 0) {
enabledCards.set(card.front, card);
if (frontMatter["重复次数"] === 0) {
newCards.set(card.front, card);
} else {
dueCards.set(card.front, card);
@ -165,33 +166,32 @@ export default class OpenWords extends Plugin {
if (isMastered !== isMasteredOld && isMasteredOld !== undefined) {
const newCheckbox = isMastered ? 'x' : ' ';
const oldCheckbox = isMasteredOld ? 'x' : ' ';
console.log(file, newCheckbox, oldCheckbox)
await this.syncMetadataToCheckbox(file, newCheckbox, oldCheckbox);
}
this.statusBarItem.setText(`${this.newCards.size} + ${this.dueCards.size} = ${this.allCards.size}`);
this.statusBarItem.setText(`${this.newCards.size} + ${this.dueCards.size} = ${this.enabledCards.size}`);
}
// 扫描所有单词文件
async scanAllNotes() {
this.alllCards.clear();
this.allCards.clear();
this.enabledCards.clear();
this.newCards.clear();
this.dueCards.clear();
const files = this.app.vault.getMarkdownFiles();
const filteredFiles = files.filter(file => file.path.startsWith(this.settings.folderPath));
if (filteredFiles.length === 0) {
new Notice('指定的文件夹下没有 Markdown 文件!');
this.statusBarItem.setText(`${this.newCards.size} + ${this.dueCards.size} = ${this.allCards.size}`);
this.statusBarItem.setText(`${this.newCards.size} + ${this.dueCards.size} = ${this.enabledCards.size}`);
return;
}
const notice = new Notice('缓存中...', 0); // 创建一个持续显示的 Notice
await Promise.all(filteredFiles.map(async (file) => {
await this.loadWordMetadata(file);
notice.setMessage(`缓存中... ${this.allCards.size}/${filteredFiles.length}`); // 更新 Notice 的消息
notice.setMessage(`缓存中... ${this.enabledCards.size}/${filteredFiles.length}`); // 更新 Notice 的消息
}));
notice.setMessage(`缓存完成!共 ${this.allCards.size} 个单词`); // 完成后更新消息
notice.setMessage(`缓存完成!共 ${this.enabledCards.size} 个单词`); // 完成后更新消息
setTimeout(() => notice.hide(), 2000); // 2 秒后自动隐藏 Notice
}
@ -207,10 +207,10 @@ export default class OpenWords extends Plugin {
this.newCards.delete(card.front);
this.dueCards.delete(card.front);
await this.app.fileManager.processFrontMatter(file, (frontMatter) => {
frontMatter. = newDate;
frontMatter. = result.interval;
frontMatter. = Math.round(result.efactor * 100);
frontMatter. = result.repetition;
frontMatter["到期日"] = newDate;
frontMatter["间隔"] = result.interval;
frontMatter["易记因子"] = Math.round(result.efactor * 100);
frontMatter["重复次数"] = result.repetition;
});
new Notice(`${card.front} \n易记因子: ${result.efactor.toFixed(2)} \n重复次数: ${result.repetition} \n间隔: ${result.interval} \n到期日: ${newDate}`);
@ -218,13 +218,13 @@ export default class OpenWords extends Plugin {
// 重置单词属性
async resetCard() {
if (this.allCards.size === 0) {
if (this.enabledCards.size === 0) {
new Notice("没有单词需要重置!");
return;
}
const notice = new Notice('重置中...', 0); // 创建一个持续显示的 Notice
let count = 0; // 计数器
const cardList = Array.from(this.allCards.values()); // 将 Map 转换为数组
const cardList = Array.from(this.enabledCards.values()); // 将 Map 转换为数组
for (const card of cardList) {
const file = this.app.vault.getFileByPath(card.path);
if (!file) {
@ -232,13 +232,13 @@ export default class OpenWords extends Plugin {
continue;
}
await this.app.fileManager.processFrontMatter(file, (frontMatter) => {
frontMatter. = dayjs().format('YYYY-MM-DD');
frontMatter. = 0;
frontMatter. = 250;
frontMatter. = 0;
frontMatter["到期日"] = dayjs().format('YYYY-MM-DD');
frontMatter["间隔"] = 0;
frontMatter["易记因子"] = 250;
frontMatter["重复次数"] = 0;
});
count++; // 增加计数器
notice.setMessage(`重置中... ${count}/${this.allCards.size}`); // 更新 Notice 的消息
notice.setMessage(`重置中... ${count}/${this.enabledCards.size}`); // 更新 Notice 的消息
}
notice.setMessage(`重置完成!共 ${count} 个单词`); // 完成后更新消息
setTimeout(() => notice.hide(), 2000); // 2 秒后自动隐藏 Notice
@ -246,7 +246,7 @@ export default class OpenWords extends Plugin {
// 建立单词双链
async addDoubleBrackets() {
const unmasteredWords = new Set(Array.from(this.allCards.values())
const unmasteredWords = new Set(Array.from(this.enabledCards.values())
.filter(card => card.efactor <= 2.5)
.map(card => card.front)
);
@ -305,7 +305,6 @@ export default class OpenWords extends Plugin {
// 创建索引文件夹 (如果不存在)
const existingIndexFolder = this.app.vault.getFolderByPath(indexDir);
console.log(indexDir,existingIndexFolder)
if (!existingIndexFolder) {
await this.app.vault.createFolder(indexDir);
}
@ -321,7 +320,7 @@ export default class OpenWords extends Plugin {
const frontMatter = this.app.metadataCache.getFileCache(file)?.frontmatter;
if (!frontMatter) continue; // 如果没有 FrontMatter跳过
const tags: string[] = frontMatter.tags || [];
const isMastered = frontMatter?. === true;
const isMastered = frontMatter["掌握"] === true;
for (const level of levels) {
if (tags.includes(level)) {
const letter = file.basename[0].toUpperCase(); // 获取单词首字母
@ -449,7 +448,7 @@ export default class OpenWords extends Plugin {
`| | [n.](单词索引.名词) | [v.](单词索引.动词) | [adj.](单词索引.形容词) | [adv.](单词索引.副词) | [prep.](单词索引.介词) | [pron.](单词索引.代词) | [det.](单词索引.限定词) | [conj.](单词索引.连词) |`,
`| :--------------: | :------------: | :------------: | :---------------: | :--------------: | :---------------: | :---------------: | :---------------: | :---------------: |`,
`| [全索引](单词索引.全索引) | [小学](单词索引.小学) | [中考](单词索引.中考) | [高四](单词索引.高考四级) | [考研](单词索引.考研) | [六级](单词索引.六级) | [雅思](单词索引.雅思) | [托福](单词索引.托福) | [GRE](单词索引.GRE) |`,
`| ${this.alllCards.size} | ${totalWordsList["级别/小学"]} | ${totalWordsList["级别/中考"]} | ${totalWordsList["级别/高考四级"]} | ${totalWordsList["级别/考研"]} | ${totalWordsList["级别/六级"]} | ${totalWordsList["级别/雅思"]} | ${totalWordsList["级别/托福"]} | ${totalWordsList["级别/GRE"]} |`
`| ${this.allCards.size} | ${totalWordsList["级别/小学"]} | ${totalWordsList["级别/中考"]} | ${totalWordsList["级别/高考四级"]} | ${totalWordsList["级别/考研"]} | ${totalWordsList["级别/六级"]} | ${totalWordsList["级别/雅思"]} | ${totalWordsList["级别/托福"]} | ${totalWordsList["级别/GRE"]} |`
];
// 定义字母索引行
@ -698,36 +697,36 @@ class LearningTypeModal extends Modal {
new Setting(buttonContainer)
.setName(`学习新词 ( 重复次数为零, 剩余 ${this.plugin.newCards.size} )`)
.addButton(btn => btn
.setButtonText("开始")
.onClick(() => {
if (this.plugin.newCards.size > 0) {
this.close();
new LearningModal(this.app, this.plugin, 'new').open();
} else {
new Notice("没有新词可学了!");
}
.setButtonText("开始")
.onClick(() => {
if (this.plugin.newCards.size > 0) {
this.close();
new LearningModal(this.app, this.plugin, 'new').open();
} else {
new Notice("没有新词可学了!");
}
}));
new Setting(buttonContainer)
.setName(`复习旧词 ( 重复次数不为零, 剩余 ${this.plugin.dueCards.size} )`)
.addButton(btn => btn
.setButtonText("开始")
.onClick(() => {
if (this.plugin.dueCards.size > 0) {
this.close();
new LearningModal(this.app, this.plugin, 'review').open();
} else {
new Notice("没有需要复习的卡片!");
}
.setButtonText("开始")
.onClick(() => {
if (this.plugin.dueCards.size > 0) {
this.close();
new LearningModal(this.app, this.plugin, 'review').open();
} else {
new Notice("没有需要复习的卡片!");
}
}));
new Setting(buttonContainer)
.setName(`掌握列表 ( 所有单词 )`)
.addButton(btn => btn
.setButtonText("开始")
.onClick(() => {
this.close();
new WordListModal(this.app, this.plugin).open();
.setButtonText("开始")
.onClick(() => {
this.close();
new WordListModal(this.app, this.plugin).open();
}));
new Setting(buttonContainer)
@ -737,16 +736,16 @@ class LearningTypeModal extends Modal {
.onClick(() => {
this.close();
new SpellingModal(this.app, this.plugin).open();
}));
}));
new Setting(buttonContainer)
.setName(`添加双链 ( 作用域中易记因子 <= 2.5 )`)
.addButton(btn => btn
.setButtonText("开始")
.onClick(() => {
this.close();
this.plugin.addDoubleBrackets();
}));
.setButtonText("开始")
.onClick(async () => {
this.close();
await this.plugin.addDoubleBrackets();
}));
}
}
@ -767,10 +766,10 @@ class LearningModal extends Modal {
this.render();
// 监听数字键 0-5 的按键事件
const handleKeydown = (event: KeyboardEvent) => {
const handleKeydown = async (event: KeyboardEvent) => {
if (event.key >= '0' && event.key <= '5') {
const grade = parseInt(event.key) as SuperMemoGrade;
this.rateCard(grade);
await this.rateCard(grade);
}
};
@ -979,7 +978,7 @@ class WordListModal extends Modal {
// 根据筛选条件过滤单词
const filteredWords = Array.from(this.plugin.alllCards.values()).filter(card => {
const filteredWords = Array.from(this.plugin.allCards.values()).filter(card => {
const file = this.plugin.app.vault.getFileByPath(card.path);
if (file instanceof TFile) {
@ -1014,7 +1013,7 @@ class WordListModal extends Modal {
if (!(file instanceof TFile)) return; // 如果文件不存在,直接返回
// 更新单词的掌握状态
await this.plugin.app.fileManager.processFrontMatter(
file, (frontMatter) => {frontMatter. = value;}
file, (frontMatter) => {frontMatter["掌握"] = value;}
);
new Notice(`单词 "${card.front}" 已更新为 ${value ? '掌握' : '未掌握'}`);
});
@ -1072,7 +1071,7 @@ class SpellingModal extends Modal {
const feedbackContainer = contentEl.createDiv({ cls: 'feedback-container' });
// 初始化第一个单词
this.pickNextCard(wordMeaningContainer, inputContainer, feedbackContainer);
await this.pickNextCard(wordMeaningContainer, inputContainer, feedbackContainer);
const handleKeydown = (event: KeyboardEvent) => {
if (event.key === 'Tab') {
@ -1103,7 +1102,7 @@ class SpellingModal extends Modal {
inputContainer: HTMLElement,
feedbackContainer: HTMLElement
) {
const cards = Array.from(this.plugin.allCards.values());
const cards = Array.from(this.plugin.enabledCards.values());
if (cards.length === 0) {
feedbackContainer.setText('没有更多单词了!');
return;
@ -1179,9 +1178,9 @@ class SpellingModal extends Modal {
if (userInput.length === word.length) {
if (userInput.toLowerCase() === word.toLowerCase()) {
feedbackContainer.setText('正确!');
setTimeout(() => {
this.pickNextCard(wordMeaningContainer, inputContainer, feedbackContainer);
}, 500);
setTimeout(async () => {
await this.pickNextCard(wordMeaningContainer, inputContainer, feedbackContainer);
}, 500);
} else {
feedbackContainer.setText('错误,请重试!');
inputFields.forEach((field) => (field.value = '')); // 清空所有输入框

View file

@ -1,7 +1,7 @@
{
"id": "openwords",
"name": "OpenWords",
"version": "1.0.1",
"version": "1.0.2",
"minAppVersion": "1.8.10",
"description": "用于英语学习中背单词与单词管理的插件",
"author": "insile",

288
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "openwords",
"version": "1.0.0",
"version": "1.0.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "openwords",
"version": "1.0.0",
"version": "1.0.2",
"license": "MIT",
"dependencies": {
"dayjs": "^1.11.13",
@ -19,7 +19,7 @@
"@typescript-eslint/eslint-plugin": "5.29.0",
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.17.3",
"esbuild": "^0.25.4",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
@ -49,10 +49,27 @@
"w3c-keyname": "^2.2.4"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz",
"integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.3.tgz",
"integrity": "sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz",
"integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==",
"cpu": [
"arm"
],
@ -63,13 +80,13 @@
"android"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz",
"integrity": "sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz",
"integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==",
"cpu": [
"arm64"
],
@ -80,13 +97,13 @@
"android"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.3.tgz",
"integrity": "sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz",
"integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==",
"cpu": [
"x64"
],
@ -97,13 +114,13 @@
"android"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz",
"integrity": "sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz",
"integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==",
"cpu": [
"arm64"
],
@ -114,13 +131,13 @@
"darwin"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz",
"integrity": "sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz",
"integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==",
"cpu": [
"x64"
],
@ -131,13 +148,13 @@
"darwin"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz",
"integrity": "sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz",
"integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==",
"cpu": [
"arm64"
],
@ -148,13 +165,13 @@
"freebsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz",
"integrity": "sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz",
"integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==",
"cpu": [
"x64"
],
@ -165,13 +182,13 @@
"freebsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz",
"integrity": "sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz",
"integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==",
"cpu": [
"arm"
],
@ -182,13 +199,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz",
"integrity": "sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz",
"integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==",
"cpu": [
"arm64"
],
@ -199,13 +216,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz",
"integrity": "sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz",
"integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==",
"cpu": [
"ia32"
],
@ -216,13 +233,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz",
"integrity": "sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz",
"integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==",
"cpu": [
"loong64"
],
@ -233,13 +250,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz",
"integrity": "sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz",
"integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==",
"cpu": [
"mips64el"
],
@ -250,13 +267,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz",
"integrity": "sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz",
"integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==",
"cpu": [
"ppc64"
],
@ -267,13 +284,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz",
"integrity": "sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz",
"integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==",
"cpu": [
"riscv64"
],
@ -284,13 +301,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz",
"integrity": "sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz",
"integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==",
"cpu": [
"s390x"
],
@ -301,13 +318,13 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz",
"integrity": "sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz",
"integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==",
"cpu": [
"x64"
],
@ -318,13 +335,30 @@
"linux"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz",
"integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz",
"integrity": "sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz",
"integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==",
"cpu": [
"x64"
],
@ -335,13 +369,30 @@
"netbsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz",
"integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz",
"integrity": "sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz",
"integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==",
"cpu": [
"x64"
],
@ -352,13 +403,13 @@
"openbsd"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz",
"integrity": "sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz",
"integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==",
"cpu": [
"x64"
],
@ -369,13 +420,13 @@
"sunos"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz",
"integrity": "sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz",
"integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==",
"cpu": [
"arm64"
],
@ -386,13 +437,13 @@
"win32"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz",
"integrity": "sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz",
"integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==",
"cpu": [
"ia32"
],
@ -403,13 +454,13 @@
"win32"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz",
"integrity": "sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz",
"integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==",
"cpu": [
"x64"
],
@ -420,7 +471,7 @@
"win32"
],
"engines": {
"node": ">=12"
"node": ">=18"
}
},
"node_modules/@eslint-community/eslint-utils": {
@ -1111,9 +1162,9 @@
"license": "MIT"
},
"node_modules/esbuild": {
"version": "0.17.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.3.tgz",
"integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==",
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz",
"integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@ -1121,31 +1172,34 @@
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/android-arm": "0.17.3",
"@esbuild/android-arm64": "0.17.3",
"@esbuild/android-x64": "0.17.3",
"@esbuild/darwin-arm64": "0.17.3",
"@esbuild/darwin-x64": "0.17.3",
"@esbuild/freebsd-arm64": "0.17.3",
"@esbuild/freebsd-x64": "0.17.3",
"@esbuild/linux-arm": "0.17.3",
"@esbuild/linux-arm64": "0.17.3",
"@esbuild/linux-ia32": "0.17.3",
"@esbuild/linux-loong64": "0.17.3",
"@esbuild/linux-mips64el": "0.17.3",
"@esbuild/linux-ppc64": "0.17.3",
"@esbuild/linux-riscv64": "0.17.3",
"@esbuild/linux-s390x": "0.17.3",
"@esbuild/linux-x64": "0.17.3",
"@esbuild/netbsd-x64": "0.17.3",
"@esbuild/openbsd-x64": "0.17.3",
"@esbuild/sunos-x64": "0.17.3",
"@esbuild/win32-arm64": "0.17.3",
"@esbuild/win32-ia32": "0.17.3",
"@esbuild/win32-x64": "0.17.3"
"@esbuild/aix-ppc64": "0.25.4",
"@esbuild/android-arm": "0.25.4",
"@esbuild/android-arm64": "0.25.4",
"@esbuild/android-x64": "0.25.4",
"@esbuild/darwin-arm64": "0.25.4",
"@esbuild/darwin-x64": "0.25.4",
"@esbuild/freebsd-arm64": "0.25.4",
"@esbuild/freebsd-x64": "0.25.4",
"@esbuild/linux-arm": "0.25.4",
"@esbuild/linux-arm64": "0.25.4",
"@esbuild/linux-ia32": "0.25.4",
"@esbuild/linux-loong64": "0.25.4",
"@esbuild/linux-mips64el": "0.25.4",
"@esbuild/linux-ppc64": "0.25.4",
"@esbuild/linux-riscv64": "0.25.4",
"@esbuild/linux-s390x": "0.25.4",
"@esbuild/linux-x64": "0.25.4",
"@esbuild/netbsd-arm64": "0.25.4",
"@esbuild/netbsd-x64": "0.25.4",
"@esbuild/openbsd-arm64": "0.25.4",
"@esbuild/openbsd-x64": "0.25.4",
"@esbuild/sunos-x64": "0.25.4",
"@esbuild/win32-arm64": "0.25.4",
"@esbuild/win32-ia32": "0.25.4",
"@esbuild/win32-x64": "0.25.4"
}
},
"node_modules/escape-string-regexp": {

View file

@ -1,6 +1,6 @@
{
"name": "openwords",
"version": "1.0.0",
"version": "1.0.2",
"description": "用于英语学习中背单词与单词管理的插件",
"main": "main.js",
"scripts": {
@ -22,7 +22,7 @@
"@typescript-eslint/eslint-plugin": "5.29.0",
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.17.3",
"esbuild": "^0.25.4",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"

View file

@ -7,15 +7,8 @@ If your plugin does not need CSS, delete this file.
*/
/* 学习模式标题 */
.type-title {
text-align: center;
margin-bottom: 20px;
font-size: 1.5em;
font-weight: bold;
}
/* 设置 */
/* 插件设置选项卡 */
.openwords-toggle-grid {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 每行 4 列 */
@ -27,9 +20,17 @@ If your plugin does not need CSS, delete this file.
border-top: 1px solid var(--background-modifier-border)
}
/* 学习模式模态框 */
.type-title {
text-align: center;
margin-bottom: 20px;
font-size: 1.5em;
font-weight: bold;
}
.type-modal{
width: 650px; /* 设置模态框宽度 */
}
/* 卡片容器样式 */
.anki-card {
width: 500px; /* 固定宽度 */

View file

@ -1,3 +1,3 @@
{
"1.0.1": "1.8.10"
"1.0.2": "1.8.10"
}