ctrl+alt+x 只显示文字外观窗口一部分
openAny.setKeymap('ctrl+alt+x', async (event, {newSetStyle})=>{
const setStyle = newSetStyle();
// 设置样式
setStyle(`.protyle-font > *:not(:nth-child(7),:nth-child(8)):not(:last-child) {
display:none;
}`);
// 等待外观窗口出现
await openAny.getEl('.protyle-util:not(.fn__none)');
// 等待外观窗口关闭
await openAny.getEl('.protyle-util.fn__none', null, -1);
// 删除样式,不影响后续操作
setStyle('');
});
alt+z 给文字添加指定颜色和背景色
openAny.setKeymap('alt+z', (event)=>{event.preventDefault();openAny.press('ctrl+alt+x', document.activeElement).clicks('.protyle-util [style="color:var(--b3-font-color9)"]', '.protyle-util [style="background-color:var(--b3-font-background6)"]').invoke(()=>openAny.queryEl('.protyle-util:not(.fn__none)')?.classList?.add('fn__none'))});
打开代码片段窗口
openAny.clicks('#barWorkspace', '[data-id="config"]', '[data-name="appearance"]', '#codeSnippet', '[data-key="dialog-setting"] svg.b3-dialog__close');
打开设置窗口
openAny.click('#barWorkspace').click('[data-id="config"]');
// 或
openAny.pressByKeymap('config');
模式切换(预览和所见即所得切换,按ctrl+alt+7即可)
setTimeout(()=>{
openAny.addKeymap('alt+meta+7', ()=>{
const isPreview = document.querySelector('.protyle-preview:not(.fn__none) .protyle-preview__action');
setTimeout(()=>{if(!isPreview) openAny.press('alt+meta+9');}, 50);
});
}, 1500);
ctrl+shif+p 全局搜索仅搜文档(不影响原有搜索状态)
// ctrl+shif+p 全局搜索仅搜文档(不影响原有搜索状态)
(async ()=>{
// 等待openAny加载完毕
await waitFor(() => typeof openAny !== 'undefined');
// 注册快捷键
const ctrl = navigator.platform.indexOf("Mac") > -1 ? 'meta' : 'ctrl';
openAny.setKeymap(`shift+${ctrl}+p`, async (event, {getSelectedText}) => {
openAny
.press(`${ctrl}+p`) // 打开搜索框
.click("#searchFilter") // 点击类型过滤按钮
.input(getSelectedText(), "#searchInput") // 搜索框置空
.invoke(async ({sleep,whenElementRemoved}) => {
// 【注意】invoke内部建议用新的OpenAny对象,防止用await时与上层链相互等待造成死锁
const openAny = new OpenAny();
// 获取当前的文档类型
const oldTypes = siyuan?.storage['local-searchdata']?.types;
// 查询所有文档类型,仅保留文档类型打开,其他全关闭
openAny
.queryElAll('[data-key="dialog-searchtype"] [type="checkbox"]')
.forEach(async (checkbox) =>
checkbox.matches('[data-type="document"]')
? !checkbox.checked && checkbox.click()
: checkbox.checked && checkbox.click()
);
// 点击确定按钮
openAny.click('[data-key="dialog-searchtype"] .b3-dialog__action .b3-button--text')
await sleep(100); // 等待100ms
openAny.focus("#searchInput"); // 聚焦搜索框
// placehoder
openAny.queryEl('#searchInput').placeholder = '请输入文档标题';
// 等待搜索对话框被关闭
whenElementRemoved('[data-key="dialog-globalsearch"]', ()=>{
// 恢复原本的文档类型
if(oldTypes) siyuan.storage['local-searchdata'].types = oldTypes;
});
});
});
function waitFor(conditionFn, timeoutMs=5000) {
return new Promise((resolve, reject) => {
const start = Date.now();
const check = () => {
if(typeof conditionFn === 'string')
conditionFn = () => document.querySelector(conditionFn);
const result = conditionFn();
if (result) resolve(result);
else if (Date.now() - start > timeoutMs) reject();
else requestAnimationFrame(check); // 利用浏览器刷新周期
};
check();
});
}
})();
快速输入,灵感输入
// 快速输入,灵感记录等
(async ()=>{
// 请填写灵感即将保存的文档ID
const captureDocId = '20250307013535-lreu6jb';
// 是否按回车键提交
// 当为 true 时,回车键提交,shift+回车 换行
// 当为 false 时,回车换行,ctrl+回车 提交
const enterSubmit = true;
// 输入框显示行数,默认3行,当行数是1时,无法换行,同时始终回车提交
const inputLines = 3;
// 等待openAny加载完毕
await waitFor(() => typeof openAny !== 'undefined');
// 注册快捷键
openAny.setKeymap("alt+i", async (event, {fetchSyncPost, showInputBox}) => {
const input = await showInputBox("", "", "", inputLines, enterSubmit);
if(!input) return;
const result = await fetchSyncPost('/api/block/insertBlock', {
"dataType": "markdown",
"data": getFormattedDateTime() + "\n{: style=\"color:#989898;\"}\n" + input + "\n---",
"nextID": "",
"previousID": "",
"parentID": captureDocId
});
console.log(result);
});
function getFormattedDateTime() {
const now = new Date();
// 获取年、月、日、时、分、秒
const year = now.getFullYear(); // 年
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月(注意月份从 0 开始,需要加 1)
const day = String(now.getDate()).padStart(2, '0'); // 日
const hours = String(now.getHours()).padStart(2, '0'); // 时
const minutes = String(now.getMinutes()).padStart(2, '0'); // 分
const seconds = String(now.getSeconds()).padStart(2, '0'); // 秒
// 拼接成字符串
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
function waitFor(conditionFn, timeoutMs=5000) {
return new Promise((resolve, reject) => {
const start = Date.now();
const check = () => {
if(typeof conditionFn === 'string')
conditionFn = () => document.querySelector(conditionFn);
const result = conditionFn();
if (result) resolve(result);
else if (Date.now() - start > timeoutMs) reject();
else requestAnimationFrame(check); // 利用浏览器刷新周期
};
check();
});
}
})();
快速打开(支持搜索,翻译,ai搜索,常用工具快捷打开,打开常用文档,打开本地工具等)
// 快速打开自定义功能
// see https://ld246.com/article/1745488922117
// version 0.0.2
// 0.0.2 增加快捷键支持,把思源命令面板的命令移植过来
// 使用帮助
// 建议把代码放到runjs插件的代码块中方便修改和添加菜单项(当然直接把该代码放到js代码片段中也行,代码片段修改后需要刷新页面)
// 然后,把下面的这行代码放到js代码片段中加载时运行即可(注意,外部调用runjs代码块,先要给块命名,然后保存为可调用的方法)
// runjs调用 runJs.plugin.call('quickOpen')
// runjs中修改代码后,只需点击「块菜单——>Run JS——> 运行代码」即可
// 或将光标聚焦在代码块中,然后按 alt + F5 即可运行当前的代码块
// 如何添加新菜单?
// 只需要“自定义菜单区 开始”和“自定义菜单区 结束”直接添加 addMenu('菜单名', ()=>{})即可
// 比如:addMenu('demo1', (event, functions, option, selection)=>{alert('demo1')}, 'D', 'shortcut'); 这里第三个参数D代表当菜单出现时按D键直接选中demo1这个菜单
(async (menus = [], pressKey = '' /* 👈修改快捷键可在这里修改pressKey,默认ctrl+; 修改后pressKey后需要刷新页面 */)=>{
///////////////////////////////// 自定义菜单区 开始 /////////////////////////////////
// 打开本代码片编辑窗口
addMenu('打开本代码片编辑窗口', (event, {getProtyleEl, showErrorMessage}) => {
// 如果在runjs代码块中,设置这个代码块的可调用方法名,如果不在runjs中保持空或注释即可
const runjsCallableName = 'quickOpen';
// 如果在代码片段中,设置这个代码片段的名字,如果不在代码片段中保持空或注释即可
const snippetName = '快速打开自定义功能';
// 当二者都配置的话,runjs优先(代码片段修改代码后需要刷新页面,runjs只需要按alt+f5即可)
if(typeof runjsCallableName !== 'undefined' && runjsCallableName) {
const codeBlockId = window.siyuan.ws.app.plugins.find(item=>item.name==='sy-run-js')?.data["Callable.json"]?.quickOpen;
if(!codeBlockId) showErrorMessage('没有找到'+runjsCallableName+'的代码块');
window.open('siyuan://blocks/'+codeBlockId);
} else {
openAny.clicks('#barWorkspace', '[data-id="config"]', '[data-name="appearance"]', '#codeSnippet', '[data-key="dialog-setting"] svg.b3-dialog__close', '[data-type="js"]').input(typeof snippetName === 'undefined' ? '' : snippetName, '[data-action="search"][data-type="js"]');
}
}, 'E');
// 移动当前文档到
addMenu('移动当前文档到', (event, {getProtyleEl}) => {
openAny.click('[data-type="doc"]', getProtyleEl()).click('[data-name="titleMenu"] button[data-id="move"]');
}, 'M');
// Bing搜索
addMenu('Bing搜索', (event, {getSelectedText}) => {
// 搜索引擎URL,%s% 是搜索关键词
const searchUrl = 'https://cn.bing.com/search?q=%s%&form=QBRE';
window.open(searchUrl.replace('%s%', getSelectedText()));
}, 'B');
// 问DeepSeek
addMenu('问DeepSeek', (event, {getSelectedText}) => {
// ai引擎URL,%s% 是查询关键词,支持deepseek-r1
const aiUrl = 'https://chat.baidu.com/search?word=%s%';
window.open(aiUrl.replace('%s%', getSelectedText()));
}, 'D');
// 打开翻译
addMenu('打开翻译', (event, {getSelectedText}) => {
// 翻译引擎URL,%s% 是翻译关键词
const fanyiUrl = 'https://fanyi.baidu.com/mtpe-individual/multimodal?query=%s%';
window.open(fanyiUrl.replace('%s%', getSelectedText()));
}, 'T');
// 打开查词
addMenu('打开查词', (event, {getSelectedText}) => {
const url = 'https://www.iciba.com/word?w=%s%';
window.open(url.replace('%s%', getSelectedText()));
});
// 打开设置
addMenu('打开设置', (event, {}) => {
openAny.pressByKeymap('config');
});
// 打开日记
addMenu('打开日记', (event, {}) => {
// 在这里输入你想在哪个笔记本中打开今日日记
const noteBookName = '我的笔记';
// 这里用wwhenExist先等待指定元素出现,否则需要在do内调用 await new OpenAny().whenExist()等待目标出现
openAny.click('#barWorkspace').whenExist('[data-name="barWorkspace"]').do(()=>{
const subMenuItems = [...openAny.queryElAll('[data-id="dailyNote"] .b3-menu__label')];
const notebutton = subMenuItems.find(item => item.textContent === noteBookName)?.closest('button.b3-menu__item');
// 返回链元素,供下一个链click调用,也可以直接在这里click,不用再次调用下一个链click
return notebutton;
}).click();
});
// 打开集市
addMenu('打开集市', (event, {}) => {
openAny.clicks('#barWorkspace', '[data-id="config"]', '[data-name="bazaar"]');
});
// 打开代码片段
addMenu('打开代码片段', (event, {}) => {
openAny.clicks('#barWorkspace', '[data-id="config"]', '[data-name="appearance"]', '#codeSnippet', '[data-key="dialog-setting"] svg.b3-dialog__close');
}, 'S');
// 打开快捷键设置
addMenu('打开快捷键设置', (event, {}) => {
openAny.clicks('#barWorkspace', '[data-id="config"]', '[data-name="keymap"]');
});
// 打开搜索
addMenu('打开思源搜索', (event, {}) => {
openAny.press('alt+p');
});
// 打开仅搜索文档
addMenu('打开仅搜索文档', (event, {}) => {
// 请参考 ctrl+shif+p 全局搜索仅搜文档,然后把这个快捷键填尽量
openAny.press('ctrl+shif+p');
}, 'P');
// 模式切换
addMenu('模式切换', (event, {}) => {
const isPreview = document.querySelector('.protyle-preview:not(.fn__none) .protyle-preview__action');
if(!isPreview) openAny.press('alt+meta+9'); else openAny.press('alt+meta+7');
}, '7');
// 打开链滴
addMenu('打开链滴', (event, {}) => {
window.open('https://ld246.com');
});
// 打开我的博客
addMenu('打开我的博客', (event, {}) => {
window.open('https://pipe.b3log.org/blogs/wilsons');
});
// 打开思源工作空间
addMenu('打开思源工作空间', (event, {showFileInFolder}) => {
showFileInFolder(window.siyuan.config.system.workspaceDir);
});
// 打开计算器
addMenu('打开计算器', (event, {runCmd, isMac}) => {
let cmd = `start calc`;
if(isMac()) cmd = `open -a Calculator`;
runCmd(cmd);
}, 'C');
// 字母大小写转换
addMenu('字母大小写转换', (event, {getEditor}, option, {selectedText, selection, range}) => {
let text = selectedText;
if(/[a-z]/.test(text)) {
text = text.toUpperCase();
} else {
text = text.toLowerCase();
}
// 替换选中的文本
range.deleteContents();
range.insertNode(document.createTextNode(text));
// 恢复选中范围
selection.removeAllRanges();
selection.addRange(range);
//const editor = getEditor();
//openAny.sendText(text, editor);
});
///////////////////////////////// 自定义菜单区 结束 /////////////////////////////////
// 等待openAny加载完毕
await waitFor(() => typeof openAny !== 'undefined');
// 生成菜单列表
const handler = async (event, functions)=>{
event.preventDefault();
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const selectedText = selection.toString();
const lastSelected = await getStorageVal('local-quickopen-selected');
if(lastSelected) {
const lastSelectedItem = menus.find(item=>item.selected);
if(lastSelectedItem) lastSelectedItem.selected=false;
const selectedItem = menus.find(item=>item.label===lastSelected);
if(selectedItem) selectedItem.selected=true;
}
functions.whenElementExist('.open-any-menu-title:not([data-reward="true"])').then((title)=>{
const search = title.querySelector('.open-any-menu-search');
if(search) {
search.style.width = 'calc(100% - 74px)';
generateReward(title);
title.dataset.reward = true;
}
});
const selectedOption = await functions.showOptionsMenu(menus, {width:'min(800px, 100%)',maxWidth:'min(1000px, 100%)', height:'min(800px, calc(100% - 80px))', maxHeight:'min(800px, calc(100% - 80px))', search:true, menuItemStyle: 'text-align:left'});
if (selectedOption !== null) {
if(typeof selectedOption.callback === 'function') {
selectedOption.callback(event, functions, selectedOption, {selectedText, selection, range});
setStorageVal('local-quickopen-selected', selectedOption.label);
} else {
alert(selectedOption.callback+' 不是有效的函数');
}
}
};
pressKey = pressKey || (openAny.fn.isMac() ? 'meta+;' : 'ctrl+;');
openAny.removeKeymap(pressKey); // 注意,这里未提供callback时,会删除同名的所有监听
openAny.addKeymap(pressKey, handler);
// 把命令面板的命令移植过来
// see https://github.com/siyuan-note/siyuan/blob/e47b8efc2f2611163beca9fad4ee5424001515ff/app/src/boot/globalEvent/command/panel.ts#L49
Object.keys(window.siyuan.config.keymap.general).forEach((key) => {
let keys;
if (isMobile()) {
keys = ["addToDatabase", "fileTree", "outline", "bookmark", "tag", "dailyNote", "inbox", "backlinks",
"dataHistory", "editReadonly", "enter", "enterBack", "globalSearch", "lockScreen", "mainMenu", "move",
"newFile", "recentDocs", "replace", "riffCard", "search", "selectOpen1", "syncNow"];
} else {
keys = ["addToDatabase", "fileTree", "outline", "bookmark", "tag", "dailyNote", "inbox", "backlinks",
"graphView", "globalGraph", "closeAll", "closeLeft", "closeOthers", "closeRight", "closeTab",
"closeUnmodified", "config", "dataHistory", "editReadonly", "enter", "enterBack", "globalSearch", "goBack",
"goForward", "goToEditTabNext", "goToEditTabPrev", "goToTab1", "goToTab2", "goToTab3", "goToTab4",
"goToTab5", "goToTab6", "goToTab7", "goToTab8", "goToTab9", "goToTabNext", "goToTabPrev", "lockScreen",
"mainMenu", "move", "newFile", "recentDocs", "replace", "riffCard", "search", "selectOpen1", "syncNow",
"splitLR", "splitMoveB", "splitMoveR", "splitTB", "tabToWindow", "stickSearch", "toggleDock", "unsplitAll",
"unsplit"];
if (!isBrowser()) {
keys.push("toggleWin");
}
}
if (keys.includes(key)) {
addMenu(window.siyuan.languages[key], (event, functions, option, selection)=>runSiyuanCommand(key, '', event, functions, option, selection), '', !isMobile()?window.siyuan.config.keymap.general[key].custom:'', window.siyuan.languages[key]);
}
});
Object.keys(window.siyuan.config.keymap.editor.general).forEach((key) => {
if (["switchReadonly", "switchAdjust"].includes(key)) {
addMenu(window.siyuan.languages[key], (event, functions, option, selection)=>runSiyuanCommand(key, '', event, functions, option, selection), '', !isMobile()?updateHotkeyTip(window.siyuan.config.keymap.editor.general[key].custom):'', window.siyuan.languages[key]);
}
});
window.siyuan.ws.app.plugins.forEach(plugin => {
plugin.commands.forEach(command => {
addMenu(`${plugin.displayName}: ${command.langText || plugin.i18n[command.langKey]}`, (event, functions, option, selection)=>runSiyuanCommand(command, 'plugin', event, functions, option, selection), '', !isMobile()?updateHotkeyTip(command.customHotkey):'', `${plugin.displayName}: ${command.langText || plugin.i18n[command.langKey]}`);
});
});
// 生成拼音和拼音首字母
setTimeout(async ()=>{
let pinyinCache = await getFile('/data/storage/quickopen_pinyin_catche.json') || '{}';
pinyinCache = JSON.parse(pinyinCache);
if(pinyinCache.code && pinyinCache.code !== 0) pinyinCache = {};
let hasNewCache = false;
for (const menu of menus) {
try {
const words = encodeURIComponent(menu.label);
if(!pinyinCache[menu.label]) pinyinCache[menu.label] = {};
// 生成汉字拼音
let pinyin = pinyinCache[menu.label]?.pinyin;
if(!pinyin) {
pinyin = await (await fetch('https://tools.getquicker.cn/api/Chinese/GetPinyin?source='+words+'&tone=false&forName=false')).text();
if(pinyin) {
pinyinCache[menu.label].pinyin = pinyin;
hasNewCache = true;
}
}
if(pinyin) menu.pinyin = pinyin;
// 生成拼音首字母
let pinyinFirst = pinyinCache[menu.label]?.pinyinFirst;
if(!pinyinFirst) {
pinyinFirst = await (await fetch('https://tools.getquicker.cn/api/Chinese/GetFirstPinyin?source='+words)).text();
if(pinyinFirst) {
pinyinCache[menu.label].pinyinFirst = pinyinFirst;
hasNewCache = true;
}
}
if(pinyinFirst) menu.pinyinFirst = pinyinFirst;
} catch(e) {
console.warn(e);
return;
}
}
if(hasNewCache) {
putFile('/data/storage/quickopen_pinyin_catche.json', JSON.stringify(pinyinCache));
}
}, 0);
// 添加菜单函数
function addMenu(name, callback, key, shortcut, value) {
menus.push({ label: name, value: value||name, key: key || '', shortcut: shortcut, callback: callback });
}
function runSiyuanCommand(command, type, event, functions, option, selection) {
if(type === 'plugin') {
if (command.callback) {
command.callback();
} else if (command.globalCallback) {
command.globalCallback();
}
} else {
setTimeout(()=>{
openAny.click('#barCommand').click(`#commands [data-command="${command}"]`);
}, 0);
}
}
// see https://github.com/siyuan-note/siyuan/blob/1317020c1791edf440da7f836d366567e03dd843/app/src/protyle/util/compatibility.ts#L409
async function setStorageVal(key, val, cb) {
if (window.siyuan.config.readonly) {
return;
}
const result = await fetchSyncPost("/api/storage/setLocalStorageVal", {
app: window.siyuan.ws.app.appId,
key,
val,
});
if(result && result.code === 0) {
if (cb) {
cb();
}
return result;
}
}
// see https://github.com/siyuan-note/siyuan/blob/e47b8efc2f2611163beca9fad4ee5424001515ff/app/src/protyle/util/compatibility.ts#L258
async function getStorageVal(key) {
const result = await fetchSyncPost("/api/storage/getLocalStorage");
if(result && result.code === 0 && result.data) {
return result.data[key];
}
}
async function fetchSyncPost(url, data, method = 'POST') {
return await (await fetch(url, {method: method, body: JSON.stringify(data||{})})).json();
}
// 获取文件
async function getFile(path) {
return fetch("/api/file/getFile", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
path,
}),
}).then((response) => {
if (response.ok) {
return response.text();
} else {
throw new Error("Failed to get file content");
}
}).catch((error) => {
console.error(error);
});
}
// 存储文件,支持创建文件夹,当isDir true时创建文件夹,忽略文件
async function putFile(path, content = '', isDir = false) {
const formData = new FormData();
formData.append("path", path);
formData.append("isDir", isDir)
formData.append("file", new Blob([content]));
const result = await fetch("/api/file/putFile", {
method: "POST",
body: formData,
});
const json = await result.json();
return json;
}
function waitFor(conditionFn, timeoutMs=5000) {
return new Promise((resolve, reject) => {
const start = Date.now();
const check = () => {
if(typeof conditionFn === 'string')
conditionFn = () => document.querySelector(conditionFn);
const result = conditionFn();
if (result) resolve(result);
else if (Date.now() - start > timeoutMs) reject();
else requestAnimationFrame(check); // 利用浏览器刷新周期
};
check();
});
}
function isMobile() {
return !!document.getElementById("sidebar");
}
function isBrowser() {
return !navigator.userAgent.startsWith("SiYuan") ||
navigator.userAgent.indexOf("iPad") > -1 ||
(/Android/.test(navigator.userAgent) && !/(?:Mobile)/.test(navigator.userAgent));
}
function isMac() {
return navigator.platform.indexOf("Mac") > -1;
}
function updateHotkeyTip(hotkey) {
if (isMac()) {
return hotkey;
}
const KEY_MAP = new Map(Object.entries({
"⌘": "Ctrl",
"⌃": "Ctrl",
"⇧": "Shift",
"⌥": "Alt",
"⇥": "Tab",
"⌫": "Backspace",
"⌦": "Delete",
"↩": "Enter",
}));
const keys = [];
if ((hotkey.indexOf("⌘") > -1 || hotkey.indexOf("⌃") > -1)) keys.push(KEY_MAP.get("⌘"));
if (hotkey.indexOf("⇧") > -1) keys.push(KEY_MAP.get("⇧"));
if (hotkey.indexOf("⌥") > -1) keys.push(KEY_MAP.get("⌥"));
// 不能去最后一个,需匹配 F2
const lastKey = hotkey.replace(/⌘|⇧|⌥|⌃/g, "");
if (lastKey) {
keys.push(KEY_MAP.get(lastKey) || lastKey);
}
return keys.join("+");
}
function generateReward(node) {
const a = document.createElement('a');
a.href = 'https://ld246.com/article/1745488922117#%E6%89%93%E8%B5%8F%E4%BD%9C%E8%80%85';
a.textContent = '打赏作者';
a.target = '_blank';
a.style.position = 'absolute';
a.style.right = '0';
a.style.top = '22px';
node.appendChild(a);
}
})();
等待openAny脚本加载完成的方法
1 for循环
// 等待openAny加载完成
for(let i=0;i<5;i++){
if(typeof openAny !== 'undefined') break;
const delay = Math.floor(1000/(i+1));
await new Promise(resolve => setTimeout(resolve, delay));
}
if(typeof openAny === 'undefined') {
console.error('openAny加载失败');
return;
}
// 继续下面的操作
2 waitFor
function waitFor(conditionFn, timeoutMs=5000) {
return new Promise((resolve, reject) => {
const start = Date.now();
const check = () => {
if(typeof conditionFn === 'string')
conditionFn = () => document.querySelector(conditionFn);
const result = conditionFn();
if (result) resolve(result);
else if (Date.now() - start > timeoutMs) reject();
else requestAnimationFrame(check); // 利用浏览器刷新周期
};
check();
});
}
// 等待oopenAny加载完毕后运行
(function run(count=0) {
setTimeout(()=>{
if(typeof openAny === 'undefined' && count < 5) return run(count+1);
if(typeof openAny === 'undefined') {console.error('openAny undefined');return;}
openAny.addKeymap('', ()=> {
// your code here
});
}, 1000);
})();
