//flashDict 英汉词典
import fonts.fontAwesome;
import web.form.chat;
import win.ui;
import com.wmPlayer;
import fsys.table;
import string.words;
namespace win.dlg;
class flashDict{
ctor(parent,keyWord){
/*DSG{{*/
this = ..win.form(text="AI 英汉词典";right=619;bottom=636;bgcolor=0xFFFFFF;exmode="none";mode="popup";parent=parent)
this.add(
btnSearch={cls="plus";left=478;top=15;right=508;bottom=41;align="left";border={bottom=1;color=0xFF969696};color=0x3C3C3C;dr=1;dt=1;font=LOGFONT(h=-13);iconStyle={align="left";font=LOGFONT(h=-13;name='FontAwesome');padding={left=8}};iconText='\uF002';notify=1;textPadding={left=25};z=3};
btnVoice={cls="plus";text="真人朗读";left=526;top=13;right=617;bottom=42;align="left";bgcolor=0xFFFFFF;color=0x3C3C3C;dr=1;dt=1;font=LOGFONT(h=-13);iconColor=0x008000;iconStyle={align="left";font=LOGFONT(h=-13;name='FontAwesome');padding={left=8}};iconText='\uF028';notify=1;textPadding={left=25};z=2};
custom={cls="custom";text="自定义控件";left=7;top=59;right=609;bottom=628;db=1;dl=1;dr=1;dt=1;z=1};
editKeyword={cls="plus";left=230;top=15;right=477;bottom=41;align="right";border={bottom=1;color=0xFF969696};dr=1;dt=1;editable="edit";font=LOGFONT(h=-13);notify=1;textPadding={top=3;bottom=3};z=4}
)
/*}}*/
var chatUi = ..web.form.chat(this.custom);
chatUi.renderPollinationsAsImg = true;
if(!keyWord)this.editKeyword.setCueBannerText("请输入搜索词,支持模式匹配语法");
else this.btnSearch.disabled = true;
this.editKeyword.editBox.disableInputMethod();
..win.showForeground(this.hwnd);
var tip = /*
- 速度飞快的 AI 英汉小词典。
本地极速词库 + COCA 词库表(例句) + AI 大模型辅助查词
自定义 AI 接口
- 韦氏词典真人发音
- 点例句后的「🔊」可以仿真人语音朗读例句。
每个例句首次朗读时要略等一会,按住 Shift 键点「🔊」可以较慢速度朗读。
在 「🔊」链接获得焦点时也可以按 Enter 键朗读例句
- 按 Enter 键查词
- 自动绘制 AI 单词卡,可拖拽单词卡到桌面悬浮窗
> [ImTip](https://imtip.aardio.com/) 默认提供超级热键:
> Ctrl+Shif+# 快速调用 AI 查词。
>
> [超级热键配置](https://www.aardio.com/zh-cn/doc/library-guide/std/key/hotkey.html#flashDict)
*/
chatUi.write(tip);
import ..table.coca20000;
chatUi.doScript("
document.onmouseup = document.onselectionchange = function() {
var text = '';
if (window.getSelection) {
var selection = window.getSelection();
if (selection.rangeCount === 0) {
return null;
}
text = tostring(selection);
} else if (document.selection && document.selection.type != 'Control') {
text = document.selection.createRange().text;
}
if(text) external.onSelectedText(text)
};")
var soundUrlCache = ..table.cache();
var pronounce = function(word,site){
var url;
if(site=="youdao"){
url = "https://dict.youdao.com/dictvoice?audio="+word+"&type=2"
}
else{
url = soundUrlCache[word] || ..thread.invokeAndWait(
function(word){
import ..web.rest.htmlClient;
var http = ..web.rest.htmlClient();
var webster = http.api("https://www.merriam-webster.com/dictionary/","GET");
var htmlDoc = webster[word].get();//抓取韦氏词典网页
var ele = htmlDoc.queryEle({"class":"play-pron-v2"});//获取指定 HTML 元素
var url;
if(ele && ele["data-dir"] && ele["data-file"]){
//合成韦氏词典美式发音链接
url = "https://media.merriam-webster.com/audio/prons/en/us/mp3/" + ele["data-dir"] + "/" + ele["data-file"] + ".mp3"
}
else{
//合成柯林斯词典美式发音链接
url = "https://www.collinsdictionary.com/sounds/hwd_sounds/en_us_"+..string.lower(word)+".mp3"
}
return url;
} ,word
)
soundUrlCache[word] = url;
if(this.btnVoice.disabledText) this.btnVoice.disabledText = ['\uF026','\uF027','\uF028'];
}
..com.wmPlayer.url = url;
}
this.btnVoice.skin({
color={
active=0xFF00FF00;
default=0xFF3C3C3C;
disabled=0xFF999999;
hover=0xFFFF0000
}
})
import ..web.edgeTextToSpeech;
import ..bass.channel;
this.btnVoice.oncommand = function(id,event){
var word = ..string.trim(this.editKeyword.text);
if(!#word) {
this.msgboxErr("请输入搜索词,支持模式匹配语法!");
this.editKeyword.setFocus();
return;
}
this.btnVoice.disabledText = ['\uF254','\uF251','\uF252','\uF253','\uF250'];
pronounce(word,"webster");
..thread.delay(1500);
this.btnVoice.disabledText = null;
}
import ..win.ui.loadingMask;
var mask = ..win.ui.loadingMask(this);
import ..win.debounce;
chatUi.external = {
onDragImageStart = function(imageUrl){
this.setTimeout( function(){
import key;
..key.press("ESC");
var frmImage = ..win.form(text="aardio form";right=359;bottom=359;border="none";max=false;topmost=1)
frmImage.add(
btnClose={cls="close";text="×";left=327;top=5;right=355;bottom=33;bgcolor=0xCC8B94;dr=1;dt=1;font=LOGFONT(h=-21);z=2};
plus={cls="plus";left=0;top=0;right=360;bottom=360;db=1;dl=1;dr=1;dt=1;repeat="scale";z=1}
)
frmImage.btnClose.show(true);
frmImage.btnClose.oncommand = function(id,event){
frmImage.close();
}
frmImage.onMouseDown = function(wParam,lParam){
frmImage.hitCaption();
}
import ..win.ui.shadow;
..win.ui.shadow(frmImage);
import ..inet.http;
frmImage.plus.background = imageUrl;
frmImage.show();
frmImage.hitCaption();
chatUi.getEle("draggableImage").outerHTML = ""
},1);
};
onSelectedText = ..win.debounce(function(text,left,top,right,bottom){
import ..winex.tooltip;
if(#text){
var meaning,word = ..string.words(text);
if(meaning){
var x,y = ..win.getMessagePos();
y = y + this.dpiScale(25)
..winex.tooltip.balloon(meaning,x,y);
if(!this.btnVoice.disabled){
pronounce(word,"youdao");
}
return;
}
}
..winex.tooltip.balloon(false);
},500);
tts = function(){
if(chatUi.cocaSentence){
if(this.btnVoice.disabled) {
return;
}
import key;
var slower = ..key.getState("Shift");
var playMp3 = function(){
this.btnVoice.disabledText = ['\uF026','\uF027','\uF028'];
var audio = ..bass.channel.open(..string.load("\mini-dict-sentence-tts.mp3"));
audio.syncCallback(function(data){
audio.free()
this.btnVoice.disabledText = null;
},2/*_BASS_SYNC_END*/)
if(slower){
audio.setSpeed(0.85);
}
audio.play()
return;
}
if( ..io.exist("\mini-dict-sentence-tts.mp3") ){
return playMp3();
}
mask.show();
this.btnVoice.disabledText = ['\uF254','\uF251','\uF252','\uF253','\uF250'];
var tts = ..web.edgeTextToSpeech(chatUi.cocaSentence,"\mini-dict-sentence-tts.mp3")
tts.voiceOptions.name = "en-US-AriaNeural"
tts.voiceOptions.rate = "-10%"
tts.OnResponseEnd = function(path){
mask.show(false);
return playMp3();
}
tts.OnError = function(sender, e){
this.btnVoice.disabledText = null;
mask.show(false);
}
//连接服务器,合成语音
tts.ConnectAsync();
return;
}
};
aiSetting = function(){
..table.assign(config,{
title = "aardio - 设置 AI 英汉词典";
});
import web.rest.aiChat.settingForm;
var frmSetting = web.rest.aiChat.settingForm(this,config);
if( frmSetting.doModal(this) ){
var configItem = config.selItem ? config.itemData[config.selItem]
}
this.editKeyword.setFocus();
};
}
this.btnSearch.skin({
color={
active=0xFF00FF00;
default=0xFF3C3C3C;
disabled=0xFF6D6D6D;
hover=0xFFFF0000
}
})
this.editKeyword.editBox.onChange = function(){
..io.remove("/mini-dict-sentence-tts.mp3");
}
this.btnSearch.oncommand = function(id,event){
var word = ..string.trim(this.editKeyword.text);
if(!#word) {
this.msgboxErr("请输入搜索词,支持模式匹配语法!");
this.editKeyword.setFocus();
return;
}
this.btnSearch.disabledText = ['\uF254','\uF251','\uF252','\uF253','\uF250']
chatUi.clear();
var meaning,word2 = ..string.words(word)
var output = ""
if(meaning){
meaning = ..string.replace(meaning,'\n',' \n');
output = '## 释义\n' + meaning + '\n\n'
}
var sentence;
for(i,wordInfo in ..table.coca20000){
if(wordInfo.word == word){
if(wordInfo.sentence){
output = output + '## 例句\n' + ..string.replace(wordInfo.sentence,'\n',' 🔊
\n') + '\n\n';
chatUi.cocaSentence = ..string.match(wordInfo.sentence,"(.+?)<::>?=");
sentence = true;
}
}
}
if(sentence){
chatUi.writeDelta(output)
chatUi.showLoading("AI 正在思考 ……");
chatUi.chatMessage.system("
你是一位英语教授,
你的任务是根据输入单词完成一系列英语学习相关的任务。
以下是输入的单词:
<单词>
{{WORD}}
单词>
请完成以下具体任务:
### 任务1: 要点
**用中文讲解此单词的主要用法、使用要点、需要注意的问题。这是所有任务中最重要的部分!**
### 任务2:词根词缀
用中文讲述该单词的**词根词缀起源故事**。
### 任务3:相近词
用这个单词的词根词缀,拓展 5 个相近单词,附带**词性**和**中文释义**。
### 任务4:小作文
请根据前面所有任务的内容编写一个有趣的 A2 难度英文故事,限 7 行内。并附上中文翻译(不要添加“中文翻译:”标题)。
### 任务5:小测验
基于前 4 个任务生成的内容创造 1 个单选题,最后一起给出答案。
### 任务6:绘制单词卡
请用英文生动的描述要绘制的单词助记卡(单词卡上要用文字清晰地显示单词{{WORD}},但不要显示其他文本)并生成链接,例如 `https://image.pollinations.ai/prompt/vocabulary%20flashcard%3a%20%22{WORD}`
请按照以下 Markdown 格式排版输出你的结果:
### 要点
### 词根词缀
### 相近词
### 小作文
### 小测验
问题
- [ ] A. 选项1
- [ ] B. 选项2
- [ ] C. 选项3
查看答案
A
正在绘制单词卡 ...
请在这里用英文生动地描述要绘制的单词卡
");
}
else{
if(meaning){
chatUi.writeDelta("> " + ..string.replace(meaning,'\n','\n> ') + '\n\n');
}
chatUi.showLoading("AI 正在思考 ……");
var userSystem = config.systemPrompt;
if(#userSystem){
chatUi.chatMessage.System(userSystem);
}
chatUi.chatMessage.system("
你是一位英语教授,
你的任务是根据输入单词完成一系列英语学习相关的任务。
以下是输入的单词:
<单词>
{{WORD}}
单词>
请完成以下具体任务:
### 任务1:单词释义
- 列出单词包含的所有词性对应的**词性**、所有的**中文释义**和**英文释义**,一行一个。
- 如果单词是动词,要展示**现在分词**、**过去式**、**过去分词**;如果是名词,要展示**第三人称单数**;如果是形容词,要展示**比较级**和**最高级**。
### 任务2:例句
根据任务2提及的要点,用这个单词造 3 个英文例句(对任务2提及的要点、短句可以加粗显示),并附上中文翻译。
### 任务3: 要点
**用中文讲解此单词的主要用法、使用要点、需要注意的问题。这是所有任务中最重要的部分!**
### 任务4:词根词缀
用中文讲述该单词的**词根词缀起源故事**。
### 任务5:相近词
用这个单词的词根词缀,拓展 5 个相近单词,附带**词性**和**中文释义**。
### 任务6:小作文
请根据任务2、任务3、任务 5的内容编写一个有趣的 A2 难度英文故事,限 7 行内。并附上中文翻译(不要添加“中文翻译:”标题)。
### 任务7:小测验
基于前 6 个任务生成的内容创造 1 个单选题,最后一起给出答案。
### 任务8:绘制单词卡
请用英文生动的描述要绘制的单词助记卡(单词卡上要用文字清晰地显示单词{{WORD}},但不要显示其他文本)并生成链接,例如 `https://image.pollinations.ai/prompt/vocabulary%20flashcard%3a%20%22{WORD}`
请按照以下 Markdown 格式排版输出你的结果:
### 释义
### 例句
### 要点
### 词根词缀
### 相近词
### 小作文
### 小测验
问题
- [ ] A. 选项1
- [ ] B. 选项2
- [ ] C. 选项3
查看答案
A
正在绘制单词卡 ...
请在这里用英文生动地描述要绘制的单词卡
");
}
//添加用户提示词,界面上不显示
chatUi.chatMessage.prompt( word );
//创建 AI 对话线程
..thread.invoke(
function(this,chatUi,config){
//创建 AI 客户端
import ..web.rest.aiChat;
config.userAgent = "Mozilla/5.0 (Windows NT "+ _WIN_VER_MAJOR +"."+_WIN_VER_MINOR+"; win.dlg.flashDict) like Gecko";
var aiClient = ..web.rest.aiChat(config)
//调用聊天接口。
var ok,err = aiClient.messages(chatUi.chatMessage,
function(deltaText,reasoning){
//输出思考过程
if(reasoning) {
chatUi.showThinking(reasoning);
}
//输出回复,自带高性能 Markdown 解析器。
chatUi.assistant(deltaText);
}
);
if(err){
chatUi.errorMessage(err)
}
this.btnSearch.disabledText = null;
},this,chatUi,config
)
pronounce(word,"youdao");
}
import ..com.autoComplete;
var aco = ..com.autoComplete(this.editKeyword);
var items = []
for(k,v in ..table.coca20000){
..table.push(items,v.word);
}
aco.setStrings(items);
this.editKeyword.setFocus();
this.editKeyword.editBox.onOk = function(ctrl,alt,shift){
aco.hide();
this.btnSearch.oncommand();
return true; //允许继续发送按键以关闭自动完成列表
}
if(keyWord){
this.editKeyword.text = keyWord;
this.btnSearch.oncommand();
}
};
}
namespace flashDict{
config = ..fsys.table(..io.appData("aardio/std/winex/flashDict.table"),{
key = '\0\1\96';
url = "https://ai.aardio.com/api/v1/";
model = "flash-dict";
})
isWord = lambda (word)..string.words(word,true);
}
if( !owner ) ..win.dlg.flashDict(,).doModal();
/**intellisense()
win.dlg.flashDict(.(parent,keyWord) = 创建英汉词典窗口,返回 win.form 对象。\n可选用参数 @parent 指定父窗口,可选用参数 @keyWord 指定立即查询的单词。
win.dlg.flashDict() = !winform.
win.dlg.flashDict.isWord(__/*字符串*/) = 检查输入字符串是否仅包含英文单词(忽略首尾空格)。\n此函数实际是调用 `string.words(word,true/*仅测试*/)`。\n等价于调用 `string.find(txt,"^\s*(<\d+\->?\a[\a\-\.é'’]*)\s*$")`
end intellisense**/