1 Star 0 Fork 0

toolkit/KumoNavigate

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
index.html 32.63 KB
一键复制 编辑 原始数据 按行查看 历史
琴梨梨OvO 提交于 2024-11-17 13:39 +08:00 . 优化异步加载
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="云酱游戏导航,收录游戏玩家常用的地址,有效抵御假冒网站,是游戏玩家必备的导航站" />
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
<link rel="icon" href="static/logo/kumo.webp">
<link rel="apple-touch-icon" href="icon.png">
<meta name="apple-mobile-web-app-title" content="云酱游戏导航">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-touch-fullscreen" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<link rel="canonical" href="https://kumo.qinlili.bid/" />
<link rel="manifest" href="manifest.json">
<meta name="referrer" content="no-referrer" />
<meta name="theme-color" content="#DFAEFF">
<title>云酱游戏导航</title>
<script defer src="module/base.js"></script>
<style>
::-webkit-scrollbar {
height: 12px;
width: 8px;
background: transparent;
z-index: 12;
overflow: visible;
}
::-webkit-scrollbar-thumb {
width: 10px;
background-color: #DFAEFF;
z-index: 12;
border: 3px solid rgba(0, 0, 0, 0);
background-clip: padding-box;
transition: background-color .32s ease-in-out;
margin: 4px;
min-height: 32px;
min-width: 32px;
}
::-webkit-scrollbar-thumb:hover {
background: #DFAEFF;
}
::-webkit-scrollbar-corner {
background: #202020;
}
* {
box-sizing: border-box;
margin: 0px;
padding: 0px;
user-select: none;
}
a {
color: darkorange;
text-decoration: none !important;
}
html,
body {
width: 100%;
height: 100%;
overflow: hidden;
text-align: center;
}
.top {
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.6);
}
.navi {
width: 100vw;
height: 32px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.navicon {
cursor: pointer;
border-radius: 16px;
display: inline;
width: 32px;
height: 32px;
padding: 4px;
transition: all 0.3s;
background-color: transparent;
&:hover {
border-radius: 0px;
background-color: rgba(0, 0, 0, 0.15);
}
&:active {
border-radius: 0px;
background-color: rgba(0, 0, 0, 0.3);
}
}
.navicon-img {
width: 100%;
height: 100%
}
#noti {
transition: all 0.2s;
background-color: rgba(0, 0, 0, 0);
width: 100vw;
height: 24px;
display: flex;
cursor: pointer;
&:hover {
background-color: rgba(0, 0, 0, 0.15);
}
}
#notiIcon {
width: 24px;
height: 24px;
margin-left: 4px;
margin-right: 4px;
padding: 4px;
}
#notiText {
font-size: 0.9em;
line-height: 24px;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
}
.search {
position: relative;
min-width: 100px;
width: 100%;
}
#searchBtn {
position: absolute;
top: 0;
right: 0;
opacity: 0.5;
}
.clickIcon {
cursor: pointer;
opacity: 0.8;
width: auto;
height: 24px;
padding: 2px;
margin: 4px;
border-radius: 0px;
background-color: transparent;
transition: all 0.2s;
&:hover {
border-radius: 4px;
background-color: #dfaeff93;
opacity: 0.9 !important;
}
&:active {
border-radius: 8px;
background-color: #DFAEFF;
opacity: 1 !important;
}
}
input[role="textbox"] {
background-color: transparent;
position: absolute;
padding-right: 40px;
height: 26px;
width: calc(100% - 16px);
margin-top: 2px;
font-size: 1.1em;
margin-left: 8px;
margin-right: 8px;
border: none;
border-bottom: 1px solid #dfaeff93;
outline: none;
transition: all 0.2s linear;
&:focus-visible {
height: 27.25px !important;
border-bottom: 2px solid #dfaeff93 !important;
}
&:hover {
height: 26.75px;
border-bottom: 1.5px solid #dfaeff93;
}
&:active {
height: 27.25px !important;
border-bottom: 2px solid #DFAEFF !important;
}
}
#search {
left: 0px;
top: 0px;
}
.title {
display: flex;
flex-direction: row;
}
.main {
width: 100vw;
overflow: hidden;
display: flex;
flex-direction: row;
}
.side,
.list {
height: 100%;
overflow-x: hidden;
overflow-y: auto;
overflow-y: overlay;
display: flex;
align-items: center;
}
.side {
padding-top: 8px;
width: 128px;
flex-direction: column;
justify-content: flex-start;
box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.4);
}
.list {
width: calc(100% - 128px);
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: flex-start;
align-content: flex-start;
}
.sideItem {
cursor: pointer;
border-radius: 8px;
background-color: transparent;
align-items: center;
width: 100%;
display: flex;
padding-left: 4px;
padding-right: 4px;
padding-top: 12px;
padding-bottom: 12px;
flex-direction: row;
justify-content: space-around;
transition: all 0.2s;
}
.sideItem[active],
.sideItem:hover,
.listItem:hover {
border-radius: 4px;
background-color: #dfaeff93;
}
.sideItem:active,
.listItem:active {
border-radius: 0px;
background-color: #dfaeffd9;
}
.sideItemIcon {
vertical-align: middle;
width: 24px;
height: 100%;
}
.sideItemTitle {
font-size: 1em;
line-height: 20px;
color: #333;
transition: all 0.15s;
width: 100%;
}
.listItem {
border: 1px solid #999;
cursor: pointer;
border-radius: 16px;
background-color: transparent;
align-items: center;
max-width: min(calc(100vw - 120px), 400px);
display: flex;
padding: 8px;
margin: 4px;
flex-direction: row;
justify-content: space-evenly;
flex-grow: 1;
transition: all 0.2s;
&:hover {
border: 1px solid #666;
}
&:active {
border: 1px solid #333;
}
&.richMenu {
border: 1px solid #dfaeff;
&:hover {
border: 1px solid #d28eff;
}
&:active {
border: 1px solid #c773fe;
}
}
}
.listItemTextGroup {
display: flex;
flex-direction: column;
align-items: center;
}
.listItemIcon {
object-fit: contain;
border-radius: 2px;
vertical-align: middle;
width: 24px;
height: 24px;
margin-right: 4px;
}
.listItemTitle {
display: inline-flex;
word-break: break-all;
font-size: 1em;
color: #000;
line-height: 20px;
height: 20px;
overflow: hidden;
text-overflow: ellipsis;
}
.listItemDesc {
display: inline-flex;
word-break: break-all;
font-size: 0.85em;
color: #333;
line-height: 17px;
overflow: hidden;
text-overflow: ellipsis;
height: 17px;
}
.tipIcon {
opacity: 0.7;
height: 20px;
width: 16px;
object-fit: contain;
}
@media (max-width:400px) {
.sideItem {
padding-left: 2px;
padding-right: 2px;
padding-top: 8px;
padding-bottom: 8px;
border-radius: 6px;
}
.sideItemIcon {
display: none;
}
.sideItemTitle {
font-size: 0.875em;
}
.listItem {
max-width: min(calc(100vw - 88px), 400px);
}
.side {
width: 80px;
}
.list {
width: calc(100vw - 80px);
}
#title {
display: none;
}
}
H1 {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
@media (max-width:200px) {
.listItemTextGroup {
display: none;
}
}
@media (max-width:550px) {
#fulltitle {
display: none;
}
}
.titleBtn {
display: flex;
flex-direction: row;
transition: all 0.15s;
&>img {
height: 40px;
width: 40px;
padding: 8px;
}
&>span {
line-height: 24px;
margin: 8px;
margin-left: 0px;
font-weight: 500;
font-size: 1.25em;
@media (max-width:500px) {
display: none;
}
}
&:hover {
background-color: rgba(0, 0, 0, 0.15);
}
&:active {
background-color: rgba(0, 0, 0, 0.3);
}
}
hr {
width: 100%;
height: 8px;
color: #dfaeff;
overflow: visible;
border: none;
border-top: 2px solid;
margin: 8px;
margin-top: 12px;
&::after {
color: black;
font-size: .85em;
background-image: linear-gradient(transparent, white, white, transparent);
content: ' ' attr(name)' ';
padding: 0 4px;
position: relative;
top: -13px;
white-space: nowrap;
}
}
.description {
margin: 4px;
padding: 4px;
width: calc(100% - 8px);
text-align: center;
font-size: 0.875em;
border: solid 1px #dfaeff;
border-radius: 4px;
}
.bottom {
height: 32px;
box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.4);
text-align: left;
display: flex;
flex-direction: row;
overflow: hidden;
>.recentText {
line-height: 32px;
padding-left: 8px;
font-size: 1.25em;
color: #333;
}
>.recentItem {
flex-shrink: 0;
height: 32px;
padding-left: 8px;
padding-right: 8px;
padding-top: 4px;
padding-bottom: 4px;
display: flex;
flex-direction: row;
transition: all 0.2s;
&:hover {
background-color: rgba(0, 0, 0, 0.15);
}
&:active {
background-color: rgba(0, 0, 0, 0.3);
}
>.recentItemIcon {
width: 24px;
height: 24px;
margin-right: 4px;
}
>.recentItemTitle {
line-height: 24px;
font-size: 1em;
color: #000;
}
}
}
button {
font-size: 1.3em;
padding: 3px;
border: 1px solid #999 !important;
background-color: white;
border-radius: 4px !important;
transition: background-color 0.25s ease-in-out;
margin: 3px;
min-width: 60%;
&:hover {
background-color: #ccc;
}
&:active {
background-color: #999;
}
}
</style>
</style>
<style id="webstyle">
.top {
height: 96px;
}
.main {
height: calc(100% - 128px);
}
</style>
<style id="clientstyle">
.title,
#noti {
display: none;
}
.top {
height: 32px;
}
.main {
height: calc(100% - 64px);
}
</style>
<script>
if (self != top) {
document.getElementById("webstyle").disabled = true;
} else {
document.getElementById("clientstyle").disabled = true;
}
</script>
</head>
<body>
<div class="top">
<div class="title" style="height:40px;justify-content: space-between;">
<div class="title" style="flex-shrink: 1;min-width: 40px;">
<img id="logo" style="width:40px;height:40px;padding:4px;" src="static/logo/kumo.webp" alt="云酱游戏导航"
decoding="async">
<H1 id="title" style="margin:5px;line-height:30px;font-size:1.75em;font-weight: 500;"><b>云酱</b><b
id="fulltitle">游戏导航</b></H1>
</div>
<div class="title" style="flex-shrink: 0;">
<div class="titleBtn" onclick="location.href='toolbox.html'" style="display:none;">
<img src="/static/icon/toolbox.svg" alt="工具箱">
<span>工具箱</span>
</div>
<div class="titleBtn" style="display:none;">
<img src="/static/icon/desktop.svg" alt="桌面版">
<span>桌面版</span>
</div>
<div class="titleBtn" id="aboutBtn">
<img src="/static/icon/info.svg" alt="关于">
<span>关于</span>
</div>
</div>
</div>
<div class="navi">
<div class="search" style="display:flex;">
<input role="textbox" id="search" name="搜索" placeholder="搜索">
<img class="clickIcon" id="searchBtn" src="/static/icon/search.svg" alt="搜索">
</div>
</div>
<div id="noti">
<img id="notiIcon" src="/static/icon/loading.svg">
<span id="notiText">正在加载导航...</span>
</div>
</div>
<div class="main">
<div class="side"></div>
<div class="list"></div>
</div>
<div class="bottom">
</div>
<script>
//初始化
document.addEventListener("DOMContentLoaded", async (event) => {
await Module.autoinit.initEverything();
ModuleLoader.loadLocal({
//桌面版同步
desktopSync: {
init: () => {
if (self != top) {
window.addEventListener("message", async (event) => {
console.log(event.data);
}, false);
window.parent.postMessage("GET-", "*");
}
}
},
magicMenu: {
init: () => {
//初始化菜单叠加层
util.loadCssCode(`#floatMenuContainer {
transition: opacity 0.2s ease-in;
opacity: 0;
display: none;
z-index: 9999;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
height: auto;
width: auto;
position: fixed;
background-color: rgba(0, 0, 0, 0.25);
}
#floatMenu {
box-shadow: rgb(0 0 0 / 25%) 0px 4px 20px 1px;
transform: scale(0.1, 0.1);
transform-origin: left top;
overflow-y: auto;
overflow-y: overlay;
width: 80%;
max-height: 0px;
border-radius: 4px;
backdrop-filter: blur(5px) brightness(100%);
-webkit-backdrop-filter: blur(5px) brightness(100%);
background-color: rgba(255, 255, 255, 0.75);
}
#menuList {
display: flex;
flex-direction: column;
}
.menuItem {
height: 40px;
display: flex;
flex-direction: row;
transition: all 0.2s;
padding: 4px;
}
.menuItem:hover {
background-color: rgba(0, 0, 0, 0.15);
}
.menuItem:active {
background-color: rgba(0, 0, 0, 0.3);
}
.menuIcon {
height: 32px;
width: 32px;
padding: 4px;
}
.menuText {
line-height: 24px;
margin: 4px;
}
@media (min-width: 700px) {
#floatMenu {
max-width: 400px;
}
}`);
const container = document.createElement("div");
container.id = "floatMenuContainer";
const menu = document.createElement("div");
menu.id = "floatMenu";
const list = document.createElement("ul");
list.id = "menuList";
menu.appendChild(list);
container.appendChild(menu);
document.body.appendChild(container);
window.addEventListener('pointerdown', (event) => {
if (container.style.display != "block") {
Module.magicMenu.lastClick.x = event.clientX;
Module.magicMenu.lastClick.y = event.clientY;
} else {
Module.magicMenu.lastClickMenu.x = event.clientX;
Module.magicMenu.lastClickMenu.y = event.clientY;
}
});
window.addEventListener("resize", async (event) => {
if (container.style.display == "block") {
await util.sleep(100);
Module.magicMenu.resizeMenu();
};
});
container.addEventListener("click", (event) => {
event.stopPropagation();
Module.magicMenu.hideMenu();
})
//覆盖方法
Module.magicMenu.locateMenu = () => {
//大屏随动菜单
if (document.body.clientWidth >= 700) {
//右侧有空间
if (document.body.clientWidth - 400 > Module.magicMenu.lastClick.x) {
menu.style.marginLeft = Module.magicMenu.lastClick.x + "px";
} else {
menu.style.marginLeft = document.body.clientWidth - 400 + "px";
};
if (document.body.clientHeight - menu.scrollHeight > Module.magicMenu.lastClick.y) {
menu.style.marginTop = Module.magicMenu.lastClick.y + "px";
} else {
if (document.body.clientHeight - menu.scrollHeight < 0) {
menu.style.marginTop = document.body.clientHeight * 0.1 + "px";
} else {
menu.style.marginTop = document.body.clientHeight - menu.scrollHeight + "px";
}
}
} else {
menu.style.marginLeft = "10%";
menu.style.marginTop = document.body.clientHeight * 0.1 + "px";
}
};
Module.magicMenu.showMenu = async () => {
if (container.style.display == "block") { return true; }
container.style.display = "block";
menu.style.overflowY = "hidden";
menu.style.marginLeft = Module.magicMenu.lastClick.x + "px";
menu.style.marginTop = Module.magicMenu.lastClick.y + "px";
menu.style.transition = "transform 0.3s, margin-top 0.3s, margin-left 0.3s,max-height 0.3s";
await util.sleep(5);
container.style.opacity = 1;
Module.magicMenu.locateMenu();
menu.style.transform = "scale(1,1)";
await util.sleep(295);
menu.style.overflowY = "auto";
menu.style.overflowY = "overlay";
};
Module.magicMenu.hideMenu = async () => {
menu.style.transform = "scale(0.1, 0.1)";
menu.style.marginLeft = Module.magicMenu.lastClickMenu.x + "px";
menu.style.marginTop = Module.magicMenu.lastClickMenu.y + "px";
container.style.opacity = 0;
await util.sleep(300);
container.style.display = "none";
menuList.innerHTML = "";
menu.style.transition = "max-height 0.3s";
};
Module.magicMenu.resizeMenu = () => {
let contentHeight = menu.scrollHeight;
menu.style.height = "auto";
let originHeight = menu.style.maxHeight;
let maxHeight = document.body.clientHeight * 0.8;
if (contentHeight > maxHeight) {
contentHeight = maxHeight;
menu.style.marginTop = document.body.clientHeight * 0.1 + "px";
}
menu.style.maxHeight = (contentHeight) + "px";
if (parseInt(originHeight) > contentHeight) {
menu.style.height = originHeight;
};
Module.magicMenu.locateMenu();
};
Module.magicMenu.newMenu = (icon, text, click) => {
const menu = document.createElement("div");
menu.className = "menuItem";
menu.innerHTML = `
<img class="menuIcon" src="${icon}" crossorigin="anonymous" loading="lazy">
<span class="menuText">${text}</span>
`;
menu.onclick = click;
return list.appendChild(menu);
};
Module.magicMenu.clearMenu = () => {
list.innerHTML = "";
};
//菜单魔法展开
const observer = new MutationObserver(Module.magicMenu.resizeMenu);
observer.observe(menu, { childList: true, subtree: true, attributes: true, attributeFilter: ['loaded'] });
},
lastClick: { x: 0, y: 0 },
lastClickMenu: { x: 0, y: 0 }
},
naviRender: {
init: async () => {
window.naviList = await Module.naviUpdater.getData();
Module.top.render();
Module.list.render();
},
updateAndRender: async () => {
await Module.naviUpdater.update();
window.naviList = await Module.naviUpdater.getData();
Module.list.render();
}
},
top: {
render: () => {
//顶栏
const topInfo = naviList.top[util.random(0, naviList.top.length - 1)];
document.getElementById("notiIcon").src = topInfo.icon;
document.getElementById("notiIcon").alt = topInfo.info;
document.getElementById("notiText").innerText = topInfo.info;
if (topInfo.url) {
document.getElementById("noti").onclick = () => {
util.link(topInfo.url, topInfo.url.startsWith("http"));
}
}
if (naviList.top.length > 1) {
setTimeout(Module.top.render, 60000);
}
}
},
list: {
init: () => {
document.getElementById("searchBtn").addEventListener("click", () => {
Module.list.filter(document.getElementById("search").value);
});
if (self != top) {
document.getElementById("search").setAttribute("placeholder", "支持桌面版扩展的游戏会带有图标,点击即可添加/安装而非打开网页");
}
},
render: () => {
document.querySelector(".side").innerHTML = "";
window.naviList.list.forEach((item, index) => {
const side = document.createElement("div");
side.className = "sideItem";
side.innerHTML = `
<img class="sideItemIcon" src="${item.icon}" alt="${item.name}">
<span class="sideItemTitle">${item.name}</span>
`;
side.onclick = () => {
Module.list.renderSublist(item.sublist);
document.querySelector(".sideItem[active]") ? document.querySelector(".sideItem[active]").removeAttribute("active") : false;
side.setAttribute("active", "true");
};
document.querySelector(".side").appendChild(side);
});
document.querySelector(".sideItem").click();
},
renderSublist: sublist => {
document.querySelector(".list").innerHTML = "";
const newTip = icon => {
return `<img class="tipIcon" src="${icon}">`
}
sublist.forEach((item, index) => {
if ((item.hidden && !Module.pref.get("showHidden")) || (Module.pref.get("hideLegacy") && item.legacy)) { return false; };
if (item.divider) {
const divider = document.createElement("hr");
divider.setAttribute("name", item.name);
document.querySelector(".list").appendChild(divider);
return false;
};
if (item.intro) {
const description = document.createElement("span");
description.innerText = item.name;
description.className = "description";
document.querySelector(".list").appendChild(description);
return false;
}
const list = document.createElement("a");
list.className = item.menu ? "listItem richMenu" : "listItem";
let tipIcons = "";
item.desktop && self != top ? tipIcons += newTip("/static/icon/desktop.svg") : false;
list.innerHTML += item.icon ? `<img class="listItemIcon" src="${item.icon}" alt="${item.name}" decoding="async">` : "";
list.innerHTML += `
<div class="listItemTextGroup">
<span class="listItemTitle">${item.name}${tipIcons}</span>
<span class="listItemDesc">${item.description}</span>
</div>
`;
list.href = item.url;
item.url.startsWith("http") ? list.target = "_blank" : false;
list.addEventListener("click", event => {
if (self != top && item.desktop) {
event.preventDefault();
event.stopPropagation();
window.parent.postMessage("ADD-" + item.desktop, "*");
}
Module.pref.addRecent(item.icon, item.name, item.url);
});
if (item.menu) {
list.addEventListener("contextmenu", event => {
event.preventDefault();
event.stopPropagation();
item.menu.forEach(item => {
Module.magicMenu.newMenu(item.icon, item.name, () => {
window.open(item.url, item.url.startsWith("http") ? "_blank" : null)
})
})
Module.magicMenu.showMenu();
});
}
document.querySelector(".list").appendChild(list);
});
},
filter: text => {
let filterList = [];
window.naviList.list.forEach((item, index) => {
item.sublist.forEach((item, index) => {
if ((item.name.toUpperCase().indexOf(text.toUpperCase()) != -1 || (item.description && item.description.toUpperCase().indexOf(text.toUpperCase()) != -1)) && !item.divider && !item.intro) {
filterList.push(item);
};
});
});
Module.list.renderSublist(filterList);
document.querySelector(".sideItem[active]") ? document.querySelector(".sideItem[active]").removeAttribute("active") : false;
}
}
});
ModuleLoader.loadRemote("homeAddon");
});
</script>
</body>
</html>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/toolkit/KumoNavigate.git
git@gitee.com:toolkit/KumoNavigate.git
toolkit
KumoNavigate
KumoNavigate
main

搜索帮助