From 022274ada4b8af2592058a68c67fef763dcc3ca8 Mon Sep 17 00:00:00 2001 From: Gk0Wk Date: Sat, 14 Oct 2023 22:45:42 +0800 Subject: [PATCH] update --- README.md | 1 - package.json | 2 +- pnpm-lock.yaml | 28 +- src/drawio/edit-drawio.ts | 22 +- src/drawio/plugin.info | 2 +- src/mindmap-elixir/mind-elixir.min.js | 2302 ++++++++++++++++- src/mindmap-elixir/plugin.info | 2 +- src/mindmap-elixir/style.css | 17 + src/mindmap-elixir/widget.ts | 44 +- src/notionpage-covericon/body.tid | 10 +- src/notionpage-covericon/plugin.info | 2 +- tsconfig.json | 2 +- wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json | 2 +- .../$__plugins_Gk0Wk_CPL-Repo.json.meta | 5 +- ..._install-plugin-request-model-template.tid | 126 + .../$__plugins_Gk0Wk_focused-tiddler.json | 15 + ...raft of '\345\233\276\350\241\250 1'.json" | 11 - ...of '\345\233\276\350\241\250 1'.json.meta" | 5 - ..._Draft of '\345\233\276\350\241\250'.json" | 11 - ...t of '\345\233\276\350\241\250'.json.meta" | 5 - wiki/tiddlers/MindMap (Elixir).tid | 2 +- 21 files changed, 2521 insertions(+), 95 deletions(-) create mode 100644 wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo_install-plugin-request-model-template.tid create mode 100644 wiki/tiddlers/$__plugins_Gk0Wk_focused-tiddler.json delete mode 100644 "wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json" delete mode 100644 "wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json.meta" delete mode 100644 "wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json" delete mode 100644 "wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json.meta" diff --git a/README.md b/README.md index 0dc3bae..ceb5636 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ # TiddlySeq View [demo](https://gk0wk.github.io/TiddlySeq/). - diff --git a/package.json b/package.json index b4b1706..64a8770 100755 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "lint-staged": "^14.0.1", "rimraf": "^5.0.5", "ts-node": "^10.9.1", - "tw5-typed": "^0.3.10", + "tw5-typed": "^0.3.11", "typescript": "^5.2.2" }, "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d74643d..9e9d686 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,10 +10,10 @@ dependencies: version: 2.0.1 '@mind-elixir/export-html': specifier: ^3.0.0 - version: 3.0.0(mind-elixir@3.1.4) + version: 3.0.0(mind-elixir@3.2.6) '@mind-elixir/export-xmind': specifier: ^2.0.1 - version: 2.0.1(file-saver@2.0.5)(jszip@3.10.1)(mind-elixir@3.1.4) + version: 2.0.1(file-saver@2.0.5)(jszip@3.10.1)(mind-elixir@3.2.6) file-saver: specifier: ^2.0.5 version: 2.0.5 @@ -21,8 +21,8 @@ dependencies: specifier: ^3.10.1 version: 3.10.1 mind-elixir: - specifier: ^3.1.4 - version: 3.1.4 + specifier: ^3.2.6 + version: 3.2.6 mind-elixir-ts: specifier: ^1.1.11 version: 1.1.11 @@ -62,8 +62,8 @@ devDependencies: specifier: ^10.9.1 version: 10.9.1(@types/node@20.7.1)(typescript@5.2.2) tw5-typed: - specifier: ^0.3.10 - version: 0.3.10 + specifier: ^0.3.11 + version: 0.3.11 typescript: specifier: ^5.2.2 version: 5.2.2 @@ -1670,16 +1670,16 @@ packages: resolution: {integrity: sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA==} dev: false - /@mind-elixir/export-html@3.0.0(mind-elixir@3.1.4): + /@mind-elixir/export-html@3.0.0(mind-elixir@3.2.6): resolution: {integrity: sha512-0lKOV818LPsjZ6hLueDp7rAgJsHOWOBQapnXkpzoXk4twWi/1UXiOsC8b+zMI+UJvOyCT0Fm6LfXmGtO7le2mg==} peerDependencies: mind-elixir: ^3.0.0 dependencies: file-saver: 2.0.5 - mind-elixir: 3.1.4 + mind-elixir: 3.2.6 dev: false - /@mind-elixir/export-xmind@2.0.1(file-saver@2.0.5)(jszip@3.10.1)(mind-elixir@3.1.4): + /@mind-elixir/export-xmind@2.0.1(file-saver@2.0.5)(jszip@3.10.1)(mind-elixir@3.2.6): resolution: {integrity: sha512-Xv5EIGc8hTzvLVW09ugBSqeWh4ZeH1L6+AEhMrOYWCn95i1yW2dOHSnyA4wEgnNnd44LejGk17wuoTdhQqyiAQ==} peerDependencies: file-saver: ^2.0.5 @@ -1688,7 +1688,7 @@ packages: dependencies: file-saver: 2.0.5 jszip: 3.10.1 - mind-elixir: 3.1.4 + mind-elixir: 3.2.6 dev: false /@modern-js-app/eslint-config@2.35.1(typescript@5.2.2): @@ -5001,8 +5001,8 @@ packages: resolution: {integrity: sha512-z7lUZbSFSvRCEiMo64fKz1pEKUtgnC3Zl7SXkq9mjALt7qufLG+j3JCSHQGnLJ6ZhLZ1o1lHLYnBjBy9yxdFKw==} dev: false - /mind-elixir@3.1.4: - resolution: {integrity: sha512-3rpfdObkQ1zdzpU23/K8rudTykJN+FzjtzxplIjTU4vyvdUWPaFxg9m97v+sQj/hEGd396wToiyoqshrEFmDKQ==} + /mind-elixir@3.2.6: + resolution: {integrity: sha512-I/3B+U5kXetstx+Z8OE2MMQHDalqxaugZsJQRGjvYK+EwGubwXHvTAXPqFXtU+XUPaZ96ClldEHffoqVkKFlMw==} dev: false /minimatch@3.1.2: @@ -6787,8 +6787,8 @@ packages: safe-buffer: 5.2.1 dev: false - /tw5-typed@0.3.10: - resolution: {integrity: sha512-c/NEOxuiGS75spVzT88BgAQORDg9l9z2g4HWCOmAoVQN27t0B910K4Db7IN5W7PF3BF88Zn4n+tjxqIwuDg2uQ==} + /tw5-typed@0.3.11: + resolution: {integrity: sha512-U9EOoWqWoT3CtCDf1CRQLyWL2Jk+br0TuJ1uuOtCdao30z4mRpllUUTT/0VQpJNvZeeWkxhC+DzUJyoSTFVAbg==} dependencies: '@types/codemirror': 5.60.8 '@types/echarts': 4.9.18 diff --git a/src/drawio/edit-drawio.ts b/src/drawio/edit-drawio.ts index dcb6713..458c1fc 100644 --- a/src/drawio/edit-drawio.ts +++ b/src/drawio/edit-drawio.ts @@ -90,6 +90,7 @@ class DrawIOEditor { innerHTML: value, }); parentNode.insertBefore(node, nextSibling); + widget.domNodes.push(node); this.xml = ''; this.unmount = () => null; return; @@ -111,6 +112,7 @@ class DrawIOEditor { }, }); parentNode.insertBefore(this.iframeNode, nextSibling); + widget.domNodes.push(this.iframeNode); // 全屏按钮 const chatButton = $tw.utils.domMaker('button', { @@ -134,6 +136,7 @@ class DrawIOEditor { }); chatButton.onclick = () => this.setFullscreen(true); parentNode.insertBefore(chatButton, nextSibling); + widget.domNodes.push(chatButton); this.xml = value; let hasInited = false; @@ -146,10 +149,10 @@ class DrawIOEditor { ) { return; } - const { event, ...payload } = $tw.utils.parseJSONSafe( - data, - () => ({}), - ) as any; + const { event, ...payload } = $tw.utils.parseJSONSafe<{ + event?: string; + [payloadName: string]: unknown; + }>(data, () => ({})); switch (event) { case 'init': { if (hasInited) { @@ -191,16 +194,17 @@ class DrawIOEditor { break; } case 'openLink': { - const { href, target } = payload; + const { href, target } = payload as { href: string; target: string }; window.open(href, target); break; } case 'export': { - const { message, data } = payload; + const { message, data } = payload as { + data: string; + message: Record; + }; if (data && message.twEditor) { - const newXml = ($tw.utils as any).base64Decode( - data.split(',', 2)[1], - ); + const newXml = $tw.utils.base64Decode(data.split(',', 2)[1]); if (newXml === this.xml) { return; } diff --git a/src/drawio/plugin.info b/src/drawio/plugin.info index af3939b..4a7bfe7 100644 --- a/src/drawio/plugin.info +++ b/src/drawio/plugin.info @@ -4,6 +4,6 @@ "author": "Gk0Wk", "description": "draw.io powerful diagram editor for TiddlyWiki", "plugin-type": "plugin", - "version": "0.0.6", + "version": "0.0.7", "list": "readme config LICENSE" } diff --git a/src/mindmap-elixir/mind-elixir.min.js b/src/mindmap-elixir/mind-elixir.min.js index d1b979d..a63d5b5 100644 --- a/src/mindmap-elixir/mind-elixir.min.js +++ b/src/mindmap-elixir/mind-elixir.min.js @@ -1,7 +1,2295 @@ -/** - * Skipped minification because the original files appears to be already minified. - * Original file: /npm/mind-elixir@2.0.2/dist/MindElixir.js - * - * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files - */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.MindElixir=t():e.MindElixir=t()}(self,(()=>(()=>{var e={74:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var i=n(81),o=n.n(i),r=n(645),a=n.n(r),s=n(667),l=n.n(s),c=new URL(n(848),n.b),d=new URL(n(295),n.b),h=a()(o()),p=l()(c),m=l()(d);h.push([e.id,".mind-elixir {\n --gap: 30px;\n --root-radius: 30px;\n --main-radius: 20px;\n --root-color: #ffffff;\n --root-bgcolor: #4c4f69;\n --main-color: #444446;\n --main-bgcolor: #ffffff;\n --topic-padding: 3px;\n --color: #777777;\n --bgcolor: #f6f6f6;\n position: relative;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;\n}\n.mind-elixir .hyper-link {\n text-decoration: none;\n}\n.map-container {\n user-select: none;\n height: 100%;\n width: 100%;\n overflow: scroll;\n font-size: 15px;\n}\n.map-container::-webkit-scrollbar {\n width: 0px;\n height: 0px;\n}\n.map-container .selected {\n box-shadow: 0 0 0 2px #4dc4ff;\n}\n.map-container .lhs {\n direction: rtl;\n}\n.map-container .lhs me-tpc {\n direction: ltr;\n}\n.map-container .map-canvas {\n height: 20000px;\n width: 20000px;\n position: relative;\n user-select: none;\n transition: all 0.3s;\n transform: scale(1);\n background-color: var(--bgcolor);\n}\n.map-container .map-canvas me-root {\n position: absolute;\n padding: 10px var(--gap);\n color: var(--root-color);\n background-color: var(--root-bgcolor);\n border-radius: var(--root-radius);\n}\n.map-container .map-canvas me-root me-tpc {\n display: block;\n font-size: 25px;\n white-space: pre-wrap;\n}\n.map-container .map-canvas me-root me-tpc #input-box {\n padding: 10px var(--gap);\n}\n.map-container .box > me-wrapper {\n position: absolute;\n}\n.map-container .box > me-wrapper > me-parent {\n margin: var(--gap);\n background-color: var(--main-bgcolor);\n border: 1px solid var(--main-color);\n border-radius: var(--main-radius);\n padding: 0;\n}\n.map-container .box > me-wrapper > me-parent > me-tpc {\n border-radius: var(--main-radius);\n color: var(--main-color);\n padding: 8px var(--gap);\n}\n.map-container .box > me-wrapper > me-parent > me-tpc #input-box {\n padding: 8px var(--gap);\n}\n.map-container me-wrapper {\n display: block;\n pointer-events: none;\n}\n.map-container me-children,\n.map-container me-parent {\n display: inline-block;\n vertical-align: middle;\n}\n.map-container me-parent {\n position: relative;\n cursor: pointer;\n padding: 6px var(--gap);\n margin-top: 10px;\n}\n.map-container me-parent me-tpc {\n position: relative;\n display: block;\n border-radius: 3px;\n color: var(--color);\n pointer-events: all;\n max-width: 800px;\n white-space: pre-wrap;\n padding: var(--topic-padding);\n line-height: 1.2;\n}\n.map-container me-parent me-tpc .tags {\n direction: ltr;\n}\n.map-container me-parent me-tpc .tags span {\n display: inline-block;\n border-radius: 3px;\n padding: 2px 4px;\n background: #d6f0f8;\n color: #276f86;\n margin: 0px;\n font-size: 12px;\n height: 16px;\n line-height: 16px;\n margin-right: 3px;\n margin-top: 2px;\n}\n.map-container me-parent me-tpc .icons {\n display: inline-block;\n direction: ltr;\n margin-right: 10px;\n}\n.map-container me-parent me-tpc .insert-preview {\n position: absolute;\n width: 100%;\n left: 0px;\n z-index: 9;\n}\n.map-container me-parent me-tpc .show {\n background: #7ad5ff;\n pointer-events: none;\n opacity: 0.7;\n}\n.map-container me-parent me-tpc .before {\n height: 14px;\n top: -14px;\n}\n.map-container me-parent me-tpc .in {\n height: 100%;\n top: 0px;\n}\n.map-container me-parent me-tpc .after {\n height: 14px;\n bottom: -14px;\n}\n.map-container me-parent me-epd {\n position: absolute;\n height: 18px;\n width: 18px;\n opacity: 0.8;\n background-image: url("+p+");\n background-repeat: no-repeat;\n background-size: contain;\n background-position: center;\n pointer-events: all;\n z-index: 9;\n}\n.map-container me-parent me-epd.minus {\n background-image: url("+m+") !important;\n transition: all 0.3s;\n opacity: 0;\n}\n.map-container me-parent me-epd.minus:hover {\n opacity: 0.8;\n}\n.map-container .icon {\n width: 1em;\n height: 1em;\n vertical-align: -0.15em;\n fill: currentColor;\n overflow: hidden;\n}\n.map-container .lines,\n.map-container .subLines,\n.map-container .topiclinks,\n.map-container .linkcontroller {\n position: absolute;\n height: 102%;\n width: 100%;\n top: 0;\n left: 0;\n}\n.map-container .topiclinks,\n.map-container .linkcontroller {\n pointer-events: none;\n}\n.map-container .topiclinks g,\n.map-container .linkcontroller g {\n pointer-events: all;\n}\n.map-container .lines,\n.map-container .subLines {\n pointer-events: none;\n z-index: -1;\n}\n.map-container .topiclinks *,\n.map-container .linkcontroller * {\n z-index: 100;\n}\n.map-container .topiclinks g {\n cursor: pointer;\n}\n.map-container #input-box {\n position: absolute;\n top: 0;\n left: 0;\n padding: var(--topic-padding);\n background-color: #fff;\n color: #666666;\n width: max-content;\n max-width: 800px;\n z-index: 11;\n direction: ltr;\n user-select: auto;\n}\n.map-container me-tpc > img {\n pointer-events: none;\n display: block;\n margin-top: 8px;\n}\n.map-container .circle {\n position: absolute;\n height: 10px;\n width: 10px;\n margin-top: -5px;\n margin-left: -5px;\n border-radius: 100%;\n background: #aaa;\n cursor: pointer;\n}\n",""]);const u=h},165:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var i=n(81),o=n.n(i),r=n(645),a=n.n(r)()(o());a.push([e.id,".mind-elixir .context-menu {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 99;\n}\n.mind-elixir .context-menu .menu-list {\n position: fixed;\n list-style: none;\n margin: 0;\n padding: 0;\n font: 300 15px 'Roboto', sans-serif;\n color: #333;\n box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.2);\n}\n.mind-elixir .context-menu .menu-list * {\n transition: color 0.4s, background-color 0.4s;\n}\n.mind-elixir .context-menu .menu-list li {\n min-width: 150px;\n overflow: hidden;\n white-space: nowrap;\n padding: 6px 10px;\n background-color: #fff;\n border-bottom: 1px solid #ecf0f1;\n}\n.mind-elixir .context-menu .menu-list li a {\n color: #333;\n text-decoration: none;\n}\n.mind-elixir .context-menu .menu-list li.disabled {\n color: #5e5e5e;\n background-color: #f7f7f7;\n}\n.mind-elixir .context-menu .menu-list li.disabled:hover {\n cursor: default;\n background-color: #f7f7f7;\n}\n.mind-elixir .context-menu .menu-list li:hover {\n cursor: pointer;\n background-color: #ecf0f1;\n}\n.mind-elixir .context-menu .menu-list li:first-child {\n border-radius: 5px 5px 0 0;\n}\n.mind-elixir .context-menu .menu-list li:last-child {\n border-bottom: 0;\n border-radius: 0 0 5px 5px;\n}\n.mind-elixir .context-menu .menu-list li span:last-child {\n float: right;\n}\n",""]);const s=a},787:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var i=n(81),o=n.n(i),r=n(645),a=n.n(r)()(o());a.push([e.id,".mind-elixir .mobile-menu {\n position: absolute;\n left: 20px;\n bottom: 70px;\n z-index: 99;\n margin: 0;\n padding: 0;\n color: #333;\n border-radius: 5px;\n box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n.mind-elixir .mobile-menu * {\n transition: color 0.4s, background-color 0.4s;\n}\n.mind-elixir .mobile-menu div {\n float: left;\n text-align: center;\n width: 30px;\n overflow: hidden;\n white-space: nowrap;\n padding: 8px;\n background-color: #fff;\n border-bottom: 1px solid #ecf0f1;\n}\n.mind-elixir .mobile-menu div a {\n color: #333;\n text-decoration: none;\n}\n.mind-elixir .mobile-menu div.disabled {\n color: #5e5e5e;\n background-color: #f7f7f7;\n}\n.mind-elixir .mobile-menu div.disabled:hover {\n cursor: default;\n background-color: #f7f7f7;\n}\n.mind-elixir .mobile-menu div:hover {\n cursor: pointer;\n background-color: #ecf0f1;\n}\n",""]);const s=a},301:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var i=n(81),o=n.n(i),r=n(645),a=n.n(r)()(o());a.push([e.id,".mind-elixir-toolbar {\n position: absolute;\n background: #fff;\n padding: 10px;\n border-radius: 5px;\n box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2);\n}\n.mind-elixir-toolbar span:active {\n opacity: 0.5;\n}\n.mind-elixir-toolbar.rb {\n right: 20px;\n bottom: 20px;\n font-family: iconfont;\n}\n.mind-elixir-toolbar.rb span + span {\n margin-left: 10px;\n}\n.mind-elixir-toolbar.lt {\n font-size: 20px;\n left: 20px;\n top: 20px;\n width: 20px;\n}\n.mind-elixir-toolbar.lt span {\n display: block;\n}\n.mind-elixir-toolbar.lt span + span {\n margin-top: 10px;\n}\n",""]);const s=a},645:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n="",i=void 0!==t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),i&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),i&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n})).join("")},t.i=function(e,n,i,o,r){"string"==typeof e&&(e=[[null,e,void 0]]);var a={};if(i)for(var s=0;s0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=r),n&&(d[2]?(d[1]="@media ".concat(d[2]," {").concat(d[1],"}"),d[2]=n):d[2]=n),o&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=o):d[4]="".concat(o)),t.push(d))}},t}},667:e=>{"use strict";e.exports=function(e,t){return t||(t={}),e?(e=String(e.__esModule?e.default:e),/^['"].*['"]$/.test(e)&&(e=e.slice(1,-1)),t.hash&&(e+=t.hash),/["'() \t\n]|(%20)/.test(e)||t.needQuotes?'"'.concat(e.replace(/"/g,'\\"').replace(/\n/g,"\\n"),'"'):e):e}},81:e=>{"use strict";e.exports=function(e){return e[1]}},379:e=>{"use strict";var t=[];function n(e){for(var n=-1,i=0;i{"use strict";var t={};e.exports=function(e,n){var i=function(e){if(void 0===t[e]){var n=document.querySelector(e);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}t[e]=n}return t[e]}(e);if(!i)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");i.appendChild(n)}},216:e=>{"use strict";e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},565:(e,t,n)=>{"use strict";e.exports=function(e){var t=n.nc;t&&e.setAttribute("nonce",t)}},795:e=>{"use strict";e.exports=function(e){var t=e.insertStyleElement(e);return{update:function(n){!function(e,t,n){var i="";n.supports&&(i+="@supports (".concat(n.supports,") {")),n.media&&(i+="@media ".concat(n.media," {"));var o=void 0!==n.layer;o&&(i+="@layer".concat(n.layer.length>0?" ".concat(n.layer):""," {")),i+=n.css,o&&(i+="}"),n.media&&(i+="}"),n.supports&&(i+="}");var r=n.sourceMap;r&&"undefined"!=typeof btoa&&(i+="\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(r))))," */")),t.styleTagTransform(i,e,t.options)}(t,e,n)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(t)}}}},589:e=>{"use strict";e.exports=function(e,t){if(t.styleSheet)t.styleSheet.cssText=e;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}}},857:()=>{!function(e){var t,n,i,o,r,a,s='',l=(l=document.getElementsByTagName("script"))[l.length-1].getAttribute("data-injectcss");if(l&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(e){console}}function c(){r||(r=!0,i())}t=function(){var e,t,n,i;(i=document.createElement("div")).innerHTML=s,s=null,(n=i.getElementsByTagName("svg")[0])&&(n.setAttribute("aria-hidden","true"),n.style.position="absolute",n.style.width=0,n.style.height=0,n.style.overflow="hidden",e=n,(t=document.body).firstChild?(i=e,(n=t.firstChild).parentNode.insertBefore(i,n)):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),t()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(i=t,o=e.document,r=!1,(a=function(){try{o.documentElement.doScroll("left")}catch(e){return void setTimeout(a,50)}c()})(),o.onreadystatechange=function(){"complete"==o.readyState&&(o.onreadystatechange=null,c())})}(window)},848:e=>{"use strict";e.exports="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdD0iMTY1NjY1NDcxNzI0MiIgY2xhc3M9Imljb24iIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIHZlcnNpb249IjEuMSIKICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+CiAgICA8cGF0aCBkPSJNNTEyIDc0LjY2NjY2N0MyNzAuOTMzMzMzIDc0LjY2NjY2NyA3NC42NjY2NjcgMjcwLjkzMzMzMyA3NC42NjY2NjcgNTEyUzI3MC45MzMzMzMgOTQ5LjMzMzMzMyA1MTIgOTQ5LjMzMzMzMyA5NDkuMzMzMzMzIDc1My4wNjY2NjcgOTQ5LjMzMzMzMyA1MTIgNzUzLjA2NjY2NyA3NC42NjY2NjcgNTEyIDc0LjY2NjY2N3oiIHN0cm9rZS13aWR0aD0iNTQiIHN0cm9rZT0nYmxhY2snIGZpbGw9J3doaXRlJyA+PC9wYXRoPgogICAgPHBhdGggZD0iTTY4Mi42NjY2NjcgNDgwaC0xMzguNjY2NjY3VjM0MS4zMzMzMzNjMC0xNy4wNjY2NjctMTQuOTMzMzMzLTMyLTMyLTMycy0zMiAxNC45MzMzMzMtMzIgMzJ2MTM4LjY2NjY2N0gzNDEuMzMzMzMzYy0xNy4wNjY2NjcgMC0zMiAxNC45MzMzMzMtMzIgMzJzMTQuOTMzMzMzIDMyIDMyIDMyaDEzOC42NjY2NjdWNjgyLjY2NjY2N2MwIDE3LjA2NjY2NyAxNC45MzMzMzMgMzIgMzIgMzJzMzItMTQuOTMzMzMzIDMyLTMydi0xMzguNjY2NjY3SDY4Mi42NjY2NjdjMTcuMDY2NjY3IDAgMzItMTQuOTMzMzMzIDMyLTMycy0xNC45MzMzMzMtMzItMzItMzJ6Ij48L3BhdGg+Cjwvc3ZnPg=="},295:e=>{"use strict";e.exports="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdD0iMTY1NjY1NTU2NDk4NSIgY2xhc3M9Imljb24iIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIHZlcnNpb249IjEuMSIKICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+CiAgICA8cGF0aCBkPSJNNTEyIDc0LjY2NjY2N0MyNzAuOTMzMzMzIDc0LjY2NjY2NyA3NC42NjY2NjcgMjcwLjkzMzMzMyA3NC42NjY2NjcgNTEyUzI3MC45MzMzMzMgOTQ5LjMzMzMzMyA1MTIgOTQ5LjMzMzMzMyA5NDkuMzMzMzMzIDc1My4wNjY2NjcgOTQ5LjMzMzMzMyA1MTIgNzUzLjA2NjY2NyA3NC42NjY2NjcgNTEyIDc0LjY2NjY2N3oiIHN0cm9rZS13aWR0aD0iNTQiIHN0cm9rZT0nYmxhY2snIGZpbGw9J3doaXRlJyA+PC9wYXRoPgogICAgPHBhdGggZD0iTTY4Mi42NjY2NjcgNTQ0SDM0MS4zMzMzMzNjLTE3LjA2NjY2NyAwLTMyLTE0LjkzMzMzMy0zMi0zMnMxNC45MzMzMzMtMzIgMzItMzJoMzQxLjMzMzMzNGMxNy4wNjY2NjcgMCAzMiAxNC45MzMzMzMgMzIgMzJzLTE0LjkzMzMzMyAzMi0zMiAzMnoiPjwvcGF0aD4KPC9zdmc+"}},t={};function n(i){var o=t[i];if(void 0!==o)return o.exports;var r=t[i]={id:i,exports:{}};return e[i](r,r.exports,n),r.exports}n.m=e,n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.b=document.baseURI||self.location.href,n.nc=void 0;var i={};return(()=>{"use strict";n.d(i,{default:()=>ue});const e=30,t={name:"Latte",palette:["#dd7878","#ea76cb","#8839ef","#e64553","#fe640b","#df8e1d","#40a02b","#209fb5","#1e66f5","#7287fd"],cssVar:{"--main-color":"#444446","--main-bgcolor":"#ffffff","--color":"#777777","--bgcolor":"#f6f6f6"}};function o(e){return e.replace(/&/g,"&").replace(/{if(e.parent=t,e.children)for(let t=0;t{let n=Date.now();return function(...i){Date.now()-n>=t&&(e.apply(this,i),n=Date.now())}};function c(e,t,n,i){const o=i-t,r=e-n;let a=Math.atan(Math.abs(o)/Math.abs(r))/3.14*180;r<0&&o>0&&(a=180-a),r<0&&o<0&&(a=180+a),r>0&&o<0&&(a=360-a);const s=a+30,l=a-30;return{x1:n+20*Math.cos(Math.PI*s/180),y1:i-20*Math.sin(Math.PI*s/180),x2:n+20*Math.cos(Math.PI*l/180),y2:i-20*Math.sin(Math.PI*l/180)}}function d(e,t,n){let i,o;const r=(e.cy-n)/(t-e.cx);return r>e.h/e.w||r<-e.h/e.w?e.cy-n<0?(i=e.cx-e.h/2/r,o=e.cy+e.h/2):(i=e.cx+e.h/2/r,o=e.cy-e.h/2):e.cx-t<0?(i=e.cx+e.w/2,o=e.cy-e.w*r/2):(i=e.cx-e.w/2,o=e.cy+e.w*r/2),{x:i,y:o}}function h(e,t,n){let i,o;const r=(e.cy-n)/(t-e.cx);return r>e.h/e.w||r<-e.h/e.w?e.cy-n<0?(i=e.cx-e.h/2/r,o=e.cy+e.h/2):(i=e.cx+e.h/2/r,o=e.cy-e.h/2):e.cx-t<0?(i=e.cx+e.w/2,o=e.cy-e.w*r/2):(i=e.cx-e.w/2,o=e.cy+e.w*r/2),{x:i,y:o}}function p(){return((new Date).getTime().toString(16)+Math.random().toString(16).substr(2)).substr(2,16)}function m(e){const t=e.parent.children,n=t.indexOf(e);return t.splice(n,1),t.length}function u(e){return JSON.parse(JSON.stringify(e,((e,t)=>{if("parent"!==e)return t})))}const f=document,g=(e,t)=>(t?t.mindElixirBox:f).querySelector(`[data-nodeid=me${e}]`),b=function(e,t){if(e.textContent=t.topic,t.style&&(e.style.color=t.style.color||null,e.style.background=t.style.background||null,e.style.fontSize=t.style.fontSize+"px",e.style.fontWeight=t.style.fontWeight||"normal"),t.image){const n=t.image;if(n.url&&n.width&&n.height){const t=f.createElement("img");t.src=n.url,t.style.width=n.width+"px",t.style.height=n.height+"px",e.appendChild(t)}}if(t.hyperLink){const n=f.createElement("a");n.className="hyper-link",n.target="_blank",n.innerText="🔗",n.href=t.hyperLink,e.appendChild(n),e.linkContainer=n}else e.linkContainer&&(e.linkContainer.remove(),e.linkContainer=null);if(t.icons&&t.icons.length){const n=f.createElement("span");n.className="icons",n.innerHTML=t.icons.map((e=>`${o(e)}`)).join(""),e.appendChild(n)}if(t.tags&&t.tags.length){const n=f.createElement("div");n.className="tags",n.innerHTML=t.tags.map((e=>`${o(e)}`)).join(""),e.appendChild(n)}t.branchColor&&(e.style.borderColor=t.branchColor)};const x=function(e){const t=f.createElement("me-epd");return t.expanded=!1!==e,t.className=!1!==e?"minus":"",t},N=document,y=document,v="http://www.w3.org/2000/svg",M=function(e,t){const n=y.createElementNS(v,"path");return n.setAttribute("d",e),n.setAttribute("stroke",t||"#666"),n.setAttribute("fill","none"),n.setAttribute("stroke-width","3"),n},C=function(e){const t=y.createElementNS(v,"svg");return t.setAttribute("class",e),t},k=function(e,t,n,i){const o=y.createElementNS(v,"line");return o.setAttribute("x1",e),o.setAttribute("y1",t),o.setAttribute("x2",n),o.setAttribute("y2",i),o.setAttribute("stroke","#bbb"),o.setAttribute("fill","none"),o.setAttribute("stroke-width","2"),o},w=function(e,t){const n=y.createElementNS(v,"path");return n.setAttribute("d",e),n.setAttribute("stroke",t||"#555"),n.setAttribute("fill","none"),n.setAttribute("stroke-linecap","square"),n.setAttribute("stroke-width","2"),n};function z(e){return{nodeData:e.isFocusMode?e.nodeDataBackup:e.nodeData,linkData:e.linkData,direction:e.direction,theme:e.theme}}const E=function(e,t){if(!e)return;const n=e.nodeObj;!1===n.expanded&&(this.expandNode(e,!0),e=g(n.id));const i=t||this.generateNewObj();n.children?n.children.push(i):n.children=[i],a(this.nodeData);const o=e.parentElement,{grp:r,top:s}=this.createWrapper(i);if("ME-PARENT"===o.tagName){if(o.children[1])o.nextSibling.appendChild(r);else{const e=this.createChildren([r]);o.appendChild(x(!0)),o.insertAdjacentElement("afterend",e)}this.linkDiv(r.offsetParent)}else"ME-ROOT"===o.tagName&&(this.judgeDirection(r,i),o.nextSibling.appendChild(r),this.linkDiv());return{newTop:s,newNodeObj:i}};function j(e){this.dom=e,this.mousedown=!1,this.lastX=null,this.lastY=null}j.prototype={init(e,t){this.handleMouseMove=e=>{if(e.stopPropagation(),this.mousedown){if(!this.lastX)return this.lastX=e.pageX,void(this.lastY=e.pageY);const n=this.lastX-e.pageX,i=this.lastY-e.pageY;t(n,i),this.lastX=e.pageX,this.lastY=e.pageY}},this.handleMouseDown=e=>{e.stopPropagation(),this.mousedown=!0},this.handleClear=e=>{e.stopPropagation(),this.clear()},e.addEventListener("mousemove",this.handleMouseMove),e.addEventListener("mouseleave",this.handleClear),e.addEventListener("mouseup",this.handleClear),this.dom.addEventListener("mousedown",this.handleMouseDown)},destory(e){e.removeEventListener("mousemove",this.handleMouseMove),e.removeEventListener("mouseleave",this.handleClear),e.removeEventListener("mouseup",this.handleClear),this.dom.removeEventListener("mousedown",this.handleMouseDown)},clear(){this.mousedown=!1,this.lastX=null,this.lastY=null}};const L=function(e,t,n){let i="";const o=t.offsetTop,r=t.offsetLeft,a=t.offsetWidth,s=t.offsetHeight;for(let t=0;t0&&(i+=L(g,c))}return i};function D({x1:e,y1:t,x2:n,y2:i}){return`M ${e} 10000 V ${i>t?i-20:i+20} C ${e} ${i} ${e} ${i} ${n>e?e+20:e-20} ${i} H ${n}`}function T({x1:e,y1:t,x2:n,y2:i}){return`M ${e} ${t} Q ${e} ${i} ${n} ${i}`}function A({pT:t,pL:n,pW:i,pH:o,cT:r,cL:a,cW:s,cH:l,direction:c,isFirst:d}){let h,p;h=d?t+o/2:t+o;const m=r+l;let u,f,g;return"lhs"===c?(g=n,u=g+e,f=g-e,p=a+e):"rhs"===c&&(g=n+i,u=g-e,f=g+e,p=a+s-e),`M ${u} ${h} C ${g} ${h} ${g} ${m} ${f} ${m} H ${p}`}const I={afterMoving:!1,mousedown:!1,lastX:null,lastY:null,onMove(e,t){if(this.mousedown){if(this.afterMoving=!0,!this.lastX)return this.lastX=e.pageX,void(this.lastY=e.pageY);const n=this.lastX-e.pageX,i=this.lastY-e.pageY;t.scrollTo(t.scrollLeft+n,t.scrollTop+i),this.lastX=e.pageX,this.lastY=e.pageY}},clear(){this.afterMoving=!1,this.mousedown=!1,this.lastX=null,this.lastY=null}};const S={addChild:"插入子节点",addParent:"插入父节点",addSibling:"插入同级节点",removeNode:"删除节点",focus:"专注",cancelFocus:"取消专注",moveUp:"上移",moveDown:"下移",link:"连接",clickTips:"请点击目标节点"},P={cn:S,zh_CN:S,zh_TW:{addChild:"插入子節點",addParent:"插入父節點",addSibling:"插入同級節點",removeNode:"刪除節點",focus:"專注",cancelFocus:"取消專注",moveUp:"上移",moveDown:"下移",link:"連接",clickTips:"請點擊目標節點"},en:{addChild:"Add child",addParent:"Add parent",addSibling:"Add sibling",removeNode:"Remove node",focus:"Focus Mode",cancelFocus:"Cancel Focus Mode",moveUp:"Move up",moveDown:"Move down",link:"Link",clickTips:"Please click the target node"},ru:{addChild:"Добавить дочерний элемент",addParent:"Добавить родительский элемент",addSibling:"Добавить на этом уровне",removeNode:"Удалить узел",focus:"Режим фокусировки",cancelFocus:"Отменить режим фокусировки",moveUp:"Поднять выше",moveDown:"Опустить ниже",link:"Ссылка",clickTips:"Пожалуйста, нажмите на целевой узел"},ja:{addChild:"子ノードを追加する",addParent:"親ノードを追加します",addSibling:"兄弟ノードを追加する",removeNode:"ノードを削除",focus:"集中",cancelFocus:"集中解除",moveUp:"上へ移動",moveDown:"下へ移動",link:"コネクト",clickTips:"ターゲットノードをクリックしてください"},pt:{addChild:"Adicionar item filho",addParent:"Adicionar item pai",addSibling:"Adicionar item irmao",removeNode:"Remover item",focus:"Modo Foco",cancelFocus:"Cancelar Modo Foco",moveUp:"Mover para cima",moveDown:"Mover para baixo",link:"Link",clickTips:"Favor clicar no item alvo"}};var O=n(379),H=n.n(O),Y=n(795),B=n.n(Y),$=n(569),R=n.n($),V=n(565),Z=n.n(V),W=n(216),F=n.n(W),U=n(589),X=n.n(U),G=n(165),_={};_.styleTagTransform=X(),_.setAttributes=Z(),_.insert=R().bind(null,"head"),_.domAPI=B(),_.insertStyleElement=F();H()(G.Z,_);G.Z&&G.Z.locals&&G.Z.locals;function q(e,t){const n=(e,t,n)=>{const i=document.createElement("li");return i.id=e,i.innerHTML=`${o(t)}${o(n)}`,i},i=P[e.locale]?e.locale:"en",r=n("cm-add_child",P[i].addChild,"tab"),a=n("cm-add_parent",P[i].addParent,""),s=n("cm-add_sibling",P[i].addSibling,"enter"),l=n("cm-remove_child",P[i].removeNode,"delete"),c=n("cm-fucus",P[i].focus,""),d=n("cm-unfucus",P[i].cancelFocus,""),h=n("cm-up",P[i].moveUp,"PgUp"),p=n("cm-down",P[i].moveDown,"Pgdn"),m=n("cm-down",P[i].link,""),u=document.createElement("ul");if(u.className="menu-list",u.appendChild(r),u.appendChild(a),u.appendChild(s),u.appendChild(l),t&&!t.focus||(u.appendChild(c),u.appendChild(d)),u.appendChild(h),u.appendChild(p),t&&!t.link||u.appendChild(m),t&&t.extend)for(let e=0;e{i.onclick(e)}}const f=document.createElement("div");f.className="context-menu",f.appendChild(u),f.hidden=!0,e.container.append(f);let g=!0;e.container.oncontextmenu=function(t){if(t.preventDefault(),!e.editable)return;const n=t.target;if("ME-TPC"===n.tagName){g="ME-ROOT"===n.parentElement.tagName,g?(c.className="disabled",h.className="disabled",p.className="disabled",s.className="disabled",l.className="disabled"):(c.className="",h.className="",p.className="",s.className="",l.className=""),e.selectNode(n),f.hidden=!1;const i=u.offsetHeight,o=u.offsetWidth;i+t.clientY>window.innerHeight?(u.style.top="",u.style.bottom="0px"):(u.style.bottom="",u.style.top=t.clientY+15+"px"),o+t.clientX>window.innerWidth?(u.style.left="",u.style.right="0px"):(u.style.right="",u.style.left=t.clientX+10+"px")}},f.onclick=e=>{e.target===f&&(f.hidden=!0)},r.onclick=()=>{e.addChild(),f.hidden=!0},a.onclick=()=>{e.insertParent(),f.hidden=!0},s.onclick=()=>{g||(e.insertSibling(),f.hidden=!0)},l.onclick=()=>{g||(e.removeNode(),f.hidden=!0)},c.onclick=()=>{g||(e.focusNode(e.currentNode),f.hidden=!0)},d.onclick=()=>{e.cancelFocus(),f.hidden=!0},h.onclick=()=>{g||(e.moveUpNode(),f.hidden=!0)},p.onclick=()=>{g||(e.moveDownNode(),f.hidden=!0)},m.onclick=()=>{f.hidden=!0;const t=e.currentNode,n=(e=>{const t=document.createElement("div");return t.innerText=e,t.style.cssText="position:absolute;bottom:20px;left:50%;transform:translateX(-50%);",t})(P[i].clickTips);e.container.appendChild(n),e.map.addEventListener("click",(i=>{i.preventDefault(),n.remove(),"ME-PARENT"!==i.target.parentElement.tagName&&"ME-ROOT"!==i.target.parentElement.tagName||e.createLink(t,e.currentNode)}),{once:!0})}}var J=n(301),Q={};Q.styleTagTransform=X(),Q.setAttributes=Z(),Q.insert=R().bind(null,"head"),Q.domAPI=B(),Q.insertStyleElement=F();H()(J.Z,Q);J.Z&&J.Z.locals&&J.Z.locals;const K=(e,t)=>{const n=document.createElement("span");return n.id=e,n.innerHTML=``,n};function ee(e){e.container.append(function(e){const t=document.createElement("div"),n=K("fullscreen","full"),i=K("toCenter","living"),o=K("zoomout","move"),r=K("zoomin","add");return document.createElement("span").innerText="100%",t.appendChild(n),t.appendChild(i),t.appendChild(o),t.appendChild(r),t.className="mind-elixir-toolbar rb",n.onclick=()=>{e.container.requestFullscreen()},i.onclick=()=>{e.toCenter()},o.onclick=()=>{e.scaleVal<.6||e.scale(e.scaleVal-=.2)},r.onclick=()=>{e.scaleVal>1.6||e.scale(e.scaleVal+=.2)},t}(e)),e.container.append(function(e){const t=document.createElement("div"),n=K("tbltl","left"),i=K("tbltr","right"),o=K("tblts","side");return t.appendChild(n),t.appendChild(i),t.appendChild(o),t.className="mind-elixir-toolbar lt",n.onclick=()=>{e.initLeft()},i.onclick=()=>{e.initRight()},o.onclick=()=>{e.initSide()},t}(e))}const te=document,ne=function(e){if(!e)return;const t=e.getElementsByClassName("insert-preview");for(const e of t||[])e.remove()},ie=function(e,t){const n=t.parentElement.parentElement.contains(e);return e&&"ME-TPC"===e.tagName&&e!==t&&!n&&!0!==e.nodeObj.root};function oe(e){let t,n,i;e.map.addEventListener("dragstart",(function(e){t=e.target,t.parentElement.parentElement.style.opacity="0.5",I.clear()})),e.map.addEventListener("dragend",(async function(o){o.target.style.opacity="",ne(i);const r=t.nodeObj;switch(n){case"before":e.moveNodeBefore(t,i),e.selectNode(g(r.id));break;case"after":e.moveNodeAfter(t,i),e.selectNode(g(r.id));break;case"in":e.moveNode(t,i)}t.parentElement.parentElement.style.opacity="1",t=null})),e.map.addEventListener("dragover",l((function(e){ne(i);const o=te.elementFromPoint(e.clientX,e.clientY-12);if(ie(o,t)){i=o;const t=o.getBoundingClientRect().y;e.clientY>t+o.clientHeight?n="after":e.clientY>t+o.clientHeight/2&&(n="in")}else{const o=te.elementFromPoint(e.clientX,e.clientY+12);if(ie(o,t)){i=o;const t=o.getBoundingClientRect().y;e.clientY0)n[0].className=i;else{const t=te.createElement("div");t.className=i,e.appendChild(t)}}(i,n)}),200))}var re=n(787),ae={};ae.styleTagTransform=X(),ae.setAttributes=Z(),ae.insert=R().bind(null,"head"),ae.domAPI=B(),ae.insertStyleElement=F();H()(re.Z,ae);re.Z&&re.Z.locals&&re.Z.locals;function se(){this.handlers={}}se.prototype={showHandler:function(){},addListener:function(e,t){void 0===this.handlers[e]&&(this.handlers[e]=[]),this.handlers[e].push(t)},fire:function(e,...t){if(this.handlers[e]instanceof Array){const n=this.handlers[e];for(let e=0;e{this.isUndo?this.isUndo=!1:["moveNode","removeNode","addChild","finishEdit","editStyle","editTags","editIcons"].includes(e.name)&&this.history.push(e)})),this.history=[],this.isUndo=!1,this.undo=function(){const e=this.history.pop();e&&(this.isUndo=!0,"moveNode"===e.name?this.moveNode(de(e.obj.fromObj.id),de(e.obj.originParentId)):"removeNode"===e.name?e.originSiblingId?this.insertBefore(de(e.originSiblingId),e.obj):this.addChild(de(e.originParentId),e.obj):"addChild"===e.name||"copyNode"===e.name?this.removeNode(de(e.obj.id)):"finishEdit"===e.name?this.setNodeTopic(de(e.obj.id),e.origin):this.isUndo=!1)},this.container=he.createElement("div"),this.container.className="map-container",this.theme=x||t;const v=he.createElement("div");var M;v.className="map-canvas",this.map=v,this.map.setAttribute("tabindex","0"),this.container.appendChild(this.map),this.mindElixirBox.appendChild(this.container),this.root=he.createElement("me-root"),this.mainNodes=he.createElement("me-children"),this.mainNodes.className="box",this.lines=C("lines"),this.linkController=C("linkcontroller"),this.P2=he.createElement("div"),this.P3=he.createElement("div"),this.P2.className=this.P3.className="circle",this.line1=k(0,0,0,0),this.line2=k(0,0,0,0),this.linkController.appendChild(this.line1),this.linkController.appendChild(this.line2),this.linkSvgGroup=C("topiclinks"),this.map.appendChild(this.root),this.map.appendChild(this.mainNodes),this.map.appendChild(this.lines),this.map.appendChild(this.linkController),this.map.appendChild(this.linkSvgGroup),this.map.appendChild(this.P2),this.map.appendChild(this.P3),this.overflowHidden?this.container.style.overflow="hidden":((M=this).map.addEventListener("click",(e=>{if("ME-EPD"===e.target.tagName)M.expandNode(e.target.previousSibling);else{if(!M.editable)return;"ME-PARENT"===e.target.parentElement.tagName||"ME-ROOT"===e.target.parentElement.tagName?M.selectNode(e.target,!1,e):"path"===e.target.tagName?"g"===e.target.parentElement.tagName&&M.selectLink(e.target.parentElement):"circle"===e.target.className||(M.unselectNode(),M.hideLinkController&&M.hideLinkController())}})),M.map.addEventListener("dblclick",(e=>{e.preventDefault(),M.editable&&("ME-PARENT"!==e.target.parentElement.tagName&&"ME-ROOT"!==e.target.parentElement.tagName||M.beginEdit(e.target))})),M.map.addEventListener("mousemove",(e=>{"true"!==e.target.contentEditable&&I.onMove(e,M.container)})),M.map.addEventListener("mousedown",(e=>{"true"!==e.target.contentEditable&&(I.afterMoving=!1,I.mousedown=!0)})),M.map.addEventListener("mouseleave",(e=>{I.clear()})),M.map.addEventListener("mouseup",(e=>{I.clear()})))}function me(e,t){return async function(...n){this.before[t]&&!await this.before[t].apply(this,n)||e.apply(this,n)}}pe.prototype={addParentLink:a,getObjById:r,generateNewObj:function(){const e=p();return{topic:this.newTopicName||"new node",id:e}},insertSibling:me((function(e,t){const n=e||this.currentNode;if(!n)return;const i=n.nodeObj;if(!0===i.root)return void this.addChild();const o=t||this.generateNewObj();!function(e,t){const n=e.parent.children,i=n.indexOf(e);n.splice(i+1,0,t)}(i,o),a(this.nodeData);const r=n.parentElement,{grp:s,top:l}=this.createWrapper(o),c=r.parentNode.parentNode;c.insertBefore(s,r.parentNode.nextSibling),"box"===c.className?(this.judgeDirection(s,o),this.linkDiv()):this.linkDiv(s.offsetParent),t||this.createInputDiv(l.children[0]),this.selectNode(l.children[0],!0),this.bus.fire("operation",{name:"insertSibling",obj:o})}),"insertSibling"),insertBefore:me((function(e,t){const n=e||this.currentNode;if(!n)return;const i=n.nodeObj;if(!0===i.root)return void this.addChild();const o=t||this.generateNewObj();!function(e,t){const n=e.parent.children,i=n.indexOf(e);n.splice(i,0,t)}(i,o),a(this.nodeData);const r=n.parentElement,{grp:s,top:l}=this.createWrapper(o),c=r.parentNode.parentNode;c.insertBefore(s,r.parentNode),"box"===c.className?(this.judgeDirection(s,o),this.linkDiv()):this.linkDiv(s.offsetParent),t||this.createInputDiv(l.children[0]),this.selectNode(l.children[0],!0),this.bus.fire("operation",{name:"insertSibling",obj:o})}),"insertBefore"),insertParent:me((function(e,t){const n=e||this.currentNode;if(!n)return;const i=n.nodeObj;if(!0===i.root)return;const o=t||this.generateNewObj();!function(e,t){const n=e.parent.children,i=n.indexOf(e);n[i]=t,t.children=[e]}(i,o),a(this.nodeData);const r=n.parentElement.parentElement,{grp:s,top:l}=this.createWrapper(o,!0);l.appendChild(x(!0)),r.insertAdjacentElement("afterend",s);const c=this.createChildren([r]);l.insertAdjacentElement("afterend",c),"box"===r.parentNode.className?(s.className=r.className,r.className="",r.querySelector(".subLines").remove(),this.linkDiv()):this.linkDiv(s.offsetParent),t||this.createInputDiv(l.children[0]),this.selectNode(l.children[0],!0),this.bus.fire("operation",{name:"insertParent",obj:o})}),"insertParent"),addChild:me((function(e,t){const n=e||this.currentNode;if(!n)return;const{newTop:i,newNodeObj:o}=E.call(this,n,t);this.bus.fire("operation",{name:"addChild",obj:o}),t||this.createInputDiv(i.children[0]),this.selectNode(i.children[0],!0)}),"addChild"),copyNode:me((function(e,t){const n=u(e.nodeObj);s(n);const{newNodeObj:i}=E.call(this,t,n);this.bus.fire("operation",{name:"copyNode",obj:i})}),"copyNode"),moveNode:me((function(e,t){const n=e.nodeObj,i=t.nodeObj,o=n.parent.id;if(!1===i.expanded&&(this.expandNode(t,!0),e=g(n.id),t=g(i.id)),!function(e,t){let n=!0;for(;t.parent;){if(t.parent===e){n=!1;break}t=t.parent}return n}(n,i))return;!function(e,t){m(e),t.children?t.children.push(e):t.children=[e]}(n,i),a(this.nodeData);const r=e.parentElement,s=r.parentElement.parentElement,l=t.parentElement;if("box"===s.className?r.parentElement.lastChild.remove():"box"===r.parentElement.className&&(r.style.cssText=""),"ME-PARENT"===l.tagName)if("box"===s.className&&(r.parentElement.className=""),l.children[1])l.nextSibling.appendChild(r.parentElement);else{const e=this.createChildren([r.parentElement]);l.appendChild(x(!0)),l.parentElement.insertBefore(e,l.nextSibling)}else"ME-ROOT"===l.tagName&&(this.judgeDirection(r.parentElement,n),l.nextSibling.appendChild(r.parentElement));this.linkDiv(),this.bus.fire("operation",{name:"moveNode",obj:{fromObj:n,toObj:i,originParentId:o}})}),"moveNode"),removeNode:me((function(e){const t=e||this.currentNode;if(!t)return;const n=t.nodeObj;if(!0===n.root)throw new Error("Can not remove root node");const i=n.parent.children.findIndex((e=>e===n)),o=n.parent.children[i+1],r=o&&o.id,a=m(n),s=t.parentNode;if(0===a){const e=s.parentNode.parentNode.previousSibling;"ME-ROOT"!==e.tagName&&e.children[1].remove(),this.selectParent()}else this.selectPrevSibling()||this.selectNextSibling()||this.selectParent();for(const e in this.linkData){const t=this.linkData[e];t.from!==s.firstChild&&t.to!==s.firstChild||this.removeLink(this.mindElixirBox.querySelector(`[data-linkid=${this.linkData[e].id}]`))}s.parentNode.remove(),this.linkDiv(),this.bus.fire("operation",{name:"removeNode",obj:n,originSiblingId:r,originParentId:n.parent.id})}),"removeNode"),moveUpNode:me((function(e){const t=e||this.currentNode;if(!t)return;const n=t.parentNode.parentNode,i=t.nodeObj;!function(e){const t=e.parent.children,n=t.indexOf(e),i=t[n];0===n?(t[n]=t[t.length-1],t[t.length-1]=i):(t[n]=t[n-1],t[n-1]=i)}(i),n.parentNode.insertBefore(n,n.previousSibling),this.linkDiv(),this.bus.fire("operation",{name:"moveUpNode",obj:i})}),"moveUpNode"),moveDownNode:me((function(e){const t=e||this.currentNode;if(!t)return;const n=t.parentNode.parentNode,i=t.nodeObj;!function(e){const t=e.parent.children,n=t.indexOf(e),i=t[n];n===t.length-1?(t[n]=t[0],t[0]=i):(t[n]=t[n+1],t[n+1]=i)}(i),n.nextSibling?n.insertAdjacentElement("afterend",n.nextSibling):n.parentNode.prepend(n),this.linkDiv(),this.bus.fire("operation",{name:"moveDownNode",obj:i})}),"moveDownNode"),beginEdit:me((function(e){const t=e||this.currentNode;t&&this.createInputDiv(t)}),"beginEdit"),moveNodeBefore:me((function(e,t){const n=e.nodeObj,i=t.nodeObj,o=n.parent.id;!function(e,t){m(e);const n=t.parent.children;let i=0;for(let e=0;e{e-=a/this.scaleVal,t-=s/this.scaleVal;const c=d(r,e,t);l=c.x,p=c.y,this.P2.style.top=t+"px",this.P2.style.left=e+"px",this.currentLink.children[0].setAttribute("d",`M ${l} ${p} C ${e} ${t} ${n} ${i} ${u} ${f}`),this.line1.setAttribute("x1",l),this.line1.setAttribute("y1",p),this.line1.setAttribute("x2",e),this.line1.setAttribute("y2",t),o.delta1.x=e-r.cx,o.delta1.y=t-r.cy})),this.helper2.init(this.map,((r,s)=>{n-=r/this.scaleVal,i-=s/this.scaleVal;const d=h(a,n,i);u=d.x,f=d.y;const m=c(n,i,u,f);this.P3.style.top=i+"px",this.P3.style.left=n+"px",this.currentLink.children[0].setAttribute("d",`M ${l} ${p} C ${e} ${t} ${n} ${i} ${u} ${f}`),this.currentLink.children[1].setAttribute("d",`M ${m.x1} ${m.y1} L ${u} ${f} L ${m.x2} ${m.y2}`),this.line2.setAttribute("x1",n),this.line2.setAttribute("y1",i),this.line2.setAttribute("x2",u),this.line2.setAttribute("y2",f),o.delta2.x=n-a.cx,o.delta2.y=i-a.cy}))},layout:function(){this.root.innerHTML="",this.mainNodes.innerHTML="";const e=this.createTopic(this.nodeData);b(e,this.nodeData),e.draggable=!1,this.root.appendChild(e);const t=this.nodeData.children;if(t&&0!==t.length){if(2===this.direction){let e=0,n=0;t.map((t=>{0===t.direction?e+=1:1===t.direction?n+=1:e<=n?(t.direction=0,e+=1):(t.direction=1,n+=1)}))}this.layoutChildren(this.nodeData.children,this.mainNodes,this.direction)}},linkDiv:function(t){const n=this.mainNodeHorizontalGap||65,i=this.mainNodeVerticalGap||25,o=this.root;o.style.cssText=`top:${1e4-o.offsetHeight/2}px;left:${1e4-o.offsetWidth/2}px;`;const r=this.mainNodes.children;this.lines.innerHTML="";let a,s,l=0,c=0,d=0,h=0,p=0,m=0;if(2===this.direction){let e=0,t=0,n=0,o=0;for(let a=0;am?(s=1e4-Math.max(p)/2,a="r",c=(p-o)/(t-1)):(s=1e4-Math.max(m)/2,a="l",c=(m-n)/(e-1))}else{for(let e=0;e{e.stopPropagation();const t=e.key;if("Enter"===t||"Tab"===t){if(e.shiftKey)return;e.preventDefault(),this.inputDiv.blur(),this.map.focus()}})),t.addEventListener("blur",(()=>{if(!t)return;const i=e.nodeObj,o=t.textContent.trim();i.topic=""===o?n:o,t.remove(),this.inputDiv=t=null,o!==n&&(e.childNodes[0].textContent=i.topic,this.linkDiv(),this.bus.fire("operation",{name:"finishEdit",obj:i,origin:n}))}))},layoutChildren:function(e,t,n){let i;i=t||N.createElement("me-children");for(let t=0;t0){if(a.appendChild(x(o.expanded)),r.appendChild(a),!1!==o.expanded){const e=this.layoutChildren(o.children);r.appendChild(e)}}else r.appendChild(a);i.appendChild(r)}return i},createWrapper:function(e,t){const n=f.createElement("me-wrapper"),i=this.createParent(e);if(n.appendChild(i),!t&&e.children&&e.children.length>0&&(i.appendChild(x(e.expanded)),!1!==e.expanded)){const t=this.layoutChildren(e.children);n.appendChild(t)}return{grp:n,top:i}},createParent:function(e){const t=f.createElement("me-parent"),n=this.createTopic(e);return b(n,e),t.appendChild(n),t},createChildren:function(e){const t=f.createElement("me-children");return t.append(...e),t},createTopic:function(e){const t=f.createElement("me-tpc");return t.nodeObj=e,t.dataset.nodeid="me"+e.id,t.draggable=this.draggable,t},selectNode:function(e,t,n){if(e){if("string"==typeof e)return this.selectNode(g(e));this.currentNode&&(this.currentNode.className=""),e.className="selected",e.scrollIntoView({block:"nearest",inline:"nearest"}),this.currentNode=e,t?this.bus.fire("selectNewNode",e.nodeObj):this.bus.fire("selectNode",e.nodeObj,n)}},unselectNode:function(){this.currentNode&&(this.currentNode.className=""),this.currentNode=null,this.bus.fire("unselectNode")},selectNextSibling:function(){if(!this.currentNode||"meroot"===this.currentNode.dataset.nodeid)return;const e=this.currentNode.parentElement.parentElement.nextSibling;let t;const n=this.currentNode.parentElement.parentElement;if("rhs"===n.className||"lhs"===n.className){const e=this.mindElixirBox.querySelectorAll("."+n.className),i=Array.from(e).indexOf(n);if(!(i+1=0))return!1;t=e[i-1].firstChild.firstChild}else{if(!e)return!1;t=e.firstChild.firstChild}return this.selectNode(t),!0},selectFirstChild:function(){if(!this.currentNode)return;const e=this.currentNode.parentElement.nextSibling;if(e&&e.firstChild){const t=e.firstChild.firstChild.firstChild;this.selectNode(t)}},selectParent:function(){if(!this.currentNode||"meroot"===this.currentNode.dataset.nodeid)return;const e=this.currentNode.parentElement.parentElement.parentElement.previousSibling;if(e){const t=e.firstChild;this.selectNode(t)}},getDataString:function(){const e=z(this);return JSON.stringify(e,((e,t)=>{if("parent"!==e)return"from"===e||"to"===e?t.nodeObj.id:t}))},getData:function(){return JSON.parse(this.getDataString())},getDataMd:function(){const e=z(this).nodeData;let t="# "+e.topic+"\n\n";return function e(n,i){for(let o=0;o{e.insertSibling()},9:()=>{e.addChild()},113:()=>{e.beginEdit()},38:()=>{e.selectPrevSibling()},40:()=>{e.selectNextSibling()},37:()=>{e.currentNode&&("rhs"===e.currentNode.offsetParent.offsetParent.className?e.selectParent():("lhs"===e.currentNode.offsetParent.offsetParent.className||e.currentNode.nodeObj.root)&&e.selectFirstChild())},39:()=>{e.currentNode&&("rhs"===e.currentNode.offsetParent.offsetParent.className||e.currentNode.nodeObj.root?e.selectFirstChild():"lhs"===e.currentNode.offsetParent.offsetParent.className&&e.selectParent())},33(){e.moveUpNode()},34(){e.moveDownNode()},67(t){(t.metaKey||t.ctrlKey)&&(e.waitCopy=e.currentNode)},86(t){e.waitCopy&&(t.metaKey||t.ctrlKey)&&(e.copyNode(e.waitCopy,e.currentNode),e.waitCopy=null)},90:t=>{e.allowUndo&&(t.metaKey||t.ctrlKey)&&e.undo()},187:t=>{if(t.metaKey||t.ctrlKey){if(e.scaleVal>1.6)return;e.scale(e.scaleVal+=.2)}},189:t=>{if(t.metaKey||t.ctrlKey){if(e.scaleVal<.6)return;e.scale(e.scaleVal-=.2)}}};e.map.onkeydown=n=>{n.preventDefault(),e.editable&&n.target===n.currentTarget&&(8===n.keyCode||46===n.keyCode?e.currentLink?e.removeLink():e.removeNode():t[n.keyCode]&&t[n.keyCode](n))}}(this),/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)&&this.mobileMenu?function(e,t){const n=(e,t)=>{const n=document.createElement("div");return n.id=e,n.innerHTML=``,n},i=n("cm-add_child","zijiedian"),o=n("cm-add_sibling","tongjijiedian-"),r=n("cm-remove_child","shanchu2"),a=n("cm-up","rising"),s=n("cm-down","falling"),l=n("cm-edit","edit"),c=document.createElement("ul");if(c.className="menu-list",t&&t.extend)for(let e=0;e{i.onclick(e)}}const d=document.createElement("mmenu");d.className="mobile-menu",d.appendChild(i),d.appendChild(o),d.appendChild(r),d.appendChild(a),d.appendChild(s),d.appendChild(l),d.hidden=!0,e.container.append(d);let h=!0;e.bus.addListener("unselectNode",(function(){d.hidden=!0})),e.bus.addListener("selectNode",(function(e){d.hidden=!1,h=!!e.root})),d.onclick=e=>{e.target===d&&(d.hidden=!0)},i.onclick=t=>{e.addChild()},o.onclick=t=>{h||e.insertSibling()},r.onclick=t=>{h||e.removeNode()},a.onclick=t=>{h||e.moveUpNode()},s.onclick=t=>{h||e.moveDownNode()},l.onclick=t=>{e.beginEdit()}}(this):this.contextMenu&&q(this,this.contextMenuOption),this.draggable&&oe(this);const t=this.theme.cssVar,n=Object.keys(t);for(let e=0;e({nodeData:{id:p(),topic:e||"new topic",root:!0,children:[]},linkData:{}});const ue=pe})(),i=i.default})())); +(function(){"use strict";try{if(typeof document<"u"){var i=document.createElement("style");i.appendChild(document.createTextNode(".mind-elixir{--gap: 30px;--root-radius: 30px;--main-radius: 20px;--root-color: #ffffff;--root-bgcolor: #4c4f69;--main-color: #444446;--main-bgcolor: #ffffff;--topic-padding: 3px;--color: #777777;--bgcolor: #f6f6f6;--selected: #4dc4ff;--panel-color: #444446;--panel-bgcolor: #ffffff;--panel-border-color: #eaeaea;position:relative;-webkit-tap-highlight-color:rgba(0,0,0,0);font-family:-apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif}.mind-elixir .hyper-link{text-decoration:none}.map-container{-webkit-user-select:none;user-select:none;height:100%;width:100%;overflow:scroll;font-size:15px}.map-container::-webkit-scrollbar{width:0px;height:0px}.map-container .selected{box-shadow:0 0 0 2px var(--selected)}.map-container .lhs{direction:rtl}.map-container .lhs me-tpc{direction:ltr}.map-container .map-canvas{height:20000px;width:20000px;position:relative;-webkit-user-select:none;user-select:none;transition:transform .3s;transform:scale(1);background-color:var(--bgcolor)}.map-container .map-canvas me-nodes{position:absolute;display:flex;justify-content:center;align-items:center;height:fit-content;width:fit-content}.map-container .map-canvas me-root{position:relative}.map-container .map-canvas me-root me-tpc{display:block;font-size:25px;line-height:1.2em;color:var(--root-color);padding:10px var(--gap);border-radius:var(--root-radius);white-space:pre-wrap;background-color:var(--root-bgcolor)}.map-container .map-canvas me-root me-tpc #input-box{padding:10px var(--gap)}.map-container me-main>me-wrapper{position:relative;margin:20px 65px}.map-container me-main>me-wrapper>me-parent{margin:var(--gap);padding:0}.map-container me-main>me-wrapper>me-parent>me-tpc{border-radius:var(--main-radius);background-color:var(--main-bgcolor);border:2px solid var(--main-color);color:var(--main-color);padding:8px var(--gap)}.map-container me-main>me-wrapper>me-parent>me-tpc #input-box{padding:8px var(--gap)}.map-container me-wrapper{display:block;pointer-events:none;width:fit-content}.map-container me-children,.map-container me-parent{display:inline-block;vertical-align:middle}.map-container me-parent{position:relative;cursor:pointer;padding:6px var(--gap);margin-top:10px}.map-container me-parent me-tpc{position:relative;display:block;border-radius:3px;color:var(--color);pointer-events:all;max-width:35em;white-space:pre-wrap;padding:var(--topic-padding);line-height:1.2em}.map-container me-parent me-tpc .insert-preview{position:absolute;width:100%;left:0;z-index:9}.map-container me-parent me-tpc .show{background:#7ad5ff;pointer-events:none;opacity:.7}.map-container me-parent me-tpc .before{height:14px;top:-14px}.map-container me-parent me-tpc .in{height:100%;top:0}.map-container me-parent me-tpc .after{height:14px;bottom:-14px}.map-container me-parent me-epd{position:absolute;height:18px;width:18px;opacity:.8;background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdD0iMTY1NjY1NDcxNzI0MiIgY2xhc3M9Imljb24iIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIHZlcnNpb249IjEuMSIKICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+CiAgICA8cGF0aCBkPSJNNTEyIDc0LjY2NjY2N0MyNzAuOTMzMzMzIDc0LjY2NjY2NyA3NC42NjY2NjcgMjcwLjkzMzMzMyA3NC42NjY2NjcgNTEyUzI3MC45MzMzMzMgOTQ5LjMzMzMzMyA1MTIgOTQ5LjMzMzMzMyA5NDkuMzMzMzMzIDc1My4wNjY2NjcgOTQ5LjMzMzMzMyA1MTIgNzUzLjA2NjY2NyA3NC42NjY2NjcgNTEyIDc0LjY2NjY2N3oiIHN0cm9rZS13aWR0aD0iNTQiIHN0cm9rZT0nYmxhY2snIGZpbGw9J3doaXRlJyA+PC9wYXRoPgogICAgPHBhdGggZD0iTTY4Mi42NjY2NjcgNDgwaC0xMzguNjY2NjY3VjM0MS4zMzMzMzNjMC0xNy4wNjY2NjctMTQuOTMzMzMzLTMyLTMyLTMycy0zMiAxNC45MzMzMzMtMzIgMzJ2MTM4LjY2NjY2N0gzNDEuMzMzMzMzYy0xNy4wNjY2NjcgMC0zMiAxNC45MzMzMzMtMzIgMzJzMTQuOTMzMzMzIDMyIDMyIDMyaDEzOC42NjY2NjdWNjgyLjY2NjY2N2MwIDE3LjA2NjY2NyAxNC45MzMzMzMgMzIgMzIgMzJzMzItMTQuOTMzMzMzIDMyLTMydi0xMzguNjY2NjY3SDY4Mi42NjY2NjdjMTcuMDY2NjY3IDAgMzItMTQuOTMzMzMzIDMyLTMycy0xNC45MzMzMzMtMzItMzItMzJ6Ij48L3BhdGg+Cjwvc3ZnPg==);background-repeat:no-repeat;background-size:contain;background-position:center;pointer-events:all;z-index:9}.map-container me-parent me-epd.minus{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgdD0iMTY1NjY1NTU2NDk4NSIgY2xhc3M9Imljb24iIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIHZlcnNpb249IjEuMSIKICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCI+CiAgICA8cGF0aCBkPSJNNTEyIDc0LjY2NjY2N0MyNzAuOTMzMzMzIDc0LjY2NjY2NyA3NC42NjY2NjcgMjcwLjkzMzMzMyA3NC42NjY2NjcgNTEyUzI3MC45MzMzMzMgOTQ5LjMzMzMzMyA1MTIgOTQ5LjMzMzMzMyA5NDkuMzMzMzMzIDc1My4wNjY2NjcgOTQ5LjMzMzMzMyA1MTIgNzUzLjA2NjY2NyA3NC42NjY2NjcgNTEyIDc0LjY2NjY2N3oiIHN0cm9rZS13aWR0aD0iNTQiIHN0cm9rZT0nYmxhY2snIGZpbGw9J3doaXRlJyA+PC9wYXRoPgogICAgPHBhdGggZD0iTTY4Mi42NjY2NjcgNTQ0SDM0MS4zMzMzMzNjLTE3LjA2NjY2NyAwLTMyLTE0LjkzMzMzMy0zMi0zMnMxNC45MzMzMzMtMzIgMzItMzJoMzQxLjMzMzMzNGMxNy4wNjY2NjcgMCAzMiAxNC45MzMzMzMgMzIgMzJzLTE0LjkzMzMzMyAzMi0zMiAzMnoiPjwvcGF0aD4KPC9zdmc+)!important;transition:opacity .3s;opacity:0}.map-container me-parent me-epd.minus:hover{opacity:.8}.map-container .icon{width:1em;height:1em;vertical-align:-.15em;fill:currentColor;overflow:hidden}.map-container .lines,.map-container .summary,.map-container .subLines,.map-container .topiclinks,.map-container .linkcontroller{position:absolute;height:102%;width:100%;top:0;left:0}.map-container .topiclinks,.map-container .linkcontroller,.map-container .summary{pointer-events:none}.map-container .topiclinks text,.map-container .linkcontroller text,.map-container .summary text{pointer-events:all}.map-container .topiclinks .selected,.map-container .linkcontroller .selected,.map-container .summary .selected{pointer-events:none}.map-container .lines,.map-container .subLines{pointer-events:none;z-index:-1}.map-container .topiclinks *,.map-container .linkcontroller *{z-index:100}.map-container .topiclinks g{cursor:pointer}.map-container #input-box{position:absolute;top:0;left:0;padding:var(--topic-padding);color:var(--color);background-color:var(--bgcolor);width:max-content;max-width:35em;z-index:11;direction:ltr;-webkit-user-select:auto;user-select:auto;pointer-events:all}.map-container me-tpc>div,.map-container me-tpc>span,.map-container me-tpc>img{pointer-events:none}.map-container me-tpc>img{display:block;margin-bottom:8px;object-fit:cover}.map-container me-tpc>.text{display:inline-block}.map-container .circle{position:absolute;height:10px;width:10px;margin-top:-5px;margin-left:-5px;border-radius:100%;background:#aaa;cursor:pointer}.map-container .tags{direction:ltr}.map-container .tags span{display:inline-block;border-radius:3px;padding:2px 4px;background:#d6f0f8;color:#276f86;margin:2px 3px 0 0;font-size:12px;line-height:1.3em}.map-container .icons{display:inline-block;direction:ltr;margin-right:10px}.map-container .icons span{display:inline-block}.map-container .mind-elixir-ghost{position:fixed;top:-100%;left:-100%;box-sizing:content-box;opacity:.5;background-color:#f6f6f6;max-width:200px;width:fit-content;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding:8px 16px;border-radius:6px;border:#666666 2px solid}.map-container .selection-area{background:#4f90f22d;border:1px solid #4f90f2}.mind-elixir .context-menu{position:fixed;top:0;left:0;width:100%;height:100%;z-index:99}.mind-elixir .context-menu .menu-list{position:fixed;list-style:none;margin:0;padding:0;font:300 15px Roboto,sans-serif;color:var(--panel-color);box-shadow:0 12px 15px #0003}.mind-elixir .context-menu .menu-list li{min-width:200px;overflow:hidden;white-space:nowrap;padding:10px 14px;background:var(--panel-bgcolor);border-bottom:1px solid var(--panel-border-color)}.mind-elixir .context-menu .menu-list li a{color:#333;text-decoration:none}.mind-elixir .context-menu .menu-list li.disabled{display:none;color:#5e5e5e;background-color:#f7f7f7}.mind-elixir .context-menu .menu-list li.disabled:hover{cursor:default;background-color:#f7f7f7}.mind-elixir .context-menu .menu-list li:hover{cursor:pointer;filter:brightness(.9)}.mind-elixir .context-menu .menu-list li:first-child{border-radius:5px 5px 0 0}.mind-elixir .context-menu .menu-list li:last-child{border-bottom:0;border-radius:0 0 5px 5px}.mind-elixir .context-menu .menu-list li span:last-child{float:right}.mind-elixir .tips{position:absolute;bottom:20px;left:50%;transform:translate(-50%);color:var(--panel-color);font-weight:bolder}.mind-elixir .mobile-menu{position:absolute;left:20px;bottom:70px;z-index:99;margin:0;padding:0;color:#333;border-radius:5px;box-shadow:0 12px 15px #0003;overflow:hidden}.mind-elixir .mobile-menu *{transition:color .4s,background-color .4s}.mind-elixir .mobile-menu div{float:left;text-align:center;width:30px;overflow:hidden;white-space:nowrap;padding:8px;background-color:#fff;border-bottom:1px solid #ecf0f1}.mind-elixir .mobile-menu div a{color:#333;text-decoration:none}.mind-elixir .mobile-menu div.disabled{color:#5e5e5e;background-color:#f7f7f7}.mind-elixir .mobile-menu div.disabled:hover{cursor:default;background-color:#f7f7f7}.mind-elixir .mobile-menu div:hover{cursor:pointer;background-color:#ecf0f1}.mind-elixir-toolbar{font-family:iconfont;position:absolute;color:var(--panel-color);background:var(--panel-bgcolor);padding:10px;border-radius:5px;box-shadow:0 1px 2px #0003}.mind-elixir-toolbar svg{display:inline-block}.mind-elixir-toolbar span:active{opacity:.5}.mind-elixir-toolbar.rb{right:20px;bottom:20px}.mind-elixir-toolbar.rb span+span{margin-left:10px}.mind-elixir-toolbar.lt{font-size:20px;left:20px;top:20px}.mind-elixir-toolbar.lt span{display:block}.mind-elixir-toolbar.lt span+span{margin-top:10px}")),document.head.appendChild(i)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})(); +(function(e) { + var t, n, i, o, s, r, l = '', c = (c = document.getElementsByTagName("script"))[c.length - 1].getAttribute("data-injectcss"); + if (c && !e.__iconfont__svg__cssinject__) { + e.__iconfont__svg__cssinject__ = !0; + try { + document.write( + "" + ); + } catch (a) { + console && console.log(a); + } + } + function h() { + s || (s = !0, i()); + } + t = function() { + var a, u, d, p; + (p = document.createElement("div")).innerHTML = l, l = null, (d = p.getElementsByTagName("svg")[0]) && (d.setAttribute("aria-hidden", "true"), d.style.position = "absolute", d.style.width = 0, d.style.height = 0, d.style.overflow = "hidden", a = d, (u = document.body).firstChild ? (p = a, (d = u.firstChild).parentNode.insertBefore(p, d)) : u.appendChild(a)); + }, document.addEventListener ? ~["complete", "loaded", "interactive"].indexOf(document.readyState) ? setTimeout(t, 0) : (n = function() { + document.removeEventListener("DOMContentLoaded", n, !1), t(); + }, document.addEventListener("DOMContentLoaded", n, !1)) : document.attachEvent && (i = t, o = e.document, s = !1, (r = function() { + try { + o.documentElement.doScroll("left"); + } catch { + return void setTimeout(r, 50); + } + h(); + })(), o.onreadystatechange = function() { + o.readyState == "complete" && (o.onreadystatechange = null, h()); + }); +})(window); +const S = 0, H = 1, K = 2, M = 30, L = 8, Le = { + name: "Latte", + palette: ["#dd7878", "#ea76cb", "#8839ef", "#e64553", "#fe640b", "#df8e1d", "#40a02b", "#209fb5", "#1e66f5", "#7287fd"], + cssVar: { + "--main-color": "#444446", + "--main-bgcolor": "#ffffff", + "--color": "#777777", + "--bgcolor": "#f6f6f6", + "--panel-color": "#444446", + "--panel-bgcolor": "#ffffff", + "--panel-border-color": "#eaeaea" + } +}, Me = { + name: "Dark", + palette: ["#848FA0", "#748BE9", "#D2F9FE", "#4145A5", "#789AFA", "#706CF4", "#EF987F", "#775DD5", "#FCEECF", "#DA7FBC"], + cssVar: { + "--main-color": "#ffffff", + "--main-bgcolor": "#4c4f69", + "--color": "#cccccc", + "--bgcolor": "#252526", + "--panel-color": "#ffffff", + "--panel-bgcolor": "#2d3748", + "--panel-border-color": "#696969" + } +}; +function ee(e) { + return e.replace(/&/g, "&").replace(/ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), te = function(e, t) { + if (t.id === e) + return t; + if (t.children && t.children.length) { + for (let n = 0; n < t.children.length; n++) { + const i = te(e, t.children[n]); + if (i) + return i; + } + return null; + } else + return null; +}, T = (e, t) => { + if (e.parent = t, e.children) + for (let n = 0; n < e.children.length; n++) + T(e.children[n], e); +}; +function Te(e) { + if (e.id = U(), e.children) + for (let t = 0; t < e.children.length; t++) + Te(e.children[t]); +} +const Ke = (e, t) => { + let n = Date.now(); + return function(...i) { + Date.now() - n >= t && (e(...i), n = Date.now()); + }; +}; +function $e(e, t, n, i) { + const o = i - t, s = e - n; + let r = Math.atan(Math.abs(o) / Math.abs(s)) / 3.14 * 180; + s < 0 && o > 0 && (r = 180 - r), s < 0 && o < 0 && (r = 180 + r), s > 0 && o < 0 && (r = 360 - r); + const l = 15, c = 30, h = r + c, a = r - c; + return { + x1: n + Math.cos(Math.PI * h / 180) * l, + y1: i - Math.sin(Math.PI * h / 180) * l, + x2: n + Math.cos(Math.PI * a / 180) * l, + y2: i - Math.sin(Math.PI * a / 180) * l + }; +} +function U() { + return ((/* @__PURE__ */ new Date()).getTime().toString(16) + Math.random().toString(16).substr(2)).substr(2, 16); +} +const Ue = function() { + const e = U(); + return { + topic: this.newTopicName, + id: e + }; +}; +function Ge(e, t) { + let n = !0; + for (; t.parent; ) { + if (t.parent === e) { + n = !1; + break; + } + t = t.parent; + } + return n; +} +const P = (e) => { + var i; + const t = (i = e.parent) == null ? void 0 : i.children, n = t.indexOf(e); + return { siblings: t, index: n }; +}; +function Je(e) { + const { siblings: t, index: n } = P(e), i = t[n]; + n === 0 ? (t[n] = t[t.length - 1], t[t.length - 1] = i) : (t[n] = t[n - 1], t[n - 1] = i); +} +function Qe(e) { + const { siblings: t, index: n } = P(e), i = t[n]; + n === t.length - 1 ? (t[n] = t[0], t[0] = i) : (t[n] = t[n + 1], t[n + 1] = i); +} +function oe(e) { + const { siblings: t, index: n } = P(e); + return t.splice(n, 1), t.length; +} +function Ze(e, t) { + const { siblings: n, index: i } = P(e); + n.splice(i + 1, 0, t); +} +function et(e, t) { + const { siblings: n, index: i } = P(e); + n.splice(i, 0, t); +} +function tt(e, t) { + const { siblings: n, index: i } = P(e); + n[i] = t, t.children = [e]; +} +function nt(e, t) { + oe(e), t.children ? t.children.push(e) : t.children = [e]; +} +function it(e, t) { + oe(e); + const { siblings: n, index: i } = P(t); + n.splice(i, 0, e); +} +function ot(e, t) { + oe(e); + const { siblings: n, index: i } = P(t); + n.splice(i + 1, 0, e); +} +function De(e) { + return JSON.parse( + JSON.stringify(e, (n, i) => { + if (n !== "parent") + return i; + }) + ); +} +const W = (e, t) => { + let n = 0, i = 0; + for (; t && t !== e; ) + n += t.offsetLeft, i += t.offsetTop, t = t.offsetParent; + return { offsetLeft: n, offsetTop: i }; +}, N = (e, t) => { + for (const n in t) + e.setAttribute(n, t[n]); +}, D = { + moved: !1, + // diffrentiate click and move + mousedown: !1, + lastX: 0, + lastY: 0, + onMove(e, t) { + if (this.mousedown) { + if (this.moved = !0, !this.lastX) { + this.lastX = e.pageX, this.lastY = e.pageY; + return; + } + const n = this.lastX - e.pageX, i = this.lastY - e.pageY; + t.scrollTo(t.scrollLeft + n, t.scrollTop + i), this.lastX = e.pageX, this.lastY = e.pageY; + } + }, + clear() { + this.moved = !1, this.mousedown = !1, this.lastX = 0, this.lastY = 0; + } +}, fe = (e) => e.tagName === "ME-TPC"; +function st(e) { + e.map.addEventListener("click", (t) => { + if (D.moved) { + D.clear(); + return; + } + e.unselectNode(), e.unselectNodes(), e.unselectSummary(), e.unselectLink(); + const n = t.target; + if (n.tagName === "ME-EPD") + e.expandNode(n.previousSibling); + else if (e.editable) + fe(n) ? e.selectNode(n, !1, t) : n.tagName === "text" ? n.dataset.type === "custom-link" ? e.selectLink(n.parentElement) : e.selectSummary(n.parentElement) : n.className === "circle" || e.hideLinkController && e.hideLinkController(); + else + return; + }), e.map.addEventListener("dblclick", (t) => { + if (t.preventDefault(), !e.editable) + return; + const n = t.target; + fe(n) ? e.beginEdit(n) : n.tagName === "text" && (n.dataset.type === "custom-link" ? e.editCutsomLinkLabel(n.parentElement) : e.editSummary(n.parentElement)); + }), e.map.addEventListener("mousemove", (t) => { + t.target.contentEditable !== "true" && D.onMove(t, e.container); + }), e.map.addEventListener("mousedown", (t) => { + t.button === 2 && t.target.contentEditable !== "true" && (D.moved = !1, D.mousedown = !0); + }), e.map.addEventListener("mouseleave", (t) => { + console.log(t.button), t.button === 2 && D.clear(); + }), e.map.addEventListener("mouseup", (t) => { + t.button === 2 && D.clear(); + }), e.map.addEventListener("contextmenu", (t) => { + t.preventDefault(); + }); +} +const rt = { + create() { + return { + handlers: {}, + showHandler: function() { + console.log(this.handlers); + }, + addListener: function(e, t) { + this.handlers[e] === void 0 && (this.handlers[e] = []), this.handlers[e].push(t); + }, + fire: function(e, ...t) { + if (this.handlers[e] instanceof Array) { + const n = this.handlers[e]; + for (let i = 0; i < n.length; i++) + n[i](...t); + } + }, + removeListener: function(e, t) { + if (!this.handlers[e]) + return; + const n = this.handlers[e]; + if (!t) + n.length = 0; + else if (n.length) + for (let i = 0; i < n.length; i++) + n[i] === t && this.handlers[e].splice(i, 1); + } + }; + } +}, ne = document, lt = function() { + console.time("layout"), this.nodes.innerHTML = ""; + const e = this.createTopic(this.nodeData); + de(e, this.nodeData), e.draggable = !1; + const t = ne.createElement("me-root"); + t.appendChild(e); + const n = this.nodeData.children || []; + if (this.direction === K) { + let i = 0, o = 0; + n.map((s) => { + s.direction === S ? i += 1 : s.direction === H ? o += 1 : i <= o ? (s.direction = S, i += 1) : (s.direction = H, o += 1); + }); + } + ct(this, n, t), console.timeEnd("layout"); +}, ct = function(e, t, n) { + const i = ne.createElement("me-main"); + i.className = "lhs"; + const o = ne.createElement("me-main"); + o.className = "rhs"; + for (let s = 0; s < t.length; s++) { + const r = t[s], { grp: l } = e.createWrapper(r); + e.direction === K ? r.direction === S ? i.appendChild(l) : o.appendChild(l) : e.direction === S ? i.appendChild(l) : o.appendChild(l); + } + e.nodes.appendChild(i), e.nodes.appendChild(n), e.nodes.appendChild(o), e.nodes.appendChild(e.lines); +}, at = function(e, t) { + const n = ne.createElement("me-children"); + for (let i = 0; i < t.length; i++) { + const o = t[i], { grp: s } = e.createWrapper(o); + n.appendChild(s); + } + return n; +}, k = document, E = (e, t) => { + const i = (t ? t.mindElixirBox : k).querySelector(`[data-nodeid=me${e}]`); + if (!i) + throw new Error(`FindEle: Node ${e} not found, maybe it's collapsed.`); + return i; +}, de = function(e, t) { + if (e.innerHTML = "", t.style && (e.style.color = t.style.color || "", e.style.background = t.style.background || "", e.style.fontSize = t.style.fontSize + "px", e.style.fontWeight = t.style.fontWeight || "normal"), t.branchColor && (e.style.borderColor = t.branchColor), t.image) { + const n = t.image; + if (n.url && n.width && n.height) { + const i = k.createElement("img"); + i.src = n.url, i.style.width = n.width + "px", i.style.height = n.height + "px", e.appendChild(i), e.image = i; + } else + console.warn("image url/width/height are required"); + } else + e.image && (e.image = void 0); + { + const n = k.createElement("span"); + n.className = "text", n.textContent = t.topic, e.appendChild(n), e.text = n; + } + if (t.hyperLink) { + const n = k.createElement("a"); + n.className = "hyper-link", n.target = "_blank", n.innerText = "🔗", n.href = t.hyperLink, e.appendChild(n), e.linkContainer = n; + } else + e.linkContainer && (e.linkContainer = void 0); + if (t.icons && t.icons.length) { + const n = k.createElement("span"); + n.className = "icons", n.innerHTML = t.icons.map((i) => `${ee(i)}`).join(""), e.appendChild(n), e.icons = n; + } else + e.icons && (e.icons = void 0); + if (t.tags && t.tags.length) { + const n = k.createElement("div"); + n.className = "tags", n.innerHTML = t.tags.map((i) => `${ee(i)}`).join(""), e.appendChild(n), e.tags = n; + } else + e.tags && (e.tags = void 0); +}, dt = function(e, t) { + const n = k.createElement("me-wrapper"), { p: i, tpc: o } = this.createParent(e); + if (n.appendChild(i), !t && e.children && e.children.length > 0) { + const s = se(e.expanded); + if (i.appendChild(s), e.expanded !== !1) { + const r = at(this, e.children); + n.appendChild(r); + } + } + return { grp: n, top: i, tpc: o }; +}, ht = function(e) { + const t = k.createElement("me-parent"), n = this.createTopic(e); + return de(n, e), t.appendChild(n), { p: t, tpc: n }; +}, ut = function(e) { + const t = k.createElement("me-children"); + return t.append(...e), t; +}, ft = function(e) { + const t = k.createElement("me-tpc"); + return t.nodeObj = e, t.dataset.nodeid = "me" + e.id, t.draggable = this.draggable, t; +}; +function Oe(e) { + const t = k.createRange(); + t.selectNodeContents(e); + const n = window.getSelection(); + n && (n.removeAllRanges(), n.addRange(t)); +} +const pt = function(e) { + if (console.time("editTopic"), !e) + return; + const t = k.createElement("div"), n = e.text.textContent; + e.appendChild(t), t.id = "input-box", t.textContent = n, t.contentEditable = "true", t.spellcheck = !1, t.style.cssText = `min-width:${e.offsetWidth - 8}px;`, this.direction === S && (t.style.right = "0"), t.focus(), Oe(t), this.bus.fire("operation", { + name: "beginEdit", + obj: e.nodeObj + }), t.addEventListener("keydown", (i) => { + i.stopPropagation(); + const o = i.key; + if (o === "Enter" || o === "Tab") { + if (i.shiftKey) + return; + i.preventDefault(), t == null || t.blur(), this.map.focus(); + } + }), t.addEventListener("blur", () => { + var s; + if (!t) + return; + const i = e.nodeObj, o = ((s = t.textContent) == null ? void 0 : s.trim()) || ""; + console.log(o), o === "" ? i.topic = n : i.topic = o, t.remove(), o !== n && (e.text.textContent = i.topic, this.linkDiv(), this.bus.fire("operation", { + name: "finishEdit", + obj: i, + origin: n + })); + }), console.timeEnd("editTopic"); +}, se = function(e) { + const t = k.createElement("me-epd"); + return t.expanded = e !== !1, t.className = e !== !1 ? "minus" : "", t; +}, z = document, R = "http://www.w3.org/2000/svg", mt = function(e, t) { + const n = z.createElementNS(R, "path"); + return n.setAttribute("d", e), n.setAttribute("stroke", t || "#666"), n.setAttribute("fill", "none"), n.setAttribute("stroke-width", "3"), n; +}, X = function(e) { + const t = z.createElementNS(R, "svg"); + return t.setAttribute("class", e), t.setAttribute("overflow", "visible"), t; +}, pe = function() { + const e = z.createElementNS(R, "line"); + return e.setAttribute("stroke", "#bbb"), e.setAttribute("fill", "none"), e.setAttribute("stroke-width", "2"), e; +}, gt = function(e, t) { + const n = z.createElementNS(R, "path"); + return n.setAttribute("d", e), n.setAttribute("stroke", t || "#555"), n.setAttribute("fill", "none"), n.setAttribute("stroke-linecap", "square"), n.setAttribute("stroke-width", "2"), n; +}, vt = function(e, t) { + const n = { + stroke: "rgb(235, 95, 82)", + fill: "none", + "stroke-linecap": "cap", + "stroke-width": "2" + }, i = z.createElementNS(R, "g"), o = z.createElementNS(R, "path"), s = z.createElementNS(R, "path"); + return N(s, { + d: t, + ...n + }), N(o, { + d: e, + ...n, + "stroke-dasharray": "8,2" + }), i.appendChild(o), i.appendChild(s), i; +}, Ae = function(e, t, n) { + if (console.time("editSummary"), !t) + return; + const i = document.createElement("div"); + e.nodes.appendChild(i); + const o = t.innerHTML; + i.id = "input-box", i.textContent = o, i.contentEditable = "true", i.spellcheck = !1; + const s = t.getAttribute("x") + "px", r = t.getAttribute("y") + "px"; + i.style.cssText = `min-width:${100 - 8}px;position:absolute;left:${s};top:${r};`; + const l = t.getAttribute("text-anchor"); + l === "end" ? i.style.cssText += "transform: translate(-100%, -100%);" : l === "middle" ? i.style.cssText += "transform: translate(-50%, -100%);" : i.style.cssText += "transform: translate(0, -100%);", i.focus(), Oe(i), i.addEventListener("keydown", (c) => { + c.stopPropagation(); + const h = c.key; + if (h === "Enter" || h === "Tab") { + if (c.shiftKey) + return; + c.preventDefault(), i.blur(), e.map.focus(); + } + }), i.addEventListener("blur", () => { + i && n(i); + }), console.timeEnd("editSummary"); +}; +let Pe = He; +const bt = function(e) { + console.time("linkDiv"); + const t = this.map.querySelector("me-root"); + this.nodes.style.top = `${1e4 - this.nodes.offsetHeight / 2}px`, this.nodes.style.left = `${1e4 - t.offsetLeft - t.offsetWidth / 2}px`; + const n = this.map.querySelectorAll("me-main > me-wrapper"); + this.lines.innerHTML = "", Pe = this.subLinkStyle === 2 ? wt : He; + for (let i = 0; i < n.length; i++) { + const o = n[i], s = o.querySelector("me-tpc"), r = o.firstChild, l = o.parentNode.className; + let c = t.offsetLeft + t.offsetWidth / 2; + const h = t.offsetTop + t.offsetHeight / 2; + let a; + const u = this.theme.palette, d = s.nodeObj.branchColor || u[i % u.length], { offsetLeft: p, offsetTop: g } = W(this.nodes, r); + l === "lhs" ? a = p + r.offsetWidth : a = p; + const m = g + r.offsetHeight / 2; + let f = ""; + if (this.mainLinkStyle === 2) + this.direction === K && (l === "lhs" ? c = c - t.offsetWidth / 6 : c = c + t.offsetWidth / 6), f = yt({ x1: c, y1: h, x2: a, y2: m }); + else { + const b = (1 - Math.abs(m - o.parentElement.offsetTop - o.parentElement.offsetHeight / 2) / o.parentElement.offsetHeight) * 0.25 * (t.offsetWidth / 2); + l === "lhs" ? c = c - t.offsetWidth / 10 - b : c = c + t.offsetWidth / 10 + b, f = xt({ x1: c, y1: h, x2: a, y2: m }); + } + this.lines.appendChild(mt(f, d)); + const v = o.children[0].children[1]; + if (v && (v.style.top = (v.parentNode.offsetHeight - v.offsetHeight) / 2 + "px", l === "lhs" ? v.style.left = "-10px" : v.style.right = "-10px"), !(e && e !== o) && o.childElementCount) { + const x = X("subLines"), b = o.lastChild; + b.tagName === "svg" && b.remove(), o.appendChild(x); + const y = o.firstChild, C = o.children[1].children, _ = je(C, y, l, !0); + x.appendChild(gt(_, d)); + } + } + this.renderCustomLink(), this.renderSummary(), console.timeEnd("linkDiv"); +}, je = function(e, t, n, i) { + let o = ""; + const s = t.offsetTop, r = t.offsetLeft, l = t.offsetWidth, c = t.offsetHeight; + for (let h = 0; h < e.length; h++) { + const a = e[h], u = a.firstChild, d = u.offsetTop, p = u.offsetLeft, g = u.offsetWidth, m = u.offsetHeight; + o += Pe({ pT: s, pL: r, pW: l, pH: c, cT: d, cL: p, cW: g, cH: m, direction: n, isFirst: i }); + const f = u.children[1]; + if (f) { + if (f.style.bottom = -(f.offsetHeight / 2) + "px", n === "lhs" ? f.style.left = "10px" : n === "rhs" && (f.style.right = "10px"), !f.expanded) + continue; + } else + continue; + const v = a.children[1].children; + v.length > 0 && (o += je(v, u, n)); + } + return o; +}; +function yt({ x1: e, y1: t, x2: n, y2: i }) { + return `M ${e} ${t} V ${i > t ? i - 20 : i + 20} C ${e} ${i} ${e} ${i} ${n > e ? e + 20 : e - 20} ${i} H ${n}`; +} +function xt({ x1: e, y1: t, x2: n, y2: i }) { + return `M ${e} ${t} Q ${e} ${i} ${n} ${i}`; +} +function wt({ pT: e, pL: t, pW: n, pH: i, cT: o, cL: s, cW: r, cH: l, direction: c, isFirst: h }) { + let a; + h ? a = e + i / 2 : a = e + i; + const u = o + l; + let d = 0, p = 0, g = 0; + return c === "lhs" ? (d = t + M, p = s, g = s + r) : c === "rhs" && (d = t + n - M, p = s + r, g = s), u < a + 50 && u > a - 50 ? `M ${d} ${a} H ${g} V ${u} H ${p}` : u >= a ? `M ${d} ${a} H ${g} V ${u - L} A ${L} ${L} 0 0 ${d > p ? 1 : 0} ${d > p ? g - L : g + L} ${u} H ${p}` : `M ${d} ${a} H ${g} V ${u + L} A ${L} ${L} 0 0 ${d > p ? 0 : 1} ${d > p ? g - L : g + L} ${u} H ${p}`; +} +function He({ pT: e, pL: t, pW: n, pH: i, cT: o, cL: s, cW: r, cH: l, direction: c, isFirst: h }) { + let a = 0, u = 0; + h ? a = e + i / 2 : a = e + i; + const d = o + l; + let p = 0, g = 0, m = 0; + const f = Math.min(Math.abs(a - d) / 800, 1.2) * M; + return c === "lhs" ? (m = t, p = m + M, g = m - M, u = s + M, `M ${p} ${a} C ${m} ${a} ${m + f} ${d} ${g} ${d} H ${u}`) : (m = t + n, p = m - M, g = m + M, u = s + r - M, `M ${p} ${a} C ${m} ${a} ${m - f} ${d} ${g} ${d} H ${u}`); +} +const me = { + addChild: "插入子节点", + addParent: "插入父节点", + addSibling: "插入同级节点", + removeNode: "删除节点", + focus: "专注", + cancelFocus: "取消专注", + moveUp: "上移", + moveDown: "下移", + link: "连接", + clickTips: "请点击目标节点", + summary: "摘要" +}, ge = { + cn: me, + zh_CN: me, + zh_TW: { + addChild: "插入子節點", + addParent: "插入父節點", + addSibling: "插入同級節點", + removeNode: "刪除節點", + focus: "專注", + cancelFocus: "取消專注", + moveUp: "上移", + moveDown: "下移", + link: "連接", + clickTips: "請點擊目標節點", + summary: "摘要" + }, + en: { + addChild: "Add child", + addParent: "Add parent", + addSibling: "Add sibling", + removeNode: "Remove node", + focus: "Focus Mode", + cancelFocus: "Cancel Focus Mode", + moveUp: "Move up", + moveDown: "Move down", + link: "Link", + clickTips: "Please click the target node", + summary: "Summary" + }, + ru: { + addChild: "Добавить дочерний элемент", + addParent: "Добавить родительский элемент", + addSibling: "Добавить на этом уровне", + removeNode: "Удалить узел", + focus: "Режим фокусировки", + cancelFocus: "Отменить режим фокусировки", + moveUp: "Поднять выше", + moveDown: "Опустить ниже", + link: "Ссылка", + clickTips: "Пожалуйста, нажмите на целевой узел", + summary: "Описание" + }, + ja: { + addChild: "子ノードを追加する", + addParent: "親ノードを追加します", + addSibling: "兄弟ノードを追加する", + removeNode: "ノードを削除", + focus: "集中", + cancelFocus: "集中解除", + moveUp: "上へ移動", + moveDown: "下へ移動", + link: "コネクト", + clickTips: "ターゲットノードをクリックしてください", + summary: "概要" + }, + pt: { + addChild: "Adicionar item filho", + addParent: "Adicionar item pai", + addSibling: "Adicionar item irmao", + removeNode: "Remover item", + focus: "Modo Foco", + cancelFocus: "Cancelar Modo Foco", + moveUp: "Mover para cima", + moveDown: "Mover para baixo", + link: "Link", + clickTips: "Favor clicar no item alvo", + summary: "Resumo" + } +}; +function Et(e, t) { + const n = (b) => { + const y = document.createElement("div"); + return y.innerText = b, y.className = "tips", y; + }, i = (b, y, C) => { + const _ = document.createElement("li"); + return _.id = b, _.innerHTML = `${ee(y)}${ee(C)}`, _; + }, o = ge[e.locale] ? e.locale : "en", s = ge[o], r = i("cm-add_child", s.addChild, "tab"), l = i("cm-add_parent", s.addParent, ""), c = i("cm-add_sibling", s.addSibling, "enter"), h = i("cm-remove_child", s.removeNode, "delete"), a = i("cm-fucus", s.focus, ""), u = i("cm-unfucus", s.cancelFocus, ""), d = i("cm-up", s.moveUp, "PgUp"), p = i("cm-down", s.moveDown, "Pgdn"), g = i("cm-down", s.link, ""), m = i("cm-down", s.summary, ""), f = document.createElement("ul"); + if (f.className = "menu-list", f.appendChild(r), f.appendChild(l), f.appendChild(c), f.appendChild(h), (!t || t.focus) && (f.appendChild(a), f.appendChild(u)), f.appendChild(d), f.appendChild(p), f.appendChild(m), (!t || t.link) && f.appendChild(g), t && t.extend) + for (let b = 0; b < t.extend.length; b++) { + const y = t.extend[b], C = i(y.name, y.name, y.key || ""); + f.appendChild(C), C.onclick = (_) => { + y.onclick(_); + }; + } + const v = document.createElement("div"); + v.className = "context-menu", v.appendChild(f), v.hidden = !0, e.container.append(v); + let x = !0; + e.container.oncontextmenu = function(b) { + if (b.preventDefault(), !e.editable) + return; + const y = b.target; + if (y.tagName === "ME-TPC") { + y.parentElement.tagName === "ME-ROOT" ? x = !0 : x = !1, x ? (a.className = "disabled", d.className = "disabled", p.className = "disabled", l.className = "disabled", c.className = "disabled", h.className = "disabled") : (a.className = "", d.className = "", p.className = "", l.className = "", c.className = "", h.className = ""), e.currentNodes || e.selectNode(y), v.hidden = !1; + const C = f.offsetHeight, _ = f.offsetWidth; + C + b.clientY > window.innerHeight ? (f.style.top = "", f.style.bottom = "0px") : (f.style.bottom = "", f.style.top = b.clientY + 15 + "px"), _ + b.clientX > window.innerWidth ? (f.style.left = "", f.style.right = "0px") : (f.style.right = "", f.style.left = b.clientX + 10 + "px"); + } + }, v.onclick = (b) => { + b.target === v && (v.hidden = !0); + }, r.onclick = () => { + e.addChild(), v.hidden = !0; + }, l.onclick = () => { + e.insertParent(), v.hidden = !0; + }, c.onclick = () => { + x || (e.insertSibling(), v.hidden = !0); + }, h.onclick = () => { + x || (e.removeNode(), v.hidden = !0); + }, a.onclick = () => { + x || (e.focusNode(e.currentNode), v.hidden = !0); + }, u.onclick = () => { + e.cancelFocus(), v.hidden = !0; + }, d.onclick = () => { + x || (e.moveUpNode(), v.hidden = !0); + }, p.onclick = () => { + x || (e.moveDownNode(), v.hidden = !0); + }, g.onclick = () => { + v.hidden = !0; + const b = e.currentNode, y = n(s.clickTips); + e.container.appendChild(y), e.map.addEventListener( + "click", + (C) => { + C.preventDefault(), y.remove(); + const _ = C.target; + _.parentElement.tagName === "ME-PARENT" || _.parentElement.tagName === "ME-ROOT" ? e.createLink(b, _) : console.log("link cancel"); + }, + { + once: !0 + } + ); + }, m.onclick = () => { + v.hidden = !0, e.createSummary(), e.unselectNodes(); + }; +} +const Nt = (e) => { + const t = e.map.querySelectorAll(".lhs>me-wrapper>me-parent>me-tpc"); + e.selectNode(t[Math.ceil(t.length / 2) - 1]); +}, Ct = (e) => { + const t = e.map.querySelectorAll(".rhs>me-wrapper>me-parent>me-tpc"); + e.selectNode(t[Math.ceil(t.length / 2) - 1]); +}, ve = (e) => { + e.selectNode(e.map.querySelector("me-root>me-tpc")); +}; +function _t(e) { + const t = { + 13: (n) => { + n.shiftKey ? e.insertBefore() : e.insertSibling(); + }, + 9: () => { + e.addChild(); + }, + 112: () => { + e.toCenter(); + }, + 113: () => { + e.beginEdit(); + }, + 38: (n) => { + if (n.altKey) + e.moveUpNode(); + else { + if (n.metaKey || n.ctrlKey) + return e.initSide(); + e.selectPrevSibling(); + } + }, + 40: (n) => { + n.altKey ? e.moveDownNode() : e.selectNextSibling(); + }, + 37: (n) => { + var s; + if (n.metaKey || n.ctrlKey) + return e.initLeft(); + if (!e.currentNode) + return; + const i = e.currentNode.nodeObj, o = e.currentNode.offsetParent.offsetParent.parentElement; + e.currentNode.nodeObj.root ? Nt(e) : o.className === "rhs" ? (s = i.parent) != null && s.root ? ve(e) : e.selectParent() : o.className === "lhs" && e.selectFirstChild(); + }, + 39: (n) => { + var s; + if (n.metaKey || n.ctrlKey) + return e.initRight(); + if (!e.currentNode) + return; + const i = e.currentNode.nodeObj, o = e.currentNode.offsetParent.offsetParent.parentElement; + i.root ? Ct(e) : o.className === "lhs" ? (s = i.parent) != null && s.root ? ve(e) : e.selectParent() : o.className === "rhs" && e.selectFirstChild(); + }, + 33() { + e.moveUpNode(); + }, + 34() { + e.moveDownNode(); + }, + 67: (n) => { + (n.metaKey || n.ctrlKey) && (e.waitCopy = e.currentNode); + }, + 86: (n) => { + !e.waitCopy || !e.currentNode || (n.metaKey || n.ctrlKey) && (e.copyNode(e.waitCopy, e.currentNode), e.waitCopy = null); + }, + // ctrl + + 187: (n) => { + if (n.metaKey || n.ctrlKey) { + if (e.scaleVal > 1.6) + return; + e.scale(e.scaleVal += 0.2); + } + }, + // ctrl - + 189: (n) => { + if (n.metaKey || n.ctrlKey) { + if (e.scaleVal < 0.6) + return; + e.scale(e.scaleVal -= 0.2); + } + }, + // ctrl 0 + 48: (n) => { + (n.metaKey || n.ctrlKey) && e.scale(1); + } + }; + e.map.onkeydown = (n) => { + if (n.preventDefault(), !!e.editable && n.target === n.currentTarget) + if (n.keyCode === 8 || n.keyCode === 46) + e.currentLink ? e.removeLink() : e.currentSummary ? e.removeSummary(e.currentSummary.summaryObj.id) : e.removeNode(); + else { + const i = t[n.keyCode]; + i && i(n); + } + }; +} +function kt(e, t) { + const n = (d, p) => { + const g = document.createElement("div"); + return g.id = d, g.innerHTML = ``, g; + }, i = n("cm-add_child", "zijiedian"), o = n("cm-add_sibling", "tongjijiedian-"), s = n("cm-remove_child", "shanchu2"), r = n("cm-up", "rising"), l = n("cm-down", "falling"), c = n("cm-edit", "edit"), h = document.createElement("ul"); + if (h.className = "menu-list", t && t.extend) + for (let d = 0; d < t.extend.length; d++) { + const p = t.extend[d], g = n(p.name, p.name); + h.appendChild(g), g.onclick = (m) => { + p.onclick(m); + }; + } + const a = document.createElement("mmenu"); + a.className = "mobile-menu", a.appendChild(i), a.appendChild(o), a.appendChild(s), a.appendChild(r), a.appendChild(l), a.appendChild(c), a.hidden = !0, e.container.append(a); + let u = !0; + e.bus.addListener("unselectNode", function() { + a.hidden = !0; + }), e.bus.addListener("selectNode", function(d) { + a.hidden = !1, d.root ? u = !0 : u = !1; + }), a.onclick = (d) => { + d.target === a && (a.hidden = !0); + }, i.onclick = () => { + e.addChild(); + }, o.onclick = () => { + u || e.insertSibling(); + }, s.onclick = () => { + u || e.removeNode(); + }, r.onclick = (d) => { + u || e.moveUpNode(); + }, l.onclick = (d) => { + u || e.moveDownNode(); + }, c.onclick = (d) => { + e.beginEdit(); + }; +} +const ce = document, St = function(e, t) { + if (!t) + return ae(e), e; + const n = e.getElementsByClassName("insert-preview"), i = `insert-preview ${t} show`; + if (n.length > 0) + n[0].className = i; + else { + const o = ce.createElement("div"); + o.className = i, e.appendChild(o); + } + return e; +}, ae = function(e) { + if (!e) + return; + const t = e.getElementsByClassName("insert-preview"); + for (const n of t || []) + n.remove(); +}, be = function(e, t) { + const n = t.parentElement.parentElement.contains(e); + return e && e.tagName === "ME-TPC" && e !== t && !n && e.nodeObj.root !== !0; +}, Lt = function(e) { + const t = document.createElement("div"); + return t.className = "mind-elixir-ghost", e.map.appendChild(t), t; +}; +function Mt(e) { + let t = null, n = null, i = null; + const o = Lt(e), s = 12; + e.map.addEventListener("dragstart", (r) => { + var c; + const l = r.target; + if ((l == null ? void 0 : l.tagName) !== "ME-TPC") { + r.preventDefault(); + return; + } + t = l, t.parentElement.parentElement.style.opacity = "0.5", o.innerHTML = t.innerHTML, (c = r.dataTransfer) == null || c.setDragImage(o, 0, 0), D.clear(); + }), e.map.addEventListener("dragend", async (r) => { + if (!t) + return; + t.parentElement.parentElement.style.opacity = "1"; + const l = r.target; + if (l.style.opacity = "", !i) + return; + ae(i); + const c = t.nodeObj; + switch (n) { + case "before": + e.moveNodeBefore(t, i), e.selectNode(E(c.id)); + break; + case "after": + e.moveNodeAfter(t, i), e.selectNode(E(c.id)); + break; + case "in": + e.moveNode(t, i); + break; + } + t = null; + }), e.map.addEventListener( + "dragover", + Ke(function(r) { + if (!t) + return; + ae(i); + const l = ce.elementFromPoint(r.clientX, r.clientY - s); + if (be(l, t)) { + i = l; + const c = l.getBoundingClientRect().y; + r.clientY > c + l.clientHeight ? n = "after" : r.clientY > c + l.clientHeight / 2 && (n = "in"); + } else { + const c = ce.elementFromPoint(r.clientX, r.clientY + s); + if (be(c, t)) { + i = c; + const h = c.getBoundingClientRect().y; + r.clientY < h ? n = "before" : r.clientY < h + c.clientHeight / 2 && (n = "in"); + } else + n = i = null; + } + i && St(i, n); + }, 200) + ); +} +function Tt(e) { + let t = [], n = -1, i = e.getData(); + e.bus.addListener("operation", (o) => { + if (o.name === "beginEdit") + return; + t = t.slice(0, n + 1); + const s = e.getData(); + t.push({ prev: i, currentNodeId: o.obj.id, next: s }), i = s, n = t.length - 1, console.log("operation", o.obj.id, t); + }), e.undo = function() { + if (n > -1) { + const o = t[n]; + i = o.prev, e.refresh(o.prev), e.selectNode(E(o.currentNodeId)), n--, console.log("current", i); + } + }, e.redo = function() { + if (n < t.length - 1) { + n++; + const o = t[n]; + i = o.next, e.refresh(o.next), e.selectNode(E(o.currentNodeId)); + } + }, e.map.addEventListener("keydown", (o) => { + (o.metaKey || o.ctrlKey) && o.shiftKey && o.key === "Z" ? e.redo() : (o.metaKey || o.ctrlKey) && o.key === "z" && e.undo(); + }); +} +const B = (e, t) => { + const n = document.createElement("span"); + return n.id = e, n.innerHTML = ``, n; +}; +function $t(e) { + const t = document.createElement("div"), n = B("fullscreen", "full"), i = B("toCenter", "living"), o = B("zoomout", "move"), s = B("zoomin", "add"), r = document.createElement("span"); + return r.innerText = "100%", t.appendChild(n), t.appendChild(i), t.appendChild(o), t.appendChild(s), t.className = "mind-elixir-toolbar rb", n.onclick = () => { + e.container.requestFullscreen(); + }, i.onclick = () => { + e.toCenter(); + }, o.onclick = () => { + e.scaleVal < 0.6 || e.scale(e.scaleVal -= 0.2); + }, s.onclick = () => { + e.scaleVal > 1.6 || e.scale(e.scaleVal += 0.2); + }, t; +} +function Dt(e) { + const t = document.createElement("div"), n = B("tbltl", "left"), i = B("tbltr", "right"), o = B("tblts", "side"); + return t.appendChild(n), t.appendChild(i), t.appendChild(o), t.className = "mind-elixir-toolbar lt", n.onclick = () => { + e.initLeft(); + }, i.onclick = () => { + e.initRight(); + }, o.onclick = () => { + e.initSide(); + }, t; +} +function Ot(e) { + e.container.append($t(e)), e.container.append(Dt(e)); +} +/*! @viselect/vanilla v3.3.1 MIT | https://github.com/Simonwep/selection/tree/master/packages/vanilla */ +var At = Object.defineProperty, Pt = (e, t, n) => t in e ? At(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n, w = (e, t, n) => (Pt(e, typeof t != "symbol" ? t + "" : t, n), n); +class jt { + constructor() { + w(this, "_listeners", /* @__PURE__ */ new Map()), w(this, "on", this.addEventListener), w(this, "off", this.removeEventListener), w(this, "emit", this.dispatchEvent); + } + addEventListener(t, n) { + const i = this._listeners.get(t) ?? /* @__PURE__ */ new Set(); + return this._listeners.set(t, i), i.add(n), this; + } + removeEventListener(t, n) { + var i; + return (i = this._listeners.get(t)) == null || i.delete(n), this; + } + dispatchEvent(t, ...n) { + let i = !0; + for (const o of this._listeners.get(t) ?? []) + i = o(...n) !== !1 && i; + return i; + } + unbindAllListeners() { + this._listeners.clear(); + } +} +const ye = (e, t = "px") => typeof e == "number" ? e + t : e; +function O({ style: e }, t, n) { + if (typeof t == "object") + for (const [i, o] of Object.entries(t)) + o !== void 0 && (e[i] = ye(o)); + else + n !== void 0 && (e[t] = ye(n)); +} +function Be(e) { + return (t, n, i, o = {}) => { + t instanceof HTMLCollection || t instanceof NodeList ? t = Array.from(t) : Array.isArray(t) || (t = [t]), Array.isArray(n) || (n = [n]); + for (const s of t) + for (const r of n) + s[e](r, i, { capture: !1, ...o }); + return [t, n, i, o]; + }; +} +const q = Be("addEventListener"), A = Be("removeEventListener"), Q = (e) => { + var t; + const { clientX: n, clientY: i, target: o } = ((t = e.touches) == null ? void 0 : t[0]) ?? e; + return { x: n, y: i, target: o }; +}; +function xe(e, t, n = "touch") { + switch (n) { + case "center": { + const i = t.left + t.width / 2, o = t.top + t.height / 2; + return i >= e.left && i <= e.right && o >= e.top && o <= e.bottom; + } + case "cover": + return t.left >= e.left && t.top >= e.top && t.right <= e.right && t.bottom <= e.bottom; + case "touch": + return e.right >= t.left && e.left <= t.right && e.bottom >= t.top && e.top <= t.bottom; + } +} +function F(e, t = document) { + const n = Array.isArray(e) ? e : [e]; + let i = []; + for (let o = 0, s = n.length; o < s; o++) { + const r = n[o]; + typeof r == "string" ? i = i.concat(Array.from(t.querySelectorAll(r))) : r instanceof Element && i.push(r); + } + return i; +} +const Ht = () => matchMedia("(hover: none), (pointer: coarse)").matches, Bt = () => "safari" in window, zt = (e) => { + let t, n = -1, i = !1; + return { + next(...o) { + t = o, i || (i = !0, n = requestAnimationFrame(() => { + e(...t), i = !1; + })); + }, + cancel() { + cancelAnimationFrame(n), i = !1; + } + }; +}, { abs: j, max: we, min: Ee, ceil: Ne } = Math; +class ze extends jt { + constructor(t) { + var n, i, o, s, r; + super(), w(this, "_options"), w(this, "_selection", { + stored: [], + selected: [], + touched: [], + changed: { + added: [], + // Added elements since last selection + removed: [] + // Removed elements since last selection + } + }), w(this, "_area"), w(this, "_clippingElement"), w(this, "_targetElement"), w(this, "_targetRect"), w(this, "_selectables", []), w(this, "_latestElement"), w(this, "_areaRect", new DOMRect()), w(this, "_areaLocation", { y1: 0, x2: 0, y2: 0, x1: 0 }), w(this, "_singleClick", !0), w(this, "_frame"), w(this, "_scrollAvailable", !0), w(this, "_scrollingActive", !1), w(this, "_scrollSpeed", { x: 0, y: 0 }), w(this, "_scrollDelta", { x: 0, y: 0 }), w(this, "disable", this._bindStartEvents.bind(this, !1)), w(this, "enable", this._bindStartEvents), this._options = { + selectionAreaClass: "selection-area", + selectionContainerClass: void 0, + selectables: [], + document: window.document, + startAreas: ["html"], + boundaries: ["html"], + container: "body", + ...t, + behaviour: { + overlap: "invert", + intersect: "touch", + ...t.behaviour, + startThreshold: (n = t.behaviour) != null && n.startThreshold ? typeof t.behaviour.startThreshold == "number" ? t.behaviour.startThreshold : { x: 10, y: 10, ...t.behaviour.startThreshold } : { x: 10, y: 10 }, + scrolling: { + speedDivider: 10, + manualSpeed: 750, + ...(i = t.behaviour) == null ? void 0 : i.scrolling, + startScrollMargins: { + x: 0, + y: 0, + ...(s = (o = t.behaviour) == null ? void 0 : o.scrolling) == null ? void 0 : s.startScrollMargins + } + } + }, + features: { + range: !0, + touch: !0, + ...t.features, + singleTap: { + allow: !0, + intersect: "native", + ...(r = t.features) == null ? void 0 : r.singleTap + } + } + }; + for (const a of Object.getOwnPropertyNames(Object.getPrototypeOf(this))) + typeof this[a] == "function" && (this[a] = this[a].bind(this)); + const { document: l, selectionAreaClass: c, selectionContainerClass: h } = this._options; + this._area = l.createElement("div"), this._clippingElement = l.createElement("div"), this._clippingElement.appendChild(this._area), this._area.classList.add(c), h && this._clippingElement.classList.add(h), O(this._area, { + willChange: "top, left, bottom, right, width, height", + top: 0, + left: 0, + position: "fixed" + }), O(this._clippingElement, { + overflow: "hidden", + position: "fixed", + transform: "translate3d(0, 0, 0)", + // https://stackoverflow.com/a/38268846 + pointerEvents: "none", + zIndex: "1" + }), this._frame = zt((a) => { + this._recalculateSelectionAreaRect(), this._updateElementSelection(), this._emitEvent("move", a), this._redrawSelectionArea(); + }), this.enable(); + } + _bindStartEvents(t = !0) { + const { document: n, features: i } = this._options, o = t ? q : A; + o(n, "mousedown", this._onTapStart), i.touch && o(n, "touchstart", this._onTapStart, { + passive: !1 + }); + } + _onTapStart(t, n = !1) { + const { x: i, y: o, target: s } = Q(t), { _options: r } = this, { document: l } = this._options, c = s.getBoundingClientRect(), h = F(r.startAreas, r.document), a = F(r.boundaries, r.document); + this._targetElement = a.find( + (p) => xe(p.getBoundingClientRect(), c) + ); + const u = t.composedPath(); + if (!this._targetElement || !h.find((p) => u.includes(p)) || !a.find((p) => u.includes(p)) || !n && this._emitEvent("beforestart", t) === !1) + return; + this._areaLocation = { x1: i, y1: o, x2: 0, y2: 0 }; + const d = l.scrollingElement ?? l.body; + this._scrollDelta = { x: d.scrollLeft, y: d.scrollTop }, this._singleClick = !0, this.clearSelection(!1, !0), q(l, ["touchmove", "mousemove"], this._delayedTapMove, { passive: !1 }), q(l, ["mouseup", "touchcancel", "touchend"], this._onTapStop), q(l, "scroll", this._onScroll); + } + _onSingleTap(t) { + const { singleTap: { intersect: n }, range: i } = this._options.features, o = Q(t); + let s; + if (n === "native") + s = o.target; + else if (n === "touch") { + this.resolveSelectables(); + const { x: l, y: c } = o; + s = this._selectables.find((h) => { + const { right: a, left: u, top: d, bottom: p } = h.getBoundingClientRect(); + return l < a && l > u && c < p && c > d; + }); + } + if (!s) + return; + for (this.resolveSelectables(); !this._selectables.includes(s); ) { + if (!s.parentElement) + return; + s = s.parentElement; + } + const { stored: r } = this._selection; + if (this._emitEvent("start", t), t.shiftKey && i && this._latestElement) { + const l = this._latestElement, [c, h] = l.compareDocumentPosition(s) & 4 ? [s, l] : [l, s], a = [...this._selectables.filter( + (u) => u.compareDocumentPosition(c) & 4 && u.compareDocumentPosition(h) & 2 + ), c, h]; + this.select(a), this._latestElement = l; + } else + r.includes(s) && (r.length === 1 || t.ctrlKey || r.every((l) => this._selection.stored.includes(l))) ? this.deselect(s) : (this.select(s), this._latestElement = s); + this._emitEvent("stop", t); + } + _delayedTapMove(t) { + const { container: n, document: i, behaviour: { startThreshold: o } } = this._options, { x1: s, y1: r } = this._areaLocation, { x: l, y: c } = Q(t); + if ( + // Single number for both coordinates + typeof o == "number" && j(l + c - (s + r)) >= o || // Different x and y threshold + typeof o == "object" && j(l - s) >= o.x || j(c - r) >= o.y + ) { + if (A(i, ["mousemove", "touchmove"], this._delayedTapMove, { passive: !1 }), this._emitEvent("beforedrag", t) === !1) { + A(i, ["mouseup", "touchcancel", "touchend"], this._onTapStop); + return; + } + q(i, ["mousemove", "touchmove"], this._onTapMove, { passive: !1 }), O(this._area, "display", "block"), F(n, i)[0].appendChild(this._clippingElement), this.resolveSelectables(), this._singleClick = !1, this._targetRect = this._targetElement.getBoundingClientRect(), this._scrollAvailable = this._targetElement.scrollHeight !== this._targetElement.clientHeight || this._targetElement.scrollWidth !== this._targetElement.clientWidth, this._scrollAvailable && (q(i, "wheel", this._manualScroll, { passive: !1 }), this._selectables = this._selectables.filter((h) => this._targetElement.contains(h))), this._setupSelectionArea(), this._emitEvent("start", t), this._onTapMove(t); + } + this._handleMoveEvent(t); + } + _setupSelectionArea() { + const { _clippingElement: t, _targetElement: n, _area: i } = this, o = this._targetRect = n.getBoundingClientRect(); + this._scrollAvailable ? (O(t, { + top: o.top, + left: o.left, + width: o.width, + height: o.height + }), O(i, { + marginTop: -o.top, + marginLeft: -o.left + })) : (O(t, { + top: 0, + left: 0, + width: "100%", + height: "100%" + }), O(i, { + marginTop: 0, + marginLeft: 0 + })); + } + _onTapMove(t) { + const { x: n, y: i } = Q(t), { _scrollSpeed: o, _areaLocation: s, _options: r, _frame: l } = this, { speedDivider: c } = r.behaviour.scrolling, h = this._targetElement; + if (s.x2 = n, s.y2 = i, this._scrollAvailable && !this._scrollingActive && (o.y || o.x)) { + this._scrollingActive = !0; + const a = () => { + if (!o.x && !o.y) { + this._scrollingActive = !1; + return; + } + const { scrollTop: u, scrollLeft: d } = h; + o.y && (h.scrollTop += Ne(o.y / c), s.y1 -= h.scrollTop - u), o.x && (h.scrollLeft += Ne(o.x / c), s.x1 -= h.scrollLeft - d), l.next(t), requestAnimationFrame(a); + }; + requestAnimationFrame(a); + } else + l.next(t); + this._handleMoveEvent(t); + } + _handleMoveEvent(t) { + const { features: n } = this._options; + (n.touch && Ht() || this._scrollAvailable && Bt()) && t.preventDefault(); + } + _onScroll() { + const { _scrollDelta: t, _options: { document: n } } = this, { scrollTop: i, scrollLeft: o } = n.scrollingElement ?? n.body; + this._areaLocation.x1 += t.x - o, this._areaLocation.y1 += t.y - i, t.x = o, t.y = i, this._setupSelectionArea(), this._frame.next(null); + } + _manualScroll(t) { + const { manualSpeed: n } = this._options.behaviour.scrolling, i = t.deltaY ? t.deltaY > 0 ? 1 : -1 : 0, o = t.deltaX ? t.deltaX > 0 ? 1 : -1 : 0; + this._scrollSpeed.y += i * n, this._scrollSpeed.x += o * n, this._onTapMove(t), t.preventDefault(); + } + _recalculateSelectionAreaRect() { + const { _scrollSpeed: t, _areaLocation: n, _areaRect: i, _targetElement: o, _options: s } = this, { scrollTop: r, scrollHeight: l, clientHeight: c, scrollLeft: h, scrollWidth: a, clientWidth: u } = o, d = this._targetRect, { x1: p, y1: g } = n; + let { x2: m, y2: f } = n; + const { behaviour: { scrolling: { startScrollMargins: v } } } = s; + m < d.left + v.x ? (t.x = h ? -j(d.left - m + v.x) : 0, m = m < d.left ? d.left : m) : m > d.right - v.x ? (t.x = a - h - u ? j(d.left + d.width - m - v.x) : 0, m = m > d.right ? d.right : m) : t.x = 0, f < d.top + v.y ? (t.y = r ? -j(d.top - f + v.y) : 0, f = f < d.top ? d.top : f) : f > d.bottom - v.y ? (t.y = l - r - c ? j(d.top + d.height - f - v.y) : 0, f = f > d.bottom ? d.bottom : f) : t.y = 0; + const x = Ee(p, m), b = Ee(g, f), y = we(p, m), C = we(g, f); + i.x = x, i.y = b, i.width = y - x, i.height = C - b; + } + _redrawSelectionArea() { + const { x: t, y: n, width: i, height: o } = this._areaRect, { style: s } = this._area; + s.left = `${t}px`, s.top = `${n}px`, s.width = `${i}px`, s.height = `${o}px`; + } + _onTapStop(t, n) { + var i; + const { document: o, features: s } = this._options, { _singleClick: r } = this; + A(o, ["mousemove", "touchmove"], this._delayedTapMove), A(o, ["touchmove", "mousemove"], this._onTapMove), A(o, ["mouseup", "touchcancel", "touchend"], this._onTapStop), A(o, "scroll", this._onScroll), this._keepSelection(), t && r && s.singleTap.allow ? this._onSingleTap(t) : !r && !n && (this._updateElementSelection(), this._emitEvent("stop", t)), this._scrollSpeed.x = 0, this._scrollSpeed.y = 0, this._scrollAvailable && A(o, "wheel", this._manualScroll, { passive: !0 }), this._clippingElement.remove(), (i = this._frame) == null || i.cancel(), O(this._area, "display", "none"); + } + _updateElementSelection() { + const { _selectables: t, _options: n, _selection: i, _areaRect: o } = this, { stored: s, selected: r, touched: l } = i, { intersect: c, overlap: h } = n.behaviour, a = h === "invert", u = [], d = [], p = []; + for (let m = 0; m < t.length; m++) { + const f = t[m]; + if (xe(o, f.getBoundingClientRect(), c)) { + if (r.includes(f)) + s.includes(f) && !l.includes(f) && l.push(f); + else if (a && s.includes(f)) { + p.push(f); + continue; + } else + d.push(f); + u.push(f); + } + } + a && d.push(...s.filter((m) => !r.includes(m))); + const g = h === "keep"; + for (let m = 0; m < r.length; m++) { + const f = r[m]; + !u.includes(f) && !// Check if user wants to keep previously selected elements, e.g. + // not make them part of the current selection as soon as they're touched. + (g && s.includes(f)) && p.push(f); + } + i.selected = u, i.changed = { added: d, removed: p }, this._latestElement = void 0; + } + _emitEvent(t, n) { + return this.emit(t, { + event: n, + store: this._selection, + selection: this + }); + } + _keepSelection() { + const { _options: t, _selection: n } = this, { selected: i, changed: o, touched: s, stored: r } = n, l = i.filter((c) => !r.includes(c)); + switch (t.behaviour.overlap) { + case "drop": { + n.stored = [ + ...l, + ...r.filter((c) => !s.includes(c)) + // Elements not touched + ]; + break; + } + case "invert": { + n.stored = [ + ...l, + ...r.filter((c) => !o.removed.includes(c)) + // Elements not removed from selection + ]; + break; + } + case "keep": { + n.stored = [ + ...r, + ...i.filter((c) => !r.includes(c)) + // Newly added + ]; + break; + } + } + } + /** + * Manually triggers the start of a selection + * @param evt A MouseEvent / TouchEvent -like object + * @param silent If beforestart should be fired, + */ + trigger(t, n = !0) { + this._onTapStart(t, n); + } + /** + * Can be used if during a selection elements have been added. + * Will update everything which can be selected. + */ + resolveSelectables() { + this._selectables = F(this._options.selectables, this._options.document); + } + /** + * Same as deselect, but for all elements currently selected. + * @param includeStored If the store should also get cleared + * @param quiet If move / stop events should be fired + */ + clearSelection(t = !0, n = !1) { + const { selected: i, stored: o, changed: s } = this._selection; + s.added = [], s.removed.push( + ...i, + ...t ? o : [] + ), n || (this._emitEvent("move", null), this._emitEvent("stop", null)), this._selection = { + stored: t ? [] : o, + selected: [], + touched: [], + changed: { added: [], removed: [] } + }; + } + /** + * @returns {Array} Selected elements + */ + getSelection() { + return this._selection.stored; + } + /** + * @returns {HTMLElement} The selection area element + */ + getSelectionArea() { + return this._area; + } + /** + * Cancel the current selection process. + * @param keepEvent {boolean} true to fire a stop event after cancel. + */ + cancel(t = !1) { + this._onTapStop(null, !t); + } + /** + * Unbinds all events and removes the area-element. + */ + destroy() { + this.cancel(), this.disable(), this._clippingElement.remove(), super.unbindAllListeners(); + } + /** + * Adds elements to the selection + * @param query - CSS Query, can be an array of queries + * @param quiet - If this should not trigger the move event + */ + select(t, n = !1) { + const { changed: i, selected: o, stored: s } = this._selection, r = F(t, this._options.document).filter( + (l) => !o.includes(l) && !s.includes(l) + ); + return s.push(...r), o.push(...r), i.added.push(...r), i.removed = [], this._latestElement = void 0, n || (this._emitEvent("move", null), this._emitEvent("stop", null)), r; + } + /** + * Removes a particular element from the selection. + * @param query - CSS Query, can be an array of queries + * @param quiet - If this should not trigger the move event + */ + deselect(t, n = !1) { + const { selected: i, stored: o, changed: s } = this._selection, r = F(t, this._options.document).filter( + (l) => i.includes(l) || o.includes(l) + ); + r.length && (this._selection.stored = o.filter((l) => !r.includes(l)), this._selection.selected = i.filter((l) => !r.includes(l)), this._selection.changed.added = [], this._selection.changed.removed.push( + ...r.filter((l) => !s.removed.includes(l)) + ), this._latestElement = void 0, n || (this._emitEvent("move", null), this._emitEvent("stop", null))); + } +} +w(ze, "version", "3.3.1"); +function Rt(e) { + const t = new ze({ + selectables: [".map-container me-tpc"], + boundaries: [e.container], + container: e.container, + behaviour: { + // Scroll configuration. + scrolling: { + // On scrollable areas the number on px per frame is devided by this amount. + // Default is 10 to provide a enjoyable scroll experience. + speedDivider: 10, + // Browsers handle mouse-wheel events differently, this number will be used as + // numerator to calculate the mount of px while scrolling manually: manualScrollSpeed / scrollSpeedDivider. + manualSpeed: 750, + // This property defines the virtual inset margins from the borders of the container + // component that, when crossed by the mouse/touch, trigger the scrolling. Useful for + // fullscreen containers. + startScrollMargins: { x: 10, y: 10 } + } + } + }).on("beforestart", ({ event: n }) => !(n.button !== 0 || n.target.tagName === "ME-TPC" || n.target.id === "input-box" || n.target.className === "circle")).on("start", ({ event: n }) => { + !n.ctrlKey && !n.metaKey && (e.unselectNode(), e.unselectNodes(), e.unselectSummary(), e.unselectLink(), t.clearSelection(!0, !0)); + }).on( + "move", + ({ + store: { + changed: { added: n, removed: i } + } + }) => { + D.moved = !0; + for (const o of n) + o.classList.add("selected"); + for (const o of i) + o.classList.remove("selected"); + } + ).on("stop", ({ store: { stored: n } }) => { + console.log(n, "stored"), e.selectNodes(n); + }); +} +const qt = function(e, t = !0) { + this.theme = e; + const n = this.theme.cssVar, i = Object.keys(n); + for (let o = 0; o < i.length; o++) { + const s = i[o]; + this.mindElixirBox.style.setProperty(s, n[s]); + } + t && this.refresh(); +}; +function Re(e) { + return { + nodeData: e.isFocusMode ? e.nodeDataBackup : e.nodeData, + linkData: e.linkData, + summaries: e.summaries, + direction: e.direction, + theme: e.theme + }; +} +const Ft = function(e, t, n) { + if (e) { + if (console.time("selectNode"), typeof e == "string") { + const i = E(e); + return i ? this.selectNode(i) : void 0; + } + this.currentNode && (this.currentNode.className = ""), e.className = "selected", e.scrollIntoView({ block: "nearest", inline: "nearest" }), this.currentNode = e, t ? this.bus.fire("selectNewNode", e.nodeObj) : this.bus.fire("selectNode", e.nodeObj, n), console.timeEnd("selectNode"); + } +}, Vt = function() { + this.currentNode && (this.currentNode.className = ""), this.currentNode = null, this.bus.fire("unselectNode"); +}, Wt = function(e) { + if (e) { + console.time("selectNodes"); + for (const t of e) + t.className = "selected"; + this.currentNodes = e, this.bus.fire( + "selectNodes", + e.map((t) => t.nodeObj) + ), console.timeEnd("selectNodes"); + } +}, Yt = function() { + if (this.currentNodes) + for (const e of this.currentNodes) + e.classList.remove("selected"); + this.currentNodes = null, this.bus.fire("unselectNodes"); +}, It = function() { + if (!this.currentNode || this.currentNode.dataset.nodeid === "meroot") + return !1; + const e = this.currentNode.parentElement.parentElement.nextSibling; + let t; + if (e) + t = e.firstChild.firstChild; + else + return !1; + return this.selectNode(t), !0; +}, Xt = function() { + if (!this.currentNode || this.currentNode.dataset.nodeid === "meroot") + return !1; + const e = this.currentNode.parentElement.parentElement.previousSibling; + let t; + if (e) + t = e.firstChild.firstChild; + else + return !1; + return this.selectNode(t), !0; +}, Kt = function() { + if (!this.currentNode) + return; + const e = this.currentNode.parentElement.nextSibling; + if (e && e.firstChild) { + const t = e.firstChild.firstChild.firstChild; + this.selectNode(t); + } +}, Ut = function() { + if (!this.currentNode || this.currentNode.dataset.nodeid === "meroot") + return; + const e = this.currentNode.parentElement.parentElement.parentElement.previousSibling; + if (e) { + const t = e.firstChild; + this.selectNode(t); + } +}, Gt = function() { + const e = Re(this); + return JSON.stringify(e, (t, n) => { + if (!(t === "parent" && typeof n != "string")) + return n; + }); +}, Jt = function() { + return JSON.parse(this.getDataString()); +}, Qt = function() { + const e = Re(this).nodeData; + let t = "# " + e.topic + ` + +`; + function n(i, o) { + for (let s = 0; s < i.length; s++) + o <= 6 ? t += "".padStart(o, "#") + " " + i[s].topic + ` + +` : t += "".padStart(o - 7, " ") + "- " + i[s].topic + ` +`, i[s].children && n(i[s].children || [], o + 1); + } + return n(e.children || [], 2), t; +}, Zt = function() { + this.editable = !0; +}, en = function() { + this.editable = !1; +}, tn = function(e) { + this.scaleVal = e, this.map.style.transform = "scale(" + e + ")"; +}, nn = function() { + this.container.scrollTo(1e4 - this.container.offsetWidth / 2, 1e4 - this.container.offsetHeight / 2); +}, on = function(e) { + e(this); +}, sn = function(e) { + e.nodeObj.root || (this.tempDirection === null && (this.tempDirection = this.direction), this.isFocusMode || (this.nodeDataBackup = this.nodeData, this.isFocusMode = !0), this.nodeData = e.nodeObj, this.nodeData.root = !0, this.initRight(), this.toCenter()); +}, rn = function() { + this.isFocusMode = !1, this.tempDirection !== null && (delete this.nodeData.root, this.nodeData = this.nodeDataBackup, this.direction = this.tempDirection, this.tempDirection = null, this.refresh(), this.toCenter()); +}, ln = function() { + this.direction = 0, this.refresh(); +}, cn = function() { + this.direction = 1, this.refresh(); +}, an = function() { + this.direction = 2, this.refresh(); +}, dn = function(e) { + this.locale = e, this.refresh(); +}, hn = function(e, t) { + const n = e.nodeObj; + typeof t == "boolean" ? n.expanded = t : n.expanded !== !1 ? n.expanded = !1 : n.expanded = !0, this.layout(), this.linkDiv(), this.bus.fire("expandNode", n); +}, un = function(e) { + e && (e = JSON.parse(JSON.stringify(e)), this.nodeData = e.nodeData, this.linkData = e.linkData || {}), T(this.nodeData), this.layout(), this.linkDiv(); +}, fn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + cancelFocus: rn, + disableEdit: en, + enableEdit: Zt, + expandNode: hn, + focusNode: sn, + getData: Jt, + getDataMd: Qt, + getDataString: Gt, + initLeft: ln, + initRight: cn, + initSide: an, + install: on, + refresh: un, + scale: tn, + selectFirstChild: Kt, + selectNextSibling: It, + selectNode: Ft, + selectNodes: Wt, + selectParent: Ut, + selectPrevSibling: Xt, + setLocale: dn, + toCenter: nn, + unselectNode: Vt, + unselectNodes: Yt +}, Symbol.toStringTag, { value: "Module" })), re = function(e) { + const n = e.parentElement.parentElement.lastElementChild; + (n == null ? void 0 : n.tagName) === "svg" && (n == null || n.remove()); +}, qe = function(e, t) { + var n, i; + if (e === S) + return S; + if (e === H) + return H; + if (e === K) { + const o = ((n = document.querySelector(".lhs")) == null ? void 0 : n.childElementCount) || 0, s = ((i = document.querySelector(".rhs")) == null ? void 0 : i.childElementCount) || 0; + return o <= s ? (t.direction = S, S) : (t.direction = H, H); + } +}, pn = function(e, t) { + console.log(t); + const n = e.nodeObj, i = De(n); + i.style && t.style && (t.style = Object.assign(i.style, t.style)); + const o = Object.assign(n, t); + de(e, o), this.linkDiv(), this.bus.fire("operation", { + name: "reshapeNode", + obj: o, + origin: i + }); +}, mn = function(e, t) { + var h, a, u; + const n = e || this.currentNode; + if (!n) + return; + const i = n.nodeObj; + if (i.root === !0) { + this.addChild(); + return; + } else if (((h = i.parent) == null ? void 0 : h.root) === !0 && ((u = (a = i.parent) == null ? void 0 : a.children) == null ? void 0 : u.length) === 1) { + this.addChild(E(i.parent.id)); + return; + } + const o = t || this.generateNewObj(); + Ze(i, o), T(this.nodeData); + const s = n.parentElement; + console.time("insertSibling_DOM"); + const { grp: r, top: l } = this.createWrapper(o); + s.parentNode.parentNode.insertBefore(r, s.parentNode.nextSibling), this.linkDiv(r.offsetParent), t || this.editTopic(l.firstChild), this.selectNode(l.firstChild, !0), console.timeEnd("insertSibling_DOM"), this.bus.fire("operation", { + name: "insertSibling", + obj: o + }); +}, gn = function(e, t) { + const n = e || this.currentNode; + if (!n) + return; + const i = n.nodeObj; + if (i.root === !0) { + this.addChild(); + return; + } + const o = t || this.generateNewObj(); + et(i, o), T(this.nodeData); + const s = n.parentElement; + console.time("insertSibling_DOM"); + const { grp: r, top: l } = this.createWrapper(o); + s.parentNode.parentNode.insertBefore(r, s.parentNode), this.linkDiv(r.offsetParent), t || this.editTopic(l.firstChild), this.selectNode(l.firstChild, !0), console.timeEnd("insertSibling_DOM"), this.bus.fire("operation", { + name: "insertBefore", + obj: o + }); +}, vn = function(e, t) { + const n = e || this.currentNode; + if (!n) + return; + re(n); + const i = n.nodeObj; + if (i.root === !0) + return; + const o = t || this.generateNewObj(); + tt(i, o), T(this.nodeData); + const s = n.parentElement.parentElement; + console.time("insertParent_DOM"); + const { grp: r, top: l } = this.createWrapper(o, !0); + l.appendChild(se(!0)), s.insertAdjacentElement("afterend", r); + const c = this.createChildren([s]); + l.insertAdjacentElement("afterend", c), this.linkDiv(), t || this.editTopic(l.firstChild), this.selectNode(l.firstChild, !0), console.timeEnd("insertParent_DOM"), this.bus.fire("operation", { + name: "insertParent", + obj: o + }); +}, Fe = function(e, t) { + var l, c; + if (!e) + return null; + const n = e.nodeObj; + n.expanded === !1 && (this.expandNode(e, !0), e = E(n.id)); + const i = t || this.generateNewObj(); + n.children ? n.children.push(i) : n.children = [i], T(this.nodeData); + const o = e.parentElement, { grp: s, top: r } = this.createWrapper(i); + if (o.tagName === "ME-PARENT") { + if (o.children[1]) + o.nextSibling.appendChild(s); + else { + const h = this.createChildren([s]); + o.appendChild(se(!0)), o.insertAdjacentElement("afterend", h); + } + this.linkDiv(s.offsetParent); + } else + o.tagName === "ME-ROOT" && (qe(this.direction, i) === S ? (l = document.querySelector(".lhs")) == null || l.appendChild(s) : (c = document.querySelector(".rhs")) == null || c.appendChild(s), this.linkDiv()); + return { newTop: r, newNodeObj: i }; +}, bn = function(e, t) { + console.time("addChild"); + const n = e || this.currentNode; + if (!n) + return; + const i = Fe.call(this, n, t); + if (!i) + return; + const { newTop: o, newNodeObj: s } = i; + this.bus.fire("operation", { + name: "addChild", + obj: s + }), console.timeEnd("addChild"), t || this.editTopic(o.firstChild), this.selectNode(o.firstChild, !0); +}, yn = function(e, t) { + console.time("copyNode"); + const n = De(e.nodeObj); + Te(n); + const i = Fe.call(this, t, n); + if (!i) + return; + const { newNodeObj: o } = i; + console.timeEnd("copyNode"), this.bus.fire("operation", { + name: "copyNode", + obj: o + }); +}, xn = function(e) { + const t = e || this.currentNode; + if (!t) + return; + const n = t.parentNode.parentNode, i = t.nodeObj; + Je(i), n.parentNode.insertBefore(n, n.previousSibling), this.linkDiv(), this.bus.fire("operation", { + name: "moveUpNode", + obj: i + }); +}, wn = function(e) { + const t = e || this.currentNode; + if (!t) + return; + const n = t.parentNode.parentNode, i = t.nodeObj; + Qe(i), n.nextSibling ? n.nextSibling.insertAdjacentElement("afterend", n) : n.parentNode.prepend(n), this.linkDiv(), this.bus.fire("operation", { + name: "moveDownNode", + obj: i + }); +}, En = function(e) { + var l; + const t = e || this.currentNode; + if (!t) + return; + const n = t.nodeObj; + if (n.root === !0) + throw new Error("Can not remove root node"); + const i = n.parent.children, o = i.findIndex((c) => c === n), s = oe(n), r = t.parentNode; + if (s === 0) { + const c = r.parentNode.parentNode; + c.tagName !== "ME-MAIN" && c.previousSibling.children[1].remove(); + } + if (i.length !== 0) { + const c = i[o] || i[o - 1]; + this.selectNode(E(c.id)); + } else + this.selectNode(E(n.parent.id)); + r.parentNode.remove(), this.linkDiv(), this.bus.fire("operation", { + name: "removeNode", + obj: n, + originIndex: o, + originParentId: (l = n == null ? void 0 : n.parent) == null ? void 0 : l.id + }); +}, Nn = function(e, t) { + var l; + const n = e.nodeObj, i = t.nodeObj, o = (l = n == null ? void 0 : n.parent) == null ? void 0 : l.id; + if (i.expanded === !1 && (this.expandNode(t, !0), e = E(n.id), t = E(i.id)), !Ge(n, i)) { + console.warn("Invalid move"); + return; + } + console.time("moveNode"), nt(n, i), T(this.nodeData); + const s = e.parentElement, r = t.parentElement; + if (r.tagName === "ME-PARENT") + if (re(e), r.children[1]) + r.nextSibling.appendChild(s.parentElement); + else { + const c = this.createChildren([s.parentElement]); + r.appendChild(se(!0)), r.parentElement.insertBefore(c, r.nextSibling); + } + else + r.tagName === "ME-ROOT" && (qe(this.direction, n), r.nextSibling.appendChild(s.parentElement)); + this.linkDiv(), this.bus.fire("operation", { + name: "moveNode", + obj: n, + toObj: i, + originParentId: o + }), console.timeEnd("moveNode"); +}, Cn = function(e, t) { + var h; + const n = e.nodeObj, i = t.nodeObj, o = (h = n.parent) == null ? void 0 : h.id; + it(n, i), T(this.nodeData), re(e); + const r = e.parentElement.parentNode; + t.parentElement.parentNode.insertAdjacentElement("beforebegin", r), this.linkDiv(), this.bus.fire("operation", { + name: "moveNodeBefore", + obj: n, + toObj: i, + originParentId: o + }); +}, _n = function(e, t) { + var h; + const n = e.nodeObj, i = t.nodeObj, o = (h = n.parent) == null ? void 0 : h.id; + ot(n, i), T(this.nodeData), re(e); + const r = e.parentElement.parentElement; + t.parentElement.parentElement.insertAdjacentElement("afterend", r), this.linkDiv(), this.bus.fire("operation", { + name: "moveNodeAfter", + obj: n, + toObj: i, + originParentId: o + }); +}, kn = function(e) { + const t = e || this.currentNode; + t && this.editTopic(t); +}, Sn = function(e, t) { + e.text.textContent = t, e.nodeObj.topic = t, this.linkDiv(); +}, Ve = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addChild: bn, + beginEdit: kn, + copyNode: yn, + insertBefore: gn, + insertParent: vn, + insertSibling: mn, + moveDownNode: wn, + moveNode: Nn, + moveNodeAfter: _n, + moveNodeBefore: Cn, + moveUpNode: xn, + removeNode: En, + reshapeNode: pn, + setNodeTopic: Sn +}, Symbol.toStringTag, { value: "Module" })), Ln = function(e) { + return { + dom: e, + mousedown: !1, + lastX: 0, + lastY: 0, + handleMouseMove(t) { + if (this.mousedown) { + if (!this.lastX) { + this.lastX = t.pageX, this.lastY = t.pageY; + return; + } + const n = this.lastX - t.pageX, i = this.lastY - t.pageY; + this.cb && this.cb(n, i), this.lastX = t.pageX, this.lastY = t.pageY; + } + }, + handleMouseDown(t) { + this.mousedown = !0; + }, + handleClear(t) { + this.clear(); + }, + cb: null, + init(t, n) { + this.cb = n, this.handleClear = this.handleClear.bind(this), this.handleMouseMove = this.handleMouseMove.bind(this), this.handleMouseDown = this.handleMouseDown.bind(this), t.addEventListener("mousemove", this.handleMouseMove), t.addEventListener("mouseleave", this.handleClear), t.addEventListener("mouseup", this.handleClear), this.dom.addEventListener("mousedown", this.handleMouseDown); + }, + destory(t) { + t.removeEventListener("mousemove", this.handleMouseMove), t.removeEventListener("mouseleave", this.handleClear), t.removeEventListener("mouseup", this.handleClear), this.dom.removeEventListener("mousedown", this.handleMouseDown); + }, + clear() { + this.mousedown = !1, this.lastX = 0, this.lastY = 0; + } + }; +}, Ce = { + create: Ln +}; +function ie(e, t, n) { + const { offsetLeft: i, offsetTop: o } = W(e.nodes, t), s = t.offsetWidth, r = t.offsetHeight, l = i + s / 2, c = o + r / 2, h = l + n.x, a = c + n.y; + return { + w: s, + h: r, + cx: l, + cy: c, + ctrlX: h, + ctrlY: a + }; +} +function V(e) { + let t, n; + const i = (e.cy - e.ctrlY) / (e.ctrlX - e.cx); + return i > e.h / e.w || i < -e.h / e.w ? e.cy - e.ctrlY < 0 ? (t = e.cx - e.h / 2 / i, n = e.cy + e.h / 2) : (t = e.cx + e.h / 2 / i, n = e.cy - e.h / 2) : e.cx - e.ctrlX < 0 ? (t = e.cx + e.w / 2, n = e.cy - e.w * i / 2) : (t = e.cx - e.w / 2, n = e.cy + e.w * i / 2), { + x: t, + y: n + }; +} +const Mn = function(e, t, n, i) { + const o = document.createElementNS("http://www.w3.org/2000/svg", "text"); + return N(o, { + "text-anchor": "middle", + x: t + "", + y: n + "", + fill: i || "#666" + }), o.dataset.type = "custom-link", o.innerHTML = e, o; +}, Tn = function(e, t, n, i) { + if (!e || !t) + return; + const o = performance.now(); + this.hideLinkController(); + const s = ie(this, e, n.delta1), r = ie(this, t, n.delta2), { x: l, y: c } = V(s), { ctrlX: h, ctrlY: a } = s, { ctrlX: u, ctrlY: d } = r, { x: p, y: g } = V(r), m = $e(u, d, p, g), f = vt( + `M ${l} ${c} C ${h} ${a} ${u} ${d} ${p} ${g}`, + `M ${m.x1} ${m.y1} L ${p} ${g} L ${m.x2} ${m.y2}` + ), v = l / 8 + h * 3 / 8 + u * 3 / 8 + p / 8, x = c / 8 + a * 3 / 8 + d * 3 / 8 + g / 8, b = Mn(n.label, v, x, this.theme.cssVar["--color"]); + f.appendChild(b), f.linkObj = n, f.dataset.linkid = n.id, this.linkSvgGroup.appendChild(f), i || (this.linkData[n.id] = n, this.currentLink = f, this.showLinkController(n, s, r)); + const y = performance.now(); + console.log(`DrawCustomLink Execution time: ${y - o} ms`); +}, $n = function(e, t) { + const n = { + id: U(), + label: "Custom Link", + from: e.nodeObj.id, + to: t.nodeObj.id, + delta1: { + x: 0, + y: -200 + }, + delta2: { + x: 0, + y: -200 + } + }; + this.drawCustomLink(e, t, n); +}, Dn = function(e) { + let t; + if (e ? t = e : t = this.currentLink, !t) + return; + this.hideLinkController(); + const n = t.linkObj.id; + delete this.linkData[n], t.remove(); +}, On = function(e) { + this.currentLink = e; + const t = e.linkObj, n = E(t.from), i = E(t.to), o = ie(this, n, t.delta1), s = ie(this, i, t.delta2); + this.showLinkController(t, o, s); +}, An = function() { + this.currentLink = null, this.hideLinkController(); +}, Pn = function() { + this.linkController.style.display = "none", this.P2.style.display = "none", this.P3.style.display = "none"; +}, jn = function(e, t, n) { + this.linkController.style.display = "initial", this.P2.style.display = "initial", this.P3.style.display = "initial", this.nodes.appendChild(this.linkController), this.nodes.appendChild(this.P2), this.nodes.appendChild(this.P3); + let { x: i, y: o } = V(t), { ctrlX: s, ctrlY: r } = t, { ctrlX: l, ctrlY: c } = n, { x: h, y: a } = V(n); + this.P2.style.cssText = `top:${r}px;left:${s}px;`, this.P3.style.cssText = `top:${c}px;left:${l}px;`, N(this.line1, { + x1: i + "", + y1: o + "", + x2: s + "", + y2: r + "" + }), N(this.line2, { + x1: l + "", + y1: c + "", + x2: h + "", + y2: a + "" + }), this.helper1 && (this.helper1.destory(this.map), this.helper2.destory(this.map)), this.helper1 = Ce.create(this.P2), this.helper2 = Ce.create(this.P3), this.helper1.init(this.map, (u, d) => { + var f; + s = s - u / this.scaleVal, r = r - d / this.scaleVal; + const p = V({ ...t, ctrlX: s, ctrlY: r }); + i = p.x, o = p.y; + const g = i / 8 + s * 3 / 8 + l * 3 / 8 + h / 8, m = o / 8 + r * 3 / 8 + c * 3 / 8 + a / 8; + this.P2.style.top = r + "px", this.P2.style.left = s + "px", (f = this.currentLink) == null || f.children[0].setAttribute("d", `M ${i} ${o} C ${s} ${r} ${l} ${c} ${h} ${a}`), N(this.currentLink.children[2], { + x: g + "", + y: m + "" + }), N(this.line1, { + x1: i + "", + y1: o + "", + x2: s + "", + y2: r + "" + }), e.delta1.x = s - t.cx, e.delta1.y = r - t.cy; + }), this.helper2.init(this.map, (u, d) => { + var v, x; + l = l - u / this.scaleVal, c = c - d / this.scaleVal; + const p = V({ ...n, ctrlX: l, ctrlY: c }); + h = p.x, a = p.y; + const g = i / 8 + s * 3 / 8 + l * 3 / 8 + h / 8, m = o / 8 + r * 3 / 8 + c * 3 / 8 + a / 8, f = $e(l, c, h, a); + this.P3.style.top = c + "px", this.P3.style.left = l + "px", (v = this.currentLink) == null || v.children[0].setAttribute("d", `M ${i} ${o} C ${s} ${r} ${l} ${c} ${h} ${a}`), (x = this.currentLink) == null || x.children[1].setAttribute("d", `M ${f.x1} ${f.y1} L ${h} ${a} L ${f.x2} ${f.y2}`), N(this.currentLink.children[2], { + x: g + "", + y: m + "" + }), N(this.line2, { + x1: l + "", + y1: c + "", + x2: h + "", + y2: a + "" + }), e.delta2.x = l - n.cx, e.delta2.y = c - n.cy; + }); +}; +function Hn() { + this.linkSvgGroup.innerHTML = ""; + for (const e in this.linkData) { + const t = this.linkData[e]; + this.drawCustomLink(E(t.from), E(t.to), t, !0); + } + this.nodes.appendChild(this.linkSvgGroup); +} +function Bn(e) { + if (console.time("editSummary"), !e) + return; + const t = e.children[2]; + console.log(t, e), Ae(this, t, (n) => { + var s; + const i = e.linkObj, o = ((s = n.textContent) == null ? void 0 : s.trim()) || ""; + o === "" ? i.label = origin : i.label = o, n.remove(), o !== origin && (t.innerHTML = i.label, this.linkDiv()); + }), console.timeEnd("editSummary"); +} +function zn() { + for (const e in this.linkData) { + const t = this.linkData[e]; + (!te(t.from, this.nodeData) || !te(t.to, this.nodeData)) && delete this.linkData[t.id]; + } +} +const Rn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + createLink: $n, + drawCustomLink: Tn, + editCutsomLinkLabel: Bn, + hideLinkController: Pn, + removeLink: Dn, + renderCustomLink: Hn, + selectLink: On, + showLinkController: jn, + tidyCustomLink: zn, + unselectLink: An +}, Symbol.toStringTag, { value: "Module" })), qn = function(e) { + var c, h; + if (e.length === 0) + throw new Error("No selected node."); + if (e.length === 1) { + const a = e[0].nodeObj, u = e[0].nodeObj.parent; + if (!u) + throw new Error("Can not select root node."); + const d = u.children.findIndex((p) => a === p); + return { + parent: u.id, + start: d, + end: d + }; + } + let t = 0; + const n = e.map((a) => { + let u = a.nodeObj; + const d = []; + for (; u.parent; ) { + const p = u.parent, g = p.children, m = g == null ? void 0 : g.indexOf(u); + u = p, d.unshift({ node: u, index: m }); + } + return d.length > t && (t = d.length), d; + }); + let i = 0; + e: + for (; i < t; i++) { + const a = (c = n[0][i]) == null ? void 0 : c.node; + for (let u = 1; u < n.length; u++) + if (((h = n[u][i]) == null ? void 0 : h.node) !== a) + break e; + } + if (!i) + throw new Error("Can not select root node."); + const o = n.map((a) => a[i - 1].index).sort(), s = o[0] || 0, r = o[o.length - 1] || 0, l = n[0][i - 1].node; + if (l.root) + throw new Error("Please select nodes in the same main topic."); + return { + parent: l.id, + start: s, + end: r + }; +}, Fn = function(e) { + const t = document.createElementNS("http://www.w3.org/2000/svg", "g"); + return t.setAttribute("id", e), t; +}, _e = function(e, t) { + const n = document.createElementNS("http://www.w3.org/2000/svg", "path"); + return N(n, { + d: e, + stroke: t || "#666", + fill: "none", + "stroke-linecap": "round", + "stroke-width": "2" + }), n; +}, ke = function(e, t, n, i, o) { + const s = document.createElementNS("http://www.w3.org/2000/svg", "text"); + return N(s, { + "text-anchor": i, + x: t + "", + y: n + "", + fill: o || "#666" + }), s.innerHTML = e, s; +}, Vn = (e) => E(e).parentElement.parentElement, Wn = function({ parent: e, start: t }) { + var s, r; + const n = E(e), i = n.nodeObj; + let o; + return i.root === !0 ? o = (s = E(i.children[t].id).closest("me-main")) == null ? void 0 : s.className : o = (r = n.closest("me-main")) == null ? void 0 : r.className, o; +}, We = function(e, t) { + var _; + const { id: n, text: i, parent: o, start: s, end: r } = t, l = e.nodes, h = E(o).nodeObj, a = Wn(t); + let u = 1 / 0, d = 0, p = 0, g = 0; + for (let Y = s; Y <= r; Y++) { + const he = (_ = h.children) == null ? void 0 : _[Y]; + if (!he) + return console.warn("Child not found"), e.removeSummary(n), null; + const G = Vn(he.id), { offsetLeft: J, offsetTop: ue } = W(l, G); + Y === s && (p = ue), Y === r && (g = ue + G.offsetHeight), J < u && (u = J), G.offsetWidth + J > d && (d = G.offsetWidth + J); + } + let m, f; + const v = p + 10, x = g + 10, b = (v + x) / 2, y = e.theme.cssVar["--color"]; + a === "lhs" ? (m = _e(`M ${u + 10} ${v} c -5 0 -10 5 -10 10 L ${u} ${x - 10} c 0 5 5 10 10 10 M ${u} ${b} h -10`, y), f = ke(i, u - 20, b + 6, "end", y)) : (m = _e(`M ${d - 10} ${v} c 5 0 10 5 10 10 L ${d} ${x - 10} c 0 5 -5 10 -10 10 M ${d} ${b} h 10`, y), f = ke(i, d + 20, b + 6, "start", y)); + const C = Fn("s-" + n); + return C.appendChild(m), C.appendChild(f), C.summaryObj = t, e.summarySvg.appendChild(C), C; +}, Yn = function() { + let e = []; + this.currentNode ? e = [this.currentNode] : this.currentNodes && (e = this.currentNodes); + const { parent: t, start: n, end: i } = qn(e), o = { id: U(), parent: t, start: n, end: i, text: "summary" }, s = We(this, o); + this.summaries.push(o), this.editSummary(s); +}, In = function(e) { + var n; + const t = this.summaries.findIndex((i) => i.id === e); + t > -1 && (this.summaries.splice(t, 1), (n = document.querySelector("#s-" + e)) == null || n.remove()); +}, Xn = function(e) { + const t = e.children[1].getBBox(), n = 6, i = 3, o = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + N(o, { + x: t.x - n + "", + y: t.y - n + "", + width: t.width + n * 2 + "", + height: t.height + n * 2 + "", + rx: i + "", + stroke: this.theme.cssVar["--selected"] || "#4dc4ff", + "stroke-width": "2", + fill: "none" + }), o.classList.add("selected"), e.appendChild(o), this.currentSummary = e; +}, Kn = function() { + var e, t; + (t = (e = this.currentSummary) == null ? void 0 : e.querySelector("rect")) == null || t.remove(), this.currentSummary = null; +}, Un = function() { + this.summarySvg.innerHTML = "", this.summaries.forEach((e) => { + We(this, e); + }), this.nodes.insertAdjacentElement("beforeend", this.summarySvg); +}, Gn = function(e) { + if (console.time("editSummary"), !e) + return; + const t = e.childNodes[1]; + Ae(this, t, (n) => { + var s; + const i = e.summaryObj, o = ((s = n.textContent) == null ? void 0 : s.trim()) || ""; + o === "" ? i.text = origin : i.text = o, n.remove(), o !== origin && (t.innerHTML = i.text, this.linkDiv(), this.bus.fire("operation", { + name: "finishEditSummary", + obj: i, + origin + })); + }), console.timeEnd("editSummary"); +}, Jn = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + createSummary: Yn, + editSummary: Gn, + removeSummary: In, + renderSummary: Un, + selectSummary: Xn, + unselectSummary: Kn +}, Symbol.toStringTag, { value: "Module" })); +function Qn(e, t) { + const n = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + return N(n, { + version: "1.1", + xmlns: "http://www.w3.org/2000/svg", + height: e, + width: t + }), n; +} +function Zn(e, t) { + return (parseInt(e) - parseInt(t)) / 2; +} +function ei(e, t, n, i) { + const o = document.createElementNS("http://www.w3.org/2000/svg", "g"); + let s = ""; + return e.text ? s = e.text.textContent : s = e.childNodes[0].textContent, s.split(` +`).forEach((l, c) => { + const h = document.createElementNS("http://www.w3.org/2000/svg", "text"); + N(h, { + x: n + parseInt(t.paddingLeft) + "", + y: i + parseInt(t.paddingTop) + Zn(t.lineHeight, t.fontSize) * (c + 1) + parseFloat(t.fontSize) * (c + 1) + "", + "text-anchor": "start", + "font-family": t.fontFamily, + "font-size": `${t.fontSize}`, + "font-weight": `${t.fontWeight}`, + fill: `${t.color}` + }), h.innerHTML = l, o.appendChild(h); + }), o; +} +function ti(e, t, n, i) { + let o = ""; + e.text ? o = e.text.textContent : o = e.childNodes[0].textContent; + const s = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject"); + N(s, { + x: n + parseInt(t.paddingLeft) + "", + y: i + parseInt(t.paddingTop) + "", + width: t.width, + height: t.height + }); + const r = document.createElement("div"); + return N(r, { + xmlns: "http://www.w3.org/1999/xhtml", + style: `font-family: ${t.fontFamily}; font-size: ${t.fontSize}; font-weight: ${t.fontWeight}; color: ${t.color}; white-space: pre-wrap;` + }), r.innerHTML = o, s.appendChild(r), s; +} +function le(e, t, n = !1) { + const i = getComputedStyle(t), { offsetLeft: o, offsetTop: s } = W(e.nodes, t), r = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + N(r, { + x: o + "", + y: s + "", + rx: i.borderRadius, + ry: i.borderRadius, + width: i.width, + height: i.height, + fill: i.backgroundColor, + stroke: i.borderColor, + "stroke-width": i.borderWidth + }); + const l = document.createElementNS("http://www.w3.org/2000/svg", "g"); + l.appendChild(r); + let c; + return n ? c = ti(t, i, o, s) : c = ei(t, i, o, s), l.appendChild(c), l; +} +function ni(e, t) { + const n = getComputedStyle(t), { offsetLeft: i, offsetTop: o } = W(e.nodes, t), s = document.createElementNS("http://www.w3.org/2000/svg", "a"), r = document.createElementNS("http://www.w3.org/2000/svg", "text"); + return N(r, { + x: i + "", + y: o + parseInt(n.fontSize) + "", + "text-anchor": "start", + "font-family": n.fontFamily, + "font-size": `${n.fontSize}`, + "font-weight": `${n.fontWeight}`, + fill: `${n.color}` + }), r.innerHTML = t.textContent, s.appendChild(r), s.setAttribute("href", t.href), s; +} +const Z = 100, ii = '', Ye = (e, t = !1) => { + var u, d, p; + const n = e.nodes, i = n.offsetHeight + Z * 2, o = n.offsetWidth + Z * 2, s = Qn(i + "px", o + "px"), r = document.createElementNS("http://www.w3.org/2000/svg", "svg"), l = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + N(l, { + x: "0", + y: "0", + width: `${o}`, + height: `${i}`, + fill: e.theme.cssVar["--bgcolor"] + }), s.appendChild(l), n.querySelectorAll(".subLines").forEach((g) => { + const m = g.cloneNode(!0), { offsetLeft: f, offsetTop: v } = W(n, g.parentElement); + m.setAttribute("x", `${f}`), m.setAttribute("y", `${v}`), r.appendChild(m); + }); + const c = (u = n.querySelector(".lines")) == null ? void 0 : u.cloneNode(!0); + c && r.appendChild(c); + const h = (d = n.querySelector(".topiclinks")) == null ? void 0 : d.cloneNode(!0); + h && r.appendChild(h); + const a = (p = n.querySelector(".summary")) == null ? void 0 : p.cloneNode(!0); + return a && r.appendChild(a), n.querySelectorAll("me-tpc").forEach((g) => { + r.appendChild(le(e, g, !t)); + }), n.querySelectorAll(".tags > span").forEach((g) => { + r.appendChild(le(e, g)); + }), n.querySelectorAll(".icons > span").forEach((g) => { + r.appendChild(le(e, g)); + }), n.querySelectorAll(".hyper-link").forEach((g) => { + r.appendChild(ni(e, g)); + }), N(r, { + x: Z + "", + y: Z + "", + overflow: "visible" + }), s.appendChild(r), ii + s.outerHTML; +}; +function oi(e) { + return new Promise((t, n) => { + const i = new FileReader(); + i.onload = (o) => { + t(o.target.result); + }, i.onerror = (o) => { + n(o); + }, i.readAsDataURL(e); + }); +} +const si = function(e = !1) { + const t = Ye(this, e); + return new Blob([t], { type: "image/svg+xml" }); +}, ri = async function(e = !1) { + const t = Ye(this, e), n = new Blob([t], { type: "image/svg+xml" }), i = await oi(n); + return new Promise((o, s) => { + const r = new Image(); + r.setAttribute("crossOrigin", "anonymous"), r.onload = () => { + const l = document.createElement("canvas"); + l.width = r.width, l.height = r.height, l.getContext("2d").drawImage(r, 0, 0), l.toBlob(o, "image/png", 1); + }, r.src = i, r.onerror = s; + }); +}, li = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + exportPng: ri, + exportSvg: si +}, Symbol.toStringTag, { value: "Module" })); +function ci(e, t) { + return async function(...n) { + const i = this.before[t]; + i && !await i.apply(this, n) || e.apply(this, n); + }; +} +const Se = Object.keys(Ve), Ie = {}; +for (let e = 0; e < Se.length; e++) { + const t = Se[e]; + Ie[t] = ci(Ve[t], t); +} +const ai = { + getObjById: te, + generateNewObj: Ue, + layout: lt, + linkDiv: bt, + editTopic: pt, + createWrapper: dt, + createParent: ht, + createChildren: ut, + createTopic: ft, + findEle: E, + changeTheme: qt, + ...fn, + ...Ie, + ...Rn, + ...Jn, + ...li, + init(e) { + if (!e || !e.nodeData) + return new Error("MindElixir: `data` is required"); + e.direction !== void 0 && (this.direction = e.direction), this.changeTheme(e.theme || this.theme, !1), this.nodeData = e.nodeData, T(this.nodeData), this.linkData = e.linkData || {}, this.summaries = e.summaries || [], this.tidyCustomLink(), this.toolBar && Ot(this), this.keypress && _t(this), this.editable && Rt(this), Xe() && this.mobileMenu ? kt(this) : this.contextMenu && Et(this, this.contextMenuOption), this.draggable && Mt(this), this.allowUndo && Tt(this), this.toCenter(), this.layout(), this.linkDiv(); + } +}, I = document; +function $({ + el: e, + direction: t, + locale: n, + draggable: i, + editable: o, + contextMenu: s, + contextMenuOption: r, + toolBar: l, + keypress: c, + before: h, + newTopicName: a, + allowUndo: u, + mainLinkStyle: d, + subLinkStyle: p, + overflowHidden: g, + mobileMenu: m, + theme: f +}) { + console.log("ME_version " + $.version, this); + let v = null; + const x = Object.prototype.toString.call(e); + if (x === "[object HTMLDivElement]" ? v = e : x === "[object String]" && (v = document.querySelector(e)), !v) + throw new Error("MindElixir: el is not a valid element"); + v.className += " mind-elixir", v.innerHTML = "", v.style.setProperty("--gap", M + "px"), this.mindElixirBox = v, this.before = h || {}, this.locale = n || "en", this.contextMenuOption = r, this.contextMenu = s === void 0 ? !0 : s, this.toolBar = l === void 0 ? !0 : l, this.keypress = c === void 0 ? !0 : c, this.mobileMenu = m || !1, this.direction = typeof t == "number" ? t : 1, this.draggable = i === void 0 ? !0 : i, this.newTopicName = a || "new node", this.editable = o === void 0 ? !0 : o, this.allowUndo = u === void 0 ? !1 : u, this.currentNode = null, this.currentLink = null, this.scaleVal = 1, this.tempDirection = null, this.mainLinkStyle = d || 0, this.subLinkStyle = p || 0, this.overflowHidden = g || !1, this.bus = rt.create(), this.container = I.createElement("div"), this.container.className = "map-container"; + const b = window.matchMedia("(prefers-color-scheme: dark)"); + this.theme = f || (b.matches ? Me : Le); + const y = I.createElement("div"); + y.className = "map-canvas", this.map = y, this.map.setAttribute("tabindex", "0"), this.container.appendChild(this.map), this.mindElixirBox.appendChild(this.container), this.nodes = I.createElement("me-nodes"), this.nodes.className = "main-node-container", this.lines = X("lines"), this.summarySvg = X("summary"), this.linkController = X("linkcontroller"), this.P2 = I.createElement("div"), this.P3 = I.createElement("div"), this.P2.className = this.P3.className = "circle", this.P2.style.display = this.P3.style.display = "none", this.line1 = pe(), this.line2 = pe(), this.linkController.appendChild(this.line1), this.linkController.appendChild(this.line2), this.linkSvgGroup = X("topiclinks"), this.map.appendChild(this.nodes), this.overflowHidden ? this.container.style.overflow = "hidden" : st(this); +} +$.prototype = ai; +$.LEFT = S; +$.RIGHT = H; +$.SIDE = K; +$.THEME = Le; +$.DARK_THEME = Me; +$.version = "3.2.6"; +$.E = E; +$.new = (e) => ({ + nodeData: { + id: U(), + topic: e || "new topic", + root: !0, + children: [] + }, + linkData: {} +}); +exports.MindElixir = $; diff --git a/src/mindmap-elixir/plugin.info b/src/mindmap-elixir/plugin.info index 5cc2623..0545cb9 100644 --- a/src/mindmap-elixir/plugin.info +++ b/src/mindmap-elixir/plugin.info @@ -4,6 +4,6 @@ "author": "Gk0Wk", "description": "A MindMap plugin TiddlyWiki5, using Elixir", "plugin-type": "plugin", - "version": "0.0.1", + "version": "0.0.2", "list": "readme config" } diff --git a/src/mindmap-elixir/style.css b/src/mindmap-elixir/style.css index baa72df..50e8389 100644 --- a/src/mindmap-elixir/style.css +++ b/src/mindmap-elixir/style.css @@ -11,3 +11,20 @@ .gk0wk-mind-elixir-container .node-menu textarea { color: black !important; } + +.mind-elixir-toolbar.rb { + display: flex; + align-items: center; +} + +.mind-elixir-toolbar.rb span#theme, +.mind-elixir-toolbar.rb span#export, +.mind-elixir-toolbar.rb span#settings { + height: 1em; +} + +.mind-elixir-toolbar.rb span#theme > p, +.mind-elixir-toolbar.rb span#export > p, +.mind-elixir-toolbar.rb span#settings > p { + margin: 0 !important; +} diff --git a/src/mindmap-elixir/widget.ts b/src/mindmap-elixir/widget.ts index 40b9e51..c18c028 100644 --- a/src/mindmap-elixir/widget.ts +++ b/src/mindmap-elixir/widget.ts @@ -65,7 +65,9 @@ if (typeof window !== 'undefined') { data2Xmind = require('@mind-elixir/export-xmind').data2Xmind; // eslint-disable-next-line prefer-destructuring data2Html = require('@mind-elixir/export-html').data2Html; - MindElixir = require('$:/plugins/Gk0Wk/mindmap-elixir/elixir.min.js'); + // eslint-disable-next-line prefer-destructuring + MindElixir = + require('$:/plugins/Gk0Wk/mindmap-elixir/elixir.min.js').MindElixir; (globalThis as any).MindElixir = MindElixir; const { parse, stringify } = opml; @@ -111,13 +113,16 @@ class ElixirWidget extends Widget { private locale_: LocaleType = 'en'; // Other - private optionsButtonText: string = $tw.wiki.getTiddlerText( + private optionsButtonText: string = $tw.wiki.renderTiddler( + 'text/html', '$:/core/images/options-button', )!; - private exportButtonText: string = $tw.wiki.getTiddlerText( + private exportButtonText: string = $tw.wiki.renderTiddler( + 'text/html', '$:/core/images/export-button', )!; - private themeButtonText: string = $tw.wiki.getTiddlerText( + private themeButtonText: string = $tw.wiki.renderTiddler( + 'text/html', '$:/core/images/palette', )!; private saveTiddler!: (reinit?: boolean) => void; @@ -181,16 +186,15 @@ class ElixirWidget extends Widget { } // 加载/创建数据 - let dataAndOptions = { - options: {} as Record, - } as any; - try { - dataAndOptions = JSON.parse( - $tw.wiki.getTiddler(this.stateTiddler)?.fields?.[ - this.stateTiddlerField - ] as any, - ); - } catch {} + const dataAndOptions = $tw.utils.parseJSONSafe<{ + options: Record; + data?: Record; + }>( + $tw.wiki.getTiddler(this.stateTiddler)?.fields?.[ + this.stateTiddlerField + ] as any, + () => ({ options: {} }), + ); try { // Configure @@ -398,7 +402,7 @@ class ElixirWidget extends Widget { const themeIcon = $tw.utils.domMaker('span', { attributes: { - id: 'export', + id: 'theme', }, }); themeIcon.innerHTML = this.themeButtonText; @@ -487,9 +491,13 @@ class ElixirWidget extends Widget { }); } }; - svg.removeAttribute('width'); - svg.removeAttribute('height'); - svg.removeAttribute('class'); + try { + svg.removeAttribute('width'); + svg.removeAttribute('height'); + svg.removeAttribute('class'); + } catch { + // + } svg.classList.add('icon'); svg.ariaHidden = 'true'; } diff --git a/src/notionpage-covericon/body.tid b/src/notionpage-covericon/body.tid index 94dc553..fecf3d2 100755 --- a/src/notionpage-covericon/body.tid +++ b/src/notionpage-covericon/body.tid @@ -36,27 +36,27 @@ list-before: $:/core/ui/ViewTemplate/title
URI:  <$edit-text tiddler=<> field="page-cover" default={{{ [get[page-cover]] }}} placeholder="" focus="true"/> - <$button setTitle=<> setField="page-cover" setTo={{{ [get[page-cover]!is[blank]else] }}}>Set + <$button setTitle=<> setField="page-cover" setTo={{{ [get[page-cover]!is[blank]else] }}} style="color:inherit !important;cursor:pointer;font-weight:800;">Set
Blur:  <$edit-text tiddler=<> field="page-cover#bg-blur" default=<> placeholder="" focus="true"/> - <$button setTitle=<> setField="page-cover#bg-blur" setTo={{{ [get[page-cover#bg-blur]!is[blank]else] }}}>Set + <$button setTitle=<> setField="page-cover#bg-blur" setTo={{{ [get[page-cover#bg-blur]!is[blank]else] }}} style="color:inherit !important;cursor:pointer;font-weight:800;">Set
Size:  <$edit-text tiddler=<> field="page-cover#size" default=<> placeholder="" focus="true"/> - <$button setTitle=<> setField="page-cover#size" setTo={{{ [get[page-cover#size]!is[blank]else] }}}>Set + <$button setTitle=<> setField="page-cover#size" setTo={{{ [get[page-cover#size]!is[blank]else] }}} style="color:inherit !important;cursor:pointer;font-weight:800;">Set
Position:  <$edit-text tiddler=<> field="page-cover#position" default=<> placeholder="" focus="true"/> - <$button setTitle=<> setField="page-cover#position" setTo={{{ [get[page-cover#position]!is[blank]else] }}}>Set + <$button setTitle=<> setField="page-cover#position" setTo={{{ [get[page-cover#position]!is[blank]else] }}} style="color:inherit !important;cursor:pointer;font-weight:800;">Set
Repeat:  <$edit-text tiddler=<> field="page-cover#repeat" default=<> placeholder="" focus="true"/> - <$button setTitle=<> setField="page-cover#repeat" setTo={{{ [get[page-cover#position]!is[blank]else] }}}>Set + <$button setTitle=<> setField="page-cover#repeat" setTo={{{ [get[page-cover#position]!is[blank]else] }}} style="color:inherit !important;cursor:pointer;font-weight:800;">Set
diff --git a/src/notionpage-covericon/plugin.info b/src/notionpage-covericon/plugin.info index 1894dd1..2400626 100755 --- a/src/notionpage-covericon/plugin.info +++ b/src/notionpage-covericon/plugin.info @@ -1,5 +1,5 @@ { - "version": "0.0.12", + "version": "0.0.13", "type": "application/json", "title": "$:/plugins/Gk0Wk/notionpage-covericon", "plugin-type": "plugin", diff --git a/tsconfig.json b/tsconfig.json index 01cacd3..ac340ca 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,6 @@ "types": ["node", "tw5-typed"], "lib": ["DOM", "ESNext"] }, - "include": ["src", "src-tmp/test", "src-tmp/pdf-printer"], + "include": ["src", "src-tmp/test", "src-tmp/pdf-printer", "src/mindmap-elixir/mind-elixir.min.js"], "exclude": ["./**/*.js"] } diff --git a/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json b/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json index cf01ba8..0d5882c 100644 --- a/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json +++ b/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json @@ -1 +1 @@ -{"tiddlers":{"$:/config/TiddlyWiki-CPL/GitHub":{"title":"$:/config/TiddlyWiki-CPL/GitHub","caption":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\"><$list filter=\"[search:title[zh]]\">太微中文社区插件源(~GitHub版)<$list filter=\"[!search:title[zh]]\">TiddlyWiki CPL(~GitHub Host)","tags":["$:/tags/PluginLibrary","$:/tags/PluginLibrary/CPL"],"type":"text/vnd.tiddlywiki","url":"https://tiddly-gittly.github.io/TiddlyWiki-CPL/library/index.html","text":"\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\">\n<$list filter=\"[search:title[zh]]\" variable=\"lang\">\n\n欢迎使用''【太微中文社区插件源】''!\n\n本插件源是由[[太微(TiddlyWiki)中文社区|https://github.com/tiddly-gittly]]维护的、致力于搜集网络上所有与 ~TiddlyWiki5 有关插件的、希望为中国以及全世界的太微用户提供一键安装、更新插件体验的公开插件源。\n\n如果还不了解该如何使用太微和本插件源,欢迎阅读[[中文社区共建的太微(TiddlyWiki)教程|https://tw-cn.netlify.app]]里插件相关的部分。如上提到的插件源和教程皆为开源项目,你可以在 [[GitHub|https://github.com/tiddly-gittly]] 中找到并参与贡献!如果乐意,可以通过QQ群等方式加入我们,详情请见如上提到的中文教程。\n\n要添加这个插件库到你的 Wiki 中,只需鼠标拖动这个链接到你的 Wiki 里即可:<$link to=<>>{{!!caption}}\n\n注意:本插件源版本为 ~GitHub Page 的版本,更新更快,但是可能需要科学上网手段。如果你在国内,而且不清楚什么是“科学上网”,请选用另一个经过 netlify.app 加速的[[版本|$:/config/TiddlyWiki-CPL/Netlify]],虽然更新有一定的延迟,但对国内用户更加友好。\n\n@@color:red;''安装任何插件前,请记得备份你的Wiki,本插件源无法为插件造成的个人损失负责!''@@\n\n\n\n<$list filter=\"[!search:title[zh]]\" variable=\"lang\">\n\nWelcome to the ''[TiddlyWiki Chinese Community Plugin Source]''!\n\nThis plugin source is maintained by the [[TiddlyWiki Chinese Community]] and is dedicated to collecting all TiddlyWiki5 related plugins on the web, hoping to provide a one-click installation and update plugin experience for TiddlyWiki users in China and around the world.\n\nIf you don't know how to use TiddlyWiki and this source, you are welcome to read the plugins related section in the [[TiddlyWiki Tutorials for Chinese Communities|https://tw-cn.netlify.app]]. As mentioned above, both the plugin source and the tutorial are open source projects, you can find them in [[GitHub|https://github.com/tiddly-gittly]] and participate in contributing! If you like, you can join us through QQ groups and other means, see the Chinese tutorials mentioned above for details.\n\nTo add this plugin library to your Wiki, just drag this link with your mouse into your Wiki: <$link to=<>>{{!!caption}}\n\nNote: The source version of this plugin is the ~GitHub Page version, which is faster to update, but may require scientific Internet access. If you are in China and are not sure what GFW is, please use another [[version|$:/config/TiddlyWiki-CPL/Netlify]] that is accelerated by netlify.app, although there is a certain delay in updating, but it is more friendly to domestic users more friendly.\n\n@@color:red;''Please remember to back up your Wiki before installing any plugins, this plugin source cannot be held responsible for personal losses caused by plugins!''@@\n\n\n\n"},"$:/config/TiddlyWiki-CPL/Netlify":{"title":"$:/config/TiddlyWiki-CPL/Netlify","caption":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\"><$list filter=\"[search:title[zh]]\">太微中文社区插件源(大陆加速版)<$list filter=\"[!search:title[zh]]\">TiddlyWiki CPL(Netlify Host)","tags":["$:/tags/PluginLibrary","$:/tags/PluginLibrary/CPL"],"type":"text/vnd.tiddlywiki","url":"https://tw-cpl.netlify.app/library/index.html","text":"\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\">\n<$list filter=\"[search:title[zh]]\" variable=\"lang\">\n\n欢迎使用''【太微中文社区插件源】''!\n\n本插件源是由[[太微(TiddlyWiki)中文社区|https://github.com/tiddly-gittly]]维护的、致力于搜集网络上所有与 ~TiddlyWiki5 有关插件的、希望为中国以及全世界的太微用户提供一键安装、更新插件体验的公开插件源。\n\n如果还不了解该如何使用太微和本插件源,欢迎阅读[[中文社区共建的太微(TiddlyWiki)教程|https://tw-cn.netlify.app]]里插件相关的部分。如上提到的插件源和教程皆为开源项目,你可以在 [[GitHub|https://github.com/tiddly-gittly]] 中找到并参与贡献!如果乐意,可以通过QQ群等方式加入我们,详情请见如上提到的中文教程。\n\n要添加这个插件库到你的 Wiki 中,只需鼠标拖动这个链接到你的 Wiki 里即可:<$link to=<>>{{!!caption}}\n\n注意:本插件源版本为经过 netlify.app 加速的版本,对国内用户更加友好,但是更新有一定的延迟。还提供另一版本,是直接使用 ~GitHub Page 服务器的版本,更新更快,但是可能需要科学上网手段。\n\n@@color:red;''安装任何插件前,请记得备份你的Wiki,本插件源无法为插件造成的个人损失负责!''@@\n\n\n\n<$list filter=\"[!search:title[zh]]\" variable=\"lang\">\n\nWelcome to the ''[TiddlyWiki Chinese Community Plugin Source]''!\n\nThis plugin source is maintained by the [[TiddlyWiki Chinese Community]] and is dedicated to collecting all TiddlyWiki5 related plugins on the web, hoping to provide a one-click installation and update plugin experience for TiddlyWiki users in China and around the world.\n\nIf you don't know how to use TiddlyWiki and this source, you are welcome to read the plugins related section in the [[TiddlyWiki Tutorials for Chinese Communities|https://tw-cn.netlify.app]]. As mentioned above, both the plugin source and the tutorial are open source projects, you can find them in [[GitHub|https://github.com/tiddly-gittly]] and participate in contributing! If you like, you can join us through QQ groups and other means, see the Chinese tutorials mentioned above for details.\n\nTo add this plugin library to your Wiki, just drag this link with your mouse into your Wiki: <$link to=<>>{{!!caption}}\n\nNote: The source version of this plugin is a version accelerated by netlify.app, which is more friendly to China mainland users, but there is a delay in updating. There is also another version that uses the GitHub Page server directly, which is faster to update, but may require technology to overturn the GFW.\n\n@@color:red;''Please remember to back up your Wiki before installing any plugins, this plugin source cannot be held responsible for personal losses caused by plugins!''@@\n\n\n\n"}}} \ No newline at end of file +{"tiddlers":{"$:/config/TiddlyWiki-CPL/GitHub":{"title":"$:/config/TiddlyWiki-CPL/GitHub","caption":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\"><$list filter=\"[search:title[zh]]\">太微中文社区插件源(~GitHub版)<$list filter=\"[!search:title[zh]]\">TiddlyWiki CPL(~GitHub Host)","tags":["$:/tags/PluginLibrary","$:/tags/PluginLibrary/CPL"],"type":"text/vnd.tiddlywiki","url":"https://tiddly-gittly.github.io/TiddlyWiki-CPL/library/index.html","text":"\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\">\n<$list filter=\"[search:title[zh]]\" variable=\"lang\">\n\n欢迎使用''【太微中文社区插件源】''!\n\n本插件源是由[[太微(TiddlyWiki)中文社区|https://github.com/tiddly-gittly]]维护的、致力于搜集网络上所有与 ~TiddlyWiki5 有关插件的、希望为中国以及全世界的太微用户提供一键安装、更新插件体验的公开插件源。\n\n如果还不了解该如何使用太微和本插件源,欢迎阅读[[中文社区共建的太微(TiddlyWiki)教程|https://tw-cn.netlify.app]]里插件相关的部分。如上提到的插件源和教程皆为开源项目,你可以在 [[GitHub|https://github.com/tiddly-gittly]] 中找到并参与贡献!如果乐意,可以通过QQ群等方式加入我们,详情请见如上提到的中文教程。\n\n要添加这个插件库到你的 Wiki 中,只需鼠标拖动这个链接到你的 Wiki 里即可:<$link to=<>>{{!!caption}}\n\n注意:本插件源版本为 ~GitHub Page 的版本,更新更快,但是可能需要科学上网手段。如果你在国内,而且不清楚什么是“科学上网”,请选用另一个经过 netlify.app 加速的[[版本|$:/config/TiddlyWiki-CPL/Netlify]],虽然更新有一定的延迟,但对国内用户更加友好。\n\n@@color:red;''安装任何插件前,请记得备份你的Wiki,本插件源无法为插件造成的个人损失负责!''@@\n\n\n\n<$list filter=\"[!search:title[zh]]\" variable=\"lang\">\n\nWelcome to the ''[TiddlyWiki Chinese Community Plugin Source]''!\n\nThis plugin source is maintained by the [[TiddlyWiki Chinese Community]] and is dedicated to collecting all TiddlyWiki5 related plugins on the web, hoping to provide a one-click installation and update plugin experience for TiddlyWiki users in China and around the world.\n\nIf you don't know how to use TiddlyWiki and this source, you are welcome to read the plugins related section in the [[TiddlyWiki Tutorials for Chinese Communities|https://tw-cn.netlify.app]]. As mentioned above, both the plugin source and the tutorial are open source projects, you can find them in [[GitHub|https://github.com/tiddly-gittly]] and participate in contributing! If you like, you can join us through QQ groups and other means, see the Chinese tutorials mentioned above for details.\n\nTo add this plugin library to your Wiki, just drag this link with your mouse into your Wiki: <$link to=<>>{{!!caption}}\n\nNote: The source version of this plugin is the ~GitHub Page version, which is faster to update, but may require scientific Internet access. If you are in China and are not sure what GFW is, please use another [[version|$:/config/TiddlyWiki-CPL/Netlify]] that is accelerated by netlify.app, although there is a certain delay in updating, but it is more friendly to domestic users more friendly.\n\n@@color:red;''Please remember to back up your Wiki before installing any plugins, this plugin source cannot be held responsible for personal losses caused by plugins!''@@\n\n\n\n"},"$:/config/TiddlyWiki-CPL/Netlify":{"title":"$:/config/TiddlyWiki-CPL/Netlify","caption":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\"><$list filter=\"[search:title[zh]]\">太微中文社区插件源(大陆加速版)<$list filter=\"[!search:title[zh]]\">TiddlyWiki CPL(Netlify Host)","tags":["$:/tags/PluginLibrary","$:/tags/PluginLibrary/CPL"],"type":"text/vnd.tiddlywiki","url":"https://tw-cpl.netlify.app/library/index.html","text":"\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\" variable=\"lang\">\n<$list filter=\"[search:title[zh]]\" variable=\"lang\">\n\n欢迎使用''【太微中文社区插件源】''!\n\n本插件源是由[[太微(TiddlyWiki)中文社区|https://github.com/tiddly-gittly]]维护的、致力于搜集网络上所有与 ~TiddlyWiki5 有关插件的、希望为中国以及全世界的太微用户提供一键安装、更新插件体验的公开插件源。\n\n如果还不了解该如何使用太微和本插件源,欢迎阅读[[中文社区共建的太微(TiddlyWiki)教程|https://tw-cn.netlify.app]]里插件相关的部分。如上提到的插件源和教程皆为开源项目,你可以在 [[GitHub|https://github.com/tiddly-gittly]] 中找到并参与贡献!如果乐意,可以通过QQ群等方式加入我们,详情请见如上提到的中文教程。\n\n要添加这个插件库到你的 Wiki 中,只需鼠标拖动这个链接到你的 Wiki 里即可:<$link to=<>>{{!!caption}}\n\n注意:本插件源版本为经过 netlify.app 加速的版本,对国内用户更加友好,但是更新有一定的延迟。还提供另一版本,是直接使用 ~GitHub Page 服务器的版本,更新更快,但是可能需要科学上网手段。\n\n@@color:red;''安装任何插件前,请记得备份你的Wiki,本插件源无法为插件造成的个人损失负责!''@@\n\n\n\n<$list filter=\"[!search:title[zh]]\" variable=\"lang\">\n\nWelcome to the ''[TiddlyWiki Chinese Community Plugin Source]''!\n\nThis plugin source is maintained by the [[TiddlyWiki Chinese Community]] and is dedicated to collecting all TiddlyWiki5 related plugins on the web, hoping to provide a one-click installation and update plugin experience for TiddlyWiki users in China and around the world.\n\nIf you don't know how to use TiddlyWiki and this source, you are welcome to read the plugins related section in the [[TiddlyWiki Tutorials for Chinese Communities|https://tw-cn.netlify.app]]. As mentioned above, both the plugin source and the tutorial are open source projects, you can find them in [[GitHub|https://github.com/tiddly-gittly]] and participate in contributing! If you like, you can join us through QQ groups and other means, see the Chinese tutorials mentioned above for details.\n\nTo add this plugin library to your Wiki, just drag this link with your mouse into your Wiki: <$link to=<>>{{!!caption}}\n\nNote: The source version of this plugin is a version accelerated by netlify.app, which is more friendly to China mainland users, but there is a delay in updating. There is also another version that uses the GitHub Page server directly, which is faster to update, but may require technology to overturn the GFW.\n\n@@color:red;''Please remember to back up your Wiki before installing any plugins, this plugin source cannot be held responsible for personal losses caused by plugins!''@@\n\n\n\n"},"$:/plugins/Gk0Wk/CPL-Repo/about-banner":{"title":"$:/plugins/Gk0Wk/CPL-Repo/about-banner","tags":[],"type":"text/vnd.tiddlywiki","text":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n
\n
<$text text={{{ [match[yes]then[加入我们, 共建设社区生态!]else[Join us in building a community ecology!]] }}}/>
\n\n
<$text text={{{ [match[yes]then[欢迎任何人在CPL仓库贡献更多插件!]else[Anyone is welcome to contribute more plugins to the CPL repository!]] }}}/>
\n
\n\n"},"$:/plugins/Gk0Wk/CPL-Repo/category-gallery":{"title":"$:/plugins/Gk0Wk/CPL-Repo/category-gallery","caption":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[分类]else[Categories]] }}} />","tags":[],"type":"text/vnd.tiddlywiki","text":"<$macrocall\n\t$name=\"tabs\"\n\tstate=\"$:/temp/CPL-Repo/category-gallery-tab-state\"\n\ttabsList=\"[{$:/temp/CPL-Repo/categories}jsonindexes[]]\"\n\tdefault={{{ [{$:/temp/CPL-Repo/categories}jsonindexes[]first[]] }}}\n\ttemplate=\"$:/plugins/Gk0Wk/CPL-Repo/category-tab-container-template\"\n\tbuttonTemplate=\"$:/plugins/Gk0Wk/CPL-Repo/category-tab-button-template\"\n/>"},"$:/plugins/Gk0Wk/CPL-Repo/category-tab-button-template":{"title":"$:/plugins/Gk0Wk/CPL-Repo/category-tab-button-template","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]] :then[addprefix[$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/]get[text]else[?]] :else[else[Unknown]else[?]] }}} />"},"$:/plugins/Gk0Wk/CPL-Repo/category-tab-container-template":{"title":"$:/plugins/Gk0Wk/CPL-Repo/category-tab-container-template","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-list-item\n\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-size\n\\import $:/plugins/Gk0Wk/CPL-Repo/paged-plugin-list\n\n<]\" field:\"category-gallery\" class1:\"cpl-plugin-info-box\" class2:\"cpl-paged-plugin-list-control\">>\n"},"$:/plugins/Gk0Wk/CPL-Repo/config/current-repo":{"title":"$:/plugins/Gk0Wk/CPL-Repo/config/current-repo","text":"https://tw-cpl.netlify.app/repo"},"$:/plugins/Gk0Wk/CPL-Repo/config/popup-readme-at-startup-threshold":{"title":"$:/plugins/Gk0Wk/CPL-Repo/config/popup-readme-at-startup-threshold","text":"1"},"$:/plugins/Gk0Wk/CPL-Repo/config/repos":{"title":"$:/plugins/Gk0Wk/CPL-Repo/config/repos","text":"https://tw-cpl.netlify.app/repo https://tiddly-gittly.github.io/TiddlyWiki-CPL/repo"},"$:/plugins/Gk0Wk/CPL-Repo/config/update-filter":{"title":"$:/plugins/Gk0Wk/CPL-Repo/config/update-filter","text":"[has[plugin-type]] -[prefix[$:/plugins/tiddlywiki/]] -[prefix[$:/themes/tiddlywiki/]] -[prefix[$:/languages/]] -[prefix[$:/temp/]] -[[$:/core]]"},"$:/plugins/Gk0Wk/CPL-Repo/core.js":{"title":"$:/plugins/Gk0Wk/CPL-Repo/core.js","text":"(function () {\n\"use strict\";\n\nexports.name = \"cpl-repo-init\";\nexports.platforms = [\"browser\"];\nexports.after = [\"render\"];\nexports.synchronous = true;\n\n/**\n * CPL通信接口,往返,异步\n * const result = await globalThis.__tiddlywiki_cpl__('类型', { ... });\n */\nvar messagerPromise;\nvar previousEntry;\nvar cpl = function (type, payload) {\n\tvar entry = $tw.wiki.getTiddlerText('$:/plugins/Gk0Wk/CPL-Repo/config/current-repo', 'https://tiddly-gittly.github.io/TiddlyWiki-CPL/repo');\n\tif (previousEntry !== entry && globalThis.__tiddlywiki_cpl__reset__ !== undefined) globalThis.__tiddlywiki_cpl__reset__();\n\tpreviousEntry = entry;\n if (messagerPromise === undefined) messagerPromise = new Promise(function (rrr) {\n var counter = 0;\n var callbackMap = new Map();\n var iframe = $tw.utils.domMaker(\"iframe\", {\n document,\n attributes: { src: entry },\n style: { display: \"none\" },\n });\n function ccc(e) {\n //console.log('<=', e.data);\n if (iframe.contentWindow === null || e.source !== iframe.contentWindow)\n return;\n if (e.data.target !== \"tiddlywiki-cpl\" || e.data.token === undefined)\n return;\n switch (e.data.type) {\n case \"Ready\": {\n if (counter === 0) {\n counter++;\n rrr(function (type, payload) {\n return new Promise(function (resolve, reject) {\n var token = counter++;\n callbackMap.set(token, [resolve, reject]);\n //console.log('=>', { type, token, target: \"tiddlywiki-cpl\", ...payload });\n iframe.contentWindow.postMessage(\n Object.assign({}, payload, {\n type: type,\n token: token,\n target: \"tiddlywiki-cpl\",\n }),\n \"*\"\n );\n });\n });\n }\n break;\n }\n default: {\n var r = callbackMap.get(e.data.token);\n if (r !== undefined) {\n callbackMap.delete(e.data.token);\n r[e.data.success ? 0 : 1](e.data.payload);\n }\n break;\n }\n }\n }\n window.addEventListener(\"message\", ccc);\n document.body.appendChild(iframe);\n globalThis.__tiddlywiki_cpl__reset__ = function () {\n delete globalThis.__tiddlywiki_cpl__reset__;\n window.removeEventListener(\"message\", ccc);\n iframe.parentNode.removeChild(iframe);\n callbackMap.forEach((r) => {\n r[1]();\n });\n };\n });\n return messagerPromise.then(function (r) { return r(type, payload) });\n};\n\nfunction getAutoUpdateTime() {\n\treturn parseInt($tw.wiki.getTiddlerText('$:/plugins/Gk0Wk/CPL-Repo/config/auto-update-intervals-minutes', '-1')) || -1;\n}\n\n// 自动更新服务、各种消息通信\nexports.startup = function () {\n globalThis.__tiddlywiki_cpl__ = cpl;\n\t// 检测更新\n\tvar lastUpdateTime = -1;\n var updateLock = false;\n\tfunction update(notify) {\n try {\n if (updateLock) return;\n updateLock = true;\n lastUpdateTime = Date.now();\n // filter 和 网络请求并发一下\n var updateP = cpl('Update');\n // 根据条件筛选插件\n var plugins = $tw.wiki.filterTiddlers($tw.wiki.getTiddlerText('$:/plugins/Gk0Wk/CPL-Repo/config/update-filter'));\n var t = [];\n updateP.then(function (text) {\n // 统计需要更新的插件\n var updatePlugins = JSON.parse(text);\n for (var title of plugins) {\n var lastestVersion = updatePlugins[title]; // [version, coreVersion]\n if (lastestVersion === undefined) continue; // 不存在该插件\n if (lastestVersion[1] && $tw.utils.compareVersions($tw.version, lastestVersion[1]) < 0) continue; // 插件兼容性检查\n var version = $tw.wiki.getTiddler(title).fields.version;\n if (version && $tw.utils.compareVersions(version, lastestVersion[0]) >= 0) continue; // 插件是否更新\n t.push(title);\n }\n if (t.length > 0) {\n // 写入临时信息\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/update-plugins', type: 'application/json', text: JSON.stringify(t) });\n if (notify !== false) {\n // 暂时修改通知停留时间为 10s\n var tt = $tw.config.preferences.notificationDuration;\n $tw.config.preferences.notificationDuration = 10_000;\n // 弹出通知框\n $tw.notifier.display(\"$:/plugins/Gk0Wk/CPL-Repo/update-notify-template\", {\n variables: { updateCount: t.length },\n });\n $tw.config.preferences.notificationDuration = tt;\n }\n }\n updateLock = false;\n }).catch(function (err) {\n console.error(err);\n updateLock = false;\n });\n } catch (err) {\n console.error(err);\n updateLock = false;\n }\n\t}\n\n\t// 监听自动更新策略的更改,调整更新间隔或者开关自动更新\n\tvar autoUpdateInterval;\n\tvar autoTimeout;\n\t$tw.wiki.addEventListener(\"change\", function (changes) {\n\t\tif($tw.utils.hop(changes, '$:/plugins/Gk0Wk/CPL-Repo/config/auto-update-intervals-minutes')) {\n var time = getAutoUpdateTime();\n\t\t\tif (autoUpdateInterval !== undefined) clearInterval(autoUpdateInterval);\n\t\t\tif (autoTimeout !== undefined) clearTimeout(autoTimeout);\n\t\t\tautoUpdateInterval = undefined;\n\t\t\tautoTimeout = undefined;\n\t\t\tif (time > 0) {\n\t\t\t\tautoTimeout = setTimeout(function () {\n\t\t\t\t\tupdate();\n\t\t\t\t\tautoUpdateInterval = setInterval(function () {\n\t\t\t\t\t\tupdate();\n\t\t\t\t\t}, time * 60_000);\n\t\t\t\t}, lastUpdateTime === -1 ? 0 : time * 60_000 + lastUpdateTime - Date.now());\n\t\t\t}\n\t\t}\n if($tw.titleWidgetNode.refresh(changes, $tw.titleContainer, null)) {\n document.title = $tw.titleContainer.textContent;\n }\n\t});\n\t// 最初启用\n\tautoTimeout = setTimeout(function () {\n var time = getAutoUpdateTime();\n\t\tif (time > 0) {\n update();\n autoUpdateInterval = setInterval(function () {\n update();\n }, time * 60_000);\n }\n\t}, 3_000);\n\n // 消息监听\n $tw.rootWidget.addEventListener(\"cpl-update-check\", function () {\n update();\n });\n var installRequestLock = false;\n $tw.rootWidget.addEventListener(\"cpl-install-plugin-request\", function (event) {\n try {\n if (installRequestLock) return;\n var paramObject = event.paramObject || {};\n var title = paramObject.title;\n var version = paramObject.version || \"latest\";\n if (!title) return;\n installRequestLock = true;\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/instal-plugin-requesting', text: 'yes', 'plugin-title': title });\n $tw.notifier.display('$:/plugins/Gk0Wk/CPL-Repo/install-plugin-query-notify', { variables: {} });\n var existingTitle = new Set(); // 避免环\n var versionsMap = {};\n var versionsMapLatest = {};\n var sizesMap = {};\n // 递归检查依赖\n var title_ = title;\n function recursiveInstallCheck(title) {\n return new Promise(function (resolve, reject) {\n cpl('Query', { plugin: title }).then(function (text) {\n var data = JSON.parse(text);\n existingTitle.add(title);\n if (title === title_ && data.versions.indexOf(version) < 0) version = data.latest;\n versionsMap[title] = data.versions;\n versionsMapLatest[title] = data.latest;\n sizesMap[title] = data['versions-size'] || {};\n var t = new Set();\n var promisese = [];\n var subtree = {};\n\n // for没有局部作用域,var不是迭代局部的\n function fuckUpVar(ti) {\n t.add(ti);\n if (existingTitle.has(ti)) {\n subtree[ti] = {};\n } else {\n promisese.push(recursiveInstallCheck(ti).then(\n function (tt) { subtree[ti] = tt; },\n function (tt) { reject(tt); },\n ));\n }\n }\n if (data['parent-plugin']) {\n fuckUpVar(data['parent-plugin']);\n }\n for (var ti of $tw.utils.parseStringArray(data.dependents || '')) {\n if (t.has(ti)) continue;\n fuckUpVar(ti);\n }\n Promise.all(promisese).then(function () {\n resolve(subtree);\n });\n }).catch(function (err) { reject(err); });\n });\n }\n\n recursiveInstallCheck(title).then(function (tree) {\n var f = {};\n for (var ti of existingTitle) {\n if (ti === title) continue;\n f['cpl-plugin#version#' + ti] = versionsMapLatest[ti];\n f['cpl-plugin#install#' + ti] = $tw.wiki.tiddlerExists(ti) ? \"no\" : \"yes\";\n }\n f['cpl-plugin#version#' + title] = version;\n $tw.wiki.addTiddler({\n title: '$:/temp/CPL-Repo/instal-plugin-request-tree/' + title,\n type: 'application/json',\n text: JSON.stringify({ title: title, versions: versionsMap, sizes: sizesMap, tree: tree }),\n ...f,\n });\n $tw.wiki.deleteTiddler('$:/temp/CPL-Repo/instal-plugin-requesting');\n $tw.modal.display('$:/plugins/Gk0Wk/CPL-Repo/install-plugin-request-model-template', {\n variables: {\n requestTiddler: '$:/temp/CPL-Repo/instal-plugin-request-tree/' + title,\n },\n event: event,\n });\n }).catch(function (err) {\n console.error(err);\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/instal-plugin-requesting', text: err, 'plugin-title': title });\n }).finally(function () {\n installRequestLock = false;\n });\n } catch (err) {\n console.error(err);\n installRequestLock = false;\n }\n });\n var installLock = false;\n $tw.rootWidget.addEventListener(\"cpl-install-plugin\", function (event) {\n try {\n if (installLock) return;\n var paramObject = event.paramObject || {};\n var response = paramObject.response;\n if (!$tw.wiki.tiddlerExists(response)) return;\n var responseTiddler = $tw.wiki.getTiddler(response).fields;\n $tw.wiki.deleteTiddler(response);\n var data = JSON.parse(responseTiddler.text);\n var rootPlugin = data.title;\n var plugins = [[rootPlugin, responseTiddler['cpl-plugin#version#'+rootPlugin]]];\n for (var plugin in data.versions) {\n if (responseTiddler['cpl-plugin#install#'+plugin] === 'yes' && responseTiddler['cpl-plugin#version#'+plugin]) {\n plugins.push([plugin, responseTiddler['cpl-plugin#version#'+plugin]]);\n }\n }\n var total = plugins.length;\n var count = 0;\n installLock=true;\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/installing-plugin', text: 'yes', 'plugin-title': rootPlugin });\n Promise.all(plugins.map(function (t) {\n return cpl('Install', { plugin: t[0], version: t[1] }).then(function (text) {\n $tw.notifier.display('$:/plugins/Gk0Wk/CPL-Repo/downloading-notify', {\n variables: { plugin: t[0], count: ++count, total: total },\n });\n return new $tw.Tiddler($tw.utils.parseJSONSafe(text));\n });\n })).then(function (tiddlers) {\n $tw.wiki.deleteTiddler('$:/temp/CPL-Repo/installing-plugin');\n for (var tiddler of tiddlers) {\n $tw.wiki.addTiddler(tiddler);\n }\n $tw.notifier.display('$:/plugins/Gk0Wk/CPL-Repo/downloading-complete-notify', { variables: {} });\n }).catch(function (err) {\n console.error(err);\n $tw.notifier.display('$:/plugins/Gk0Wk/CPL-Repo/downloading-fail-notify', {\n variables: { message: err },\n });\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/installing-plugin', text: err, 'plugin-title': rootPlugin });\n }).finally(function () {\n installLock = false;\n });\n } catch (e) {\n console.error(e);\n installLock = false;\n }\n });\n var tmpIndex;\n var tmpAllPlugins;\n var tmpCategories;\n var getPluginsIndexLock = false;\n $tw.rootWidget.addEventListener(\"cpl-get-plugins-index\", function () {\n try {\n if (getPluginsIndexLock) return;\n getPluginsIndexLock = true;\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/getting-plugins-index', text: 'yes' });\n cpl('Index').then(function (text) {\n var data = JSON.parse(text);\n var pluginMap = {};\n var categories = {};\n var authors = {};\n var allPlugins = [];\n var allTags = new Set();\n for (var p of data) {\n pluginMap[p.title] = p;\n allPlugins.push(p.title);\n if (p.category && p.category !== 'Unknown') {\n if (categories[p.category] === undefined) categories[p.category] = [];\n categories[p.category].push(p.title);\n }\n if (p.author) {\n if (authors[p.author] === undefined) authors[p.author] = [];\n authors[p.author].push(p.title);\n }\n if (!p.title.startsWith('$:/languages') && p.title.split('/').length === 4) {\n var a = p.title.split('/')[2];\n if (a !== p.author) {\n if (authors[a] === undefined) authors[a] = [];\n authors[a].push(p.title);\n }\n }\n if (p.tags) {\n for (var tag of $tw.utils.parseStringArray(p.tags)) {\n allTags.add(tag);\n }\n }\n }\n tmpIndex = data;\n tmpAllPlugins = allPlugins;\n tmpCategories = categories;\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/plugins-index', text: JSON.stringify(pluginMap), type: 'application/json' });\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/categories', text: JSON.stringify(categories), type: 'application/json' });\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/authors', text: JSON.stringify(authors), type: 'application/json' });\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/tags', text: JSON.stringify(Array.from(allTags)), type: 'application/json' });\n $tw.wiki.deleteTiddler('$:/temp/CPL-Repo/getting-plugins-index');\n }).catch(function (err) {\n console.error(err);\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/getting-plugins-index', text: err });\n }).finally(function () {\n getPluginsIndexLock = false;\n });\n } catch (err) {\n console.error(err);\n getPluginsIndexLock = false;\n }\n });\n var queryPluginLocks = new Set();\n $tw.rootWidget.addEventListener(\"cpl-query-plugin\", function (event) {\n try {\n var paramObject = event.paramObject || {};\n var title = paramObject.title;\n if (queryPluginLocks.has(title)) return;\n if (!title) return;\n queryPluginLocks.add(title);\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/querying-plugin/' + title, text: 'yes' });\n cpl('Query', { plugin: title }).then(function (text) {\n var data = JSON.parse(text);\n // 计算作者\n if (!data.author) {\n if (!data.title.startsWith('$:/languages') && data.title.split('/').length === 4) {\n data.author = data.title.split('/')[2];\n }\n }\n // 相似推荐\n var suggestions = [];\n if (tmpIndex && data.category !== 'Language') {\n // 基于标签距离进行推荐\n if (data.tags) {\n var tags = new Set($tw.utils.parseStringArray(data.tags).map(function (t) { return t.toLowerCase(); }));\n for (var plugin of tmpIndex) {\n if (!plugin.tags || plugin.title === title) continue;\n var weight = 0;\n for (var t of $tw.utils.parseStringArray(data.tags)) {\n if (tags.has(t.toLowerCase())) weight++;\n }\n if (weight === 0) continue;\n suggestions.push([plugin.title, weight]);\n }\n }\n // 按照权重排序\n suggestions.sort(function (a, b) { return b[1] - a[1]; });\n suggestions = suggestions.slice(0, 20).map(function (t) { return t[0] });\n // 如果数量不够,用同category\n if (suggestions.length < 20 && data.category !== '' && data.category !== 'Unknown') {\n var tset = new Set(suggestions);\n for (var p of (tmpCategories[data.category] ?? [])) {\n if (tset.has(p) || p === title) continue;\n suggestions.push(p);\n if (suggestions.length >= 20) break;\n }\n }\n }\n data.suggestions = $tw.utils.stringifyList(suggestions);\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/plugin-info/' + title, text: JSON.stringify(data), type: 'application/json' });\n $tw.wiki.deleteTiddler('$:/temp/CPL-Repo/querying-plugin/' + title);\n }).catch(function (err) {\n console.error(err);\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/querying-plugin/' + title, text: err });\n }).finally(function () {\n queryPluginLocks.delete(title);\n });\n } catch (err) {\n console.error(err);\n if (event.paramObject && event.paramObject.title) queryPluginLocks.delete(event.paramObject.title);\n }\n });\n // 插件查询\n var searchPluginsLock = false;\n $tw.rootWidget.addEventListener(\"cpl-search-plugins\", function (event) {\n try {\n if (searchPluginsLock) return;\n if (tmpAllPlugins === undefined) return;\n var paramObject = event.paramObject || {};\n var mode = paramObject.mode ?? '';\n var text = paramObject.text ?? '';\n var saveTo = paramObject.saveTo ?? '';\n if (!saveTo) return;\n searchPluginsLock = true;\n switch (mode) {\n case \"mix\": {\n if (text.length < 3) {\n // 字太少,匹配量爆炸,直接返回所有\n $tw.wiki.addTiddler({\n title: saveTo,\n text: JSON.stringify(tmpAllPlugins),\n type: 'application/json'\n });\n } else {\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/searching-plugin', text: 'yes' });\n var patterns = new Set(text.split(/\\s+/).map(function (t) { return t.toLowerCase(); }));\n patterns = new Set(Array.from(patterns).slice(0, 10)); // 再多性能撑不住了\n var suggestions = [];\n for (var plugin of tmpIndex) {\n var weight = 0;\n // 标题、作者、名称的搜索 10 权重\n for (var f of ['title', 'author', 'name']) {\n if (plugin[f]) {\n var t = plugin[f].toLowerCase();\n for (var pattern of patterns) {\n if (t.indexOf(pattern) >= 0) weight += 10;\n }\n }\n }\n // tag 的搜索 5 权重\n if (plugin.tags) {\n for (var t of $tw.utils.parseStringArray(plugin.tags)) {\n if (patterns.has(t.toLowerCase())) weight += 5;\n }\n }\n // description 搜索 2 权重\n if (plugin.description) {\n var t = plugin.description.toLowerCase();\n for (var pattern of patterns) {\n if (t.indexOf(pattern) >= 0) weight += 2;\n }\n }\n // readme 搜索 1 权重\n if (plugin.description) {\n var t = plugin.description;\n for (var pattern of patterns) {\n if (t.indexOf(pattern) >= 0) weight += 1;\n }\n }\n if (weight === 0) continue;\n suggestions.push([plugin.title, weight]);\n }\n // 按照权重排序\n suggestions.sort(function (a, b) { return b[1] - a[1]; });\n suggestions = suggestions.map(function (t) { return t[0] });\n $tw.wiki.addTiddler({\n title: saveTo,\n text: JSON.stringify(suggestions),\n type: 'application/json'\n });\n $tw.wiki.deleteTiddler('$:/temp/CPL-Repo/searching-plugin');\n }\n break;\n }\n case \"tags\": {\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/searching-plugin', text: 'yes' });\n var tags = new Set($tw.utils.parseStringArray(text).map(function (t) { return t.toLowerCase(); }));\n var result = [];\n for (var plugin of tmpIndex) {\n if (!plugin.tags) continue;\n var matched = true;\n for (var t of $tw.utils.parseStringArray(plugin.tags)) {\n if (tags.has(t.toLowerCase())) continue;\n matched = false;\n break;\n }\n if (matched) result.push(plugin.title);\n }\n $tw.wiki.addTiddler({\n title: saveTo,\n text: JSON.stringify(result),\n type: 'application/json'\n });\n $tw.wiki.deleteTiddler('$:/temp/CPL-Repo/searching-plugin');\n break;\n }\n default: {\n return;\n }\n }\n searchPluginsLock = false;\n } catch (err) {\n console.error(err);\n $tw.wiki.addTiddler({ title: '$:/temp/CPL-Repo/searching-plugin', text: String(err) });\n searchPluginsLock = false;\n }\n });\n};\n\n/*\n安装插件\n<$action-sendmessage $message=\"cpl-install-plugin\" title=\"xxx\" version=\"latest\"/>\n$:/temp/CPL-Repo/installing-plugin 如果为 yes 说明正在安装,请勿进行其他操作 如果不是yes,如果非空说明是错误信息 plugin-title字段是正在安装的插件\n\n获取所有插件的索引\n<$action-sendmessage $message=\"cpl-get-plugins-index\"/>\n$:/temp/CPL-Repo/plugins-index 所有信息\n$:/temp/CPL-Repo/getting-plugins-index 同上\n\n查询某个插件的信息\n<$action-sendmessage $message=\"cpl-query-plugin\" title=\"xxx\"/>\n$:/temp/CPL-Repo/plugin-info/<插件title> 插件的相关信息\n$:/temp/CPL-Repo/querying-plugin/<插件title> 同上\n*/\n})();\n","module-type":"startup","tags":[],"type":"application/javascript"},"$:/plugins/Gk0Wk/CPL-Repo/downloading-complete-notify":{"title":"$:/plugins/Gk0Wk/CPL-Repo/downloading-complete-notify","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"!! <$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[安装完成]else[Installation completed]] }}} />"},"$:/plugins/Gk0Wk/CPL-Repo/downloading-fail-notify":{"title":"$:/plugins/Gk0Wk/CPL-Repo/downloading-fail-notify","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"!! <$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[安装失败]else[Installation failed]] }}} />\n\n<>"},"$:/plugins/Gk0Wk/CPL-Repo/downloading-notify":{"title":"$:/plugins/Gk0Wk/CPL-Repo/downloading-notify","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n\n<$list filter=\"[match[yes]]\" variable=\"t\">\n\n!! 请稍候...\n\n正在下载第 <> 个插件(共 <> 个): <>\n\n\n\n<$list filter=\"[!match[yes]]\" variable=\"t\">\n\n!! Please wait...\n\nDownloading the <> of plugins (total <>): <>\n\n\n\n"},"$:/plugins/Gk0Wk/CPL-Repo/home-gallery":{"title":"$:/plugins/Gk0Wk/CPL-Repo/home-gallery","caption":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[首页]else[Home]] }}} />","tags":[],"type":"text/vnd.tiddlywiki","text":"\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-list-item\n\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-size\n\\import $:/plugins/Gk0Wk/CPL-Repo/paged-plugin-list\n\n
\n<$edit-text\n tiddler=\"$:/temp/CPL-Repo/searchplugin-home/input\"\n default=\"\"\n placeholder={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[搜索插件...]else[Search for plugin...]] }}}\n focus=\"true\"\n tag=\"input\"\n class=\"tc-titlebar tc-edit-texteditor cpl-plugin-search\"\n/>\n<$button class=\"tc-primary-btn tc-btn-big-green cpl-plugin-search-go\" disabled={{$:/temp/CPL-Repo/searching-plugin}}>\n <$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]] :then[{$:/temp/CPL-Repo/searching-plugin}match[yes]then[搜索中...]else[搜索]] :else[{$:/temp/CPL-Repo/searching-plugin}match[yes]then[Searching...]else[Search]] }}} />\n <$action-sendmessage\n $message=\"cpl-search-plugins\"\n mode=\"mix\"\n text={{$:/temp/CPL-Repo/searchplugin-home/input}}\n saveTo=\"$:/temp/CPL-Repo/searchplugin-home/result\"\n />\n\n
\n<$list filter=\"[[$:/temp/CPL-Repo/searching-plugin]is[tiddler]!field:text[yes]]\">\n
\n\t<$text text={{{ [match[yes]then[出现了一些问题]else[Some errors occured]] }}}/>: <$text text={{!!text}}/>\n
\n\n<$list filter=\"[[$:/temp/CPL-Repo/searchplugin-home/result]is[tiddler]then[yes]else[no]]\" variable=\"go\">\n\n<$list filter=\"[match[yes]]\" variable=\"t\">\n<>\n\n\n<$list filter=\"[match[no]]\" variable=\"t\">\n<>\n\n\n"},"$:/plugins/Gk0Wk/CPL-Repo/install-plugin-query-notify":{"title":"$:/plugins/Gk0Wk/CPL-Repo/install-plugin-query-notify","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[获取安装信息中,请稍候]else[Getting installation information, please wait]] }}} />"},"$:/plugins/Gk0Wk/CPL-Repo/install-plugin-request-model-template":{"title":"$:/plugins/Gk0Wk/CPL-Repo/install-plugin-request-model-template","code-body":"yes","subtitle":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[请确认安装]else[Please Confirm to Install]] }}} />","tags":[],"type":"text/vnd.tiddlywiki","text":"\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-size\n\n\\define dependents-tree(json,checked-title,versions,sizes)\n<$list filter=\"[<__json__>jsonindexes[]]\" variable=\"plugin\">\n
\n<$let install-field={{{ [[cpl-plugin#install#]addsuffix] }}} version-field={{{ [[cpl-plugin#version#]addsuffix] }}}>\n
\n\n ''<$text text=<>/>'' \n <$let v={{{ [<__checked-title__>get] }}}>\n <$macrocall name=\"plugin-size\" size={{{ [<__sizes__>jsonget,else[0]] }}} />\n \n\n\n<$checkbox tiddler=<<__checked-title__>> field=<> checked=\"yes\" unchecked=\"no\" default=\"no\">\n <$text text={{{ [<__checked-title__>getmatch[yes]] :then[match[yes]then[即将安装:]else[Will be installed:]] :else[match[yes]then[不会安装]else[Will not be installed]] }}} />\n\n<$list filter=\"[<__checked-title__>getmatch[yes]]\" variable=\"t\">\n \n<$select tiddler=<<__checked-title__>> field=<>>\n<$list filter=\"[<__versions__>jsonget]\" variable=\"version\">\n\n\n\n\n\n
\n<$macrocall $name=\"dependents-tree\" json={{{ [<__json__>jsonextract] }}} checked-title=<<__checked-title__>> versions=<<__versions__>> sizes=<<__sizes__>> />\n\n
\n\n\\end\n\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n<$let json={{{ [get[text]] }}}>\n\n<<<\n<$let title={{{ [jsonget[title]] }}}>\n''<$text text={{{ [match[yes]then[即将安装:]else[To be installed:]] }}}/>''\n<$text text=<>/>   \n''<$text text={{{ [<chinese>match[yes]then[选择版本:]else[Select version:]] }}}/>''\n<$select tiddler=<<requestTiddler>> field={{{ [[cpl-plugin#version#]addsuffix<title>] }}}>\n<$list filter=\"[<json>jsonget[versions],<title>]\" variable=\"version\">\n<option value=<<version>>><$text text=<<version>>/></option>\n</$list>\n</$select>\n</$let>\n<<<\n\n<!-- 依赖树 -->\n<$list filter=\"[<json>jsonextract[tree]jsonindexes[]count[]compare:integer:gt[0]]\" variable=\"t\">\n<$list filter=\"[<chinese>match[yes]]\" variable=\"t\">\n\n这个插件有一些依赖项,在安装插件之前,将会递归地安装这些插件,如果这些插件没有被成功安装,将会回滚所有安装动作。\n\n你可以自行选择安装哪些插件并选择其版本。插件依赖树如下:\n\n</$list>\n<$list filter=\"[<chinese>!match[yes]]\" variable=\"t\">\n\nThis plugin has some dependencies that will be installed recursively before installing the plugin, and if these plugins are not installed successfully, all installation actions will be rolled back.\n\nIt is up to you to choose which plugins to install and select their versions. The plugin dependency tree is as follows:\n\n</$list>\n<div style=\"margin-left:-1em;margin-right:6px;\">\n <$macrocall\n $name=\"dependents-tree\"\n json={{{ [<json>jsonextract[tree]] }}}\n checked-title=<<requestTiddler>>\n versions={{{ [<json>jsonextract[versions]] }}}\n sizes={{{ [<json>jsonextract[sizes]] }}}\n />\n</div>\n<hr/>\n</$list>\n\n<$list filter=\"[<chinese>match[yes]]\" variable=\"t\">\n\n注意:虽然 CPL 对安装失败有一定的回滚措施,但是无法避免因插件自身以及插件间相互作用所产生的潜在风险,包括但不限于\n\n* 浏览器崩溃;\n* Wiki 系统受损或数据丢失;\n* 插件内含恶意脚本的执行造成隐私泄露或系统损坏;\n\nCPL [[接受恶意插件举报|https://github.com/tiddly-gittly/TiddlyWiki-CPL/issues]]并将下架这类插件,但 CPL 不能保证其中收录的所有插件均安全可用。如您在安装后出现任何问题造成损失,CPL 无法负责。\n\n@@background:#e91e3db0;color:white;padding:4px;''因此,在安装任何插件前,请备份您的Wiki!''@@\n\n即便如此,您依然要安装吗?\n\n</$list>\n\n<$list filter=\"[<chinese>!match[yes]]\" variable=\"t\">\n\nNote: Although the CPL has some rollback measures for failed installations, it is not immune to the potential risks arising from the plugins themselves and from interactions between plugins, including but not limited to\n\n* Browser crashes;\n* Damage to the Wiki system or loss of data;\n* Privacy leakage or system damage caused by the execution of malicious scripts contained in the plugin;\n\nCPL [[accepts reports of malicious plugins|https://github.com/tiddly-gittly/TiddlyWiki-CPL/issues]] and will take down such plugins, but CPL cannot guarantee that all plugins included are safe and available. However, CPL cannot guarantee that all plugins are safe and available. CPL cannot be held responsible for any damage caused by any problem that occurs after you have installed the plugin.\n\n@@background:#e91e3db0;color:white;width:100%;padding:4px;''Therefore, please back up your wiki before installing any plugins!''@@\n\nEven so, do you still want to install it?\n\n</$list>\n\n<$button class=\"tc-btn-big-green tc-primary-btn\" message=\"tm-close-tiddler\">\n<$action-sendmessage $message=\"cpl-install-plugin\" response=<<requestTiddler>> />\n{{$:/core/images/done-button}}\n \n<$text text={{{ [<chinese>match[yes]then[确认安装]else[Confirm to Install]] }}} />\n</$button>\n\n</$let>\n</$list>\n"},"$:/plugins/Gk0Wk/CPL-Repo/paged-plugin-list":{"title":"$:/plugins/Gk0Wk/CPL-Repo/paged-plugin-list","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"\\define paged-plugin-list-control(class2:\"\")\n\\whitespace trim\n<$list filter=\"[<pageMin>!match<pageMax>]\">\n<div class=\"$class2$\">\n <div>\n <$list filter=\"[<page>!match<lastPage>]\">\n <$button setTitle=<<pageState>> setTo=<<lastPage>>>{{$:/core/images/left-arrow}}</$button>\n </$list>\n </div>\n <span><$text text={{{ [<page>add[1]] }}}/> / <$text text={{{ [<pageMax>add[1]] }}}/></span>\n <div>\n <$list filter=\"[<page>!match<nextPage>]\">\n <$button setTitle=<<pageState>> setTo=<<nextPage>>>{{$:/core/images/right-arrow}}</$button>\n </$list>\n </div>\n</div>\n</$list>\n\\end\n\\define paged-plugin-list(filter,field,pageSize:\"10\",indexTitle:\"$:/temp/CPL-Repo/plugins-index\",class1:\"\",class2:\"\")\n\\whitespace trim\n<$let pageSize={{{ [<__pageSize__>min[1]] }}} indexTitle=<<__indexTitle__>> pageState=<<qualify \"$:/temp/CPL-Repo/paged-plugin-list-page\">> pluginCount={{{ $filter$ +[count[]] }}}>\n<$let pageMin=\"0\" pageMax={{{ [<pluginCount>divide<__pageSize__>ceil[]subtract[1]max[0]] }}}>\n<$let page={{{ [<pageState>get[text]else<pageMin>] +[max<pageMin>min<pageMax>] }}}>\n<$let firstIndex={{{ [<page>multiply<__pageSize__>] }}} nextPage={{{ [<page>add[1]min<pageMax>] }}} lastPage={{{ [<page>subtract[1]max<pageMin>] }}}>\n<<paged-plugin-list-control \"$class2$\">>\n<div class=\"$class1$\">\n <$list filter=\"$filter$ +[rest<firstIndex>first<__pageSize__>]\" variable=\"plugin\">\n <$macrocall\n $name=\"plugin-list-item\"\n json={{{ [{$:/temp/CPL-Repo/plugins-index}jsonextract<plugin>] }}}\n field=\"$field$\"\n class=\"cpl-plugin-info-box\"\n />\n </$list>\n</div>\n<<paged-plugin-list-control \"$class2$\">>\n</$let>\n</$let>\n</$let>\n</$let>\n\\end\n"},"$:/plugins/Gk0Wk/CPL-Repo/panel":{"title":"$:/plugins/Gk0Wk/CPL-Repo/panel","caption":"CPL","list-after":"$:/core/ui/ControlPanel/Plugins","tags":["$:/tags/MoreSideBar","$:/tags/ControlPanel"],"type":"text/vnd.tiddlywiki","text":"<!-- 在侧栏不显示 -->\n<$list filter=\"[<listItem>!match[$:/core/ui/SideBarSegments/tabs]]\">\n{{$:/plugins/Gk0Wk/CPL-Repo/about-banner}}\n</$list>\n\n<$macrocall\n\t$name=\"tabs\"\n\tstate=\"$:/temp/CPL-Repo/panel-tab-state\"\n\ttabsList=\"plugin-database settings +[addprefix[$:/plugins/Gk0Wk/CPL-Repo/]]\"\n\tdefault=\"$:/plugins/Gk0Wk/CPL-Repo/plugin-database\"\n/>\n"},"$:/plugins/Gk0Wk/CPL-Repo/plugin-database":{"title":"$:/plugins/Gk0Wk/CPL-Repo/plugin-database","caption":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[插件数据库]else[Plugin Database]] }}} />","tags":[],"type":"text/vnd.tiddlywiki","text":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n\n<$button disabled={{{ [{$:/temp/CPL-Repo/getting-plugins-index}match[yes]else[no]] }}} class=\"tc-btn-big-green tc-primary-btn\">\n<$action-sendmessage $message=\"cpl-get-plugins-index\" />\n{{$:/core/images/download-button}}\n \n<$text text={{{ [[$:/temp/CPL-Repo/plugins-index]is[tiddler]] :then[<chinese>match[yes]then[刷新数据库]else[Refresh Database]] :else[<chinese>match[yes]then[加载数据库]else[Load Database]] }}} />\n</$button>\n\n<span style=\"opacity:0.5;\"><$text text={{{ [<chinese>match[yes]then[当前镜像]else[Current mirror]] }}}/>: <$text text={{{ [{$:/plugins/Gk0Wk/CPL-Repo/config/current-repo}!is[blank]else[https://tiddly-gittly.github.io/TiddlyWiki-CPL/library/all]] }}} /></span>\n\n<!-- 错误提示 -->\n<$list filter=\"[[$:/temp/CPL-Repo/getting-plugins-index]is[tiddler]!field:text[yes]]\">\n<div style=\"background:#e91e3db0;color:white;padding:2px 6px;margin:3px 0;border-radius:2px;backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;\">\n\t<$text text={{{ [<chinese>match[yes]then[出现了一些问题]else[Some errors occured]] }}}/>: <$text text={{!!text}}/>\n\t<$text text={{{ [<chinese>match[yes]then[请尝试刷新]else[Please try refreshing]] }}}/>\n</div>\n</$list>\n\n<!-- 加载中提示 -->\n<$list filter=\"[[$:/temp/CPL-Repo/getting-plugins-index]is[tiddler]field:text[yes]]\">\n<div style=\"background:#0005;color:#aaa;padding:2px 6px;margin:3px 0;border-radius:2px;backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;\">\n\t<$text text={{{ [<chinese>match[yes]then[加载中...]else[Loading...]] }}}/>\n</div>\n</$list>\n\n<$list filter=\"[[$:/temp/CPL-Repo/plugins-index]is[tiddler]]\" variable=\"ready\">\n<$macrocall\n\t$name=\"tabs\"\n\tstate=\"$:/temp/CPL-Repo/plugin-database-tab-state\"\n\ttabsList=\"home-gallery category-gallery tags-gallery update-manager +[addprefix[$:/plugins/Gk0Wk/CPL-Repo/]]\"\n\tdefault=\"$:/plugins/Gk0Wk/CPL-Repo/home-gallery\"\n/>\n</$list>\n\n</$list>\n"},"$:/plugins/Gk0Wk/CPL-Repo/plugin-list-item":{"title":"$:/plugins/Gk0Wk/CPL-Repo/plugin-list-item","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"\\define tag-plain(text:\"\",icon:\"\",color:\"\",bg:\"\")\n\\whitespace trim\n<span class=\"tc-tag-label\" style=\"background-color:$bg$;color:$color$;fill:$color$;user-select:none;margin-right:6px;\">\n\t{{$icon$}}$text$\n</span>\n\\end\n\n<!-- 安装插件的按钮 -->\n\\define install-plugin-button(plugin,libraryVersion,installedVersion)\n\\whitespace trim\n<div>\n <$let libraryVersion=<<__libraryVersion__>> installedVersion=<<__installedVersion__>> plugin=<<__plugin__>>>\n <$set name=\"reinstall-type\" value={{{ [<libraryVersion>compare:version:eq<installedVersion>then[tc-reinstall]] [<libraryVersion>compare:version:gt<installedVersion>then[tc-reinstall-upgrade]] [<libraryVersion>compare:version:lt<installedVersion>then[tc-reinstall-downgrade]] }}}>\n <$button class={{{ [<installedVersion>!is[blank]then<reinstall-type>] tc-btn-invisible tc-install-plugin +[join[ ]] }}} disabled={{{ [[$:/temp/CPL-Repo/instal-plugin-requesting]field:text[yes]else[]] [[$:/temp/CPL-Repo/installing-plugin]field:text[yes]else[]] +[unique[]match[yes]limit[1]else[no]] }}}>\n <$action-sendmessage $message=\"cpl-install-plugin-request\" title=<<plugin>> version=<<libraryVersion>>/>\n <$list filter=\"[[$:/temp/CPL-Repo/instal-plugin-requesting]field:plugin-title<plugin>]\">{{$:/core/images/timestamp-on}}</$list>\n <$list filter=\"[[$:/temp/CPL-Repo/instal-plugin-requesting]!field:plugin-title<plugin>]\">\n {{$:/core/images/download-button}}\n \n <!-- 根据版本判断安装/升级/降级/重装 -->\n <$list filter=\"[<installedVersion>is[blank]]\">{{$:/language/ControlPanel/Plugins/Install/Caption}}</$list>\n <$list filter=\"[<installedVersion>!is[blank]]\">\n <$list filter=\"[<libraryVersion>compare:version:gt<installedVersion>]\">{{$:/language/ControlPanel/Plugins/Update/Caption}}</$list>\n <$list filter=\"[<libraryVersion>compare:version:lt<installedVersion>]\">{{$:/language/ControlPanel/Plugins/Downgrade/Caption}}</$list>\n <$list filter=\"[<libraryVersion>compare:version:eq<installedVersion>]\">{{$:/language/ControlPanel/Plugins/Reinstall/Caption}}</$list>\n </$list>\n </$list>\n </$button>\n </$set>\n </$let>\n</div>\n\\end\n\n\\define plugin-list-item(json,field,show-suggestion:\"yes\",class:\"\")\n\\whitespace trim\n\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-size\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n<div class=\"$class$\">\n<$let json=<<__json__>>>\n<$let\n title={{{ [<json>jsonget[title]] }}}\n tags={{{ [<json>jsonget[tags]] }}}\n icon={{{ [<json>jsonget[icon]trim[]] }}}\n type={{{ [<json>jsonget[type]else[plugin]] }}}\n name={{{ [<json>jsonget[name]] ~[<json>jsonget[title]split[/]last[1]] }}}\n description={{{ [<json>jsonget[description]] }}}\n version={{{ [<json>jsonget[version]] }}}\n category={{{ [<json>jsonget[category]!is[blank]else[Unknown]] }}}\n installedVersion={{{ [<json>jsonget[title]get[version]] }}}\n detailJsonTitle={{{ $:/temp/CPL-Repo/plugin-info [<json>jsonget[title]] +[join[/]] }}}\n detailJsonStateTitle={{{ $:/temp/CPL-Repo/querying-plugin [<json>jsonget[title]] +[join[/]] }}}\n>\n<$let popup-state={{{ $:/temp/CPL-Repo/popup-state [<__field__>] [<title>] +[join[/]] }}}>\n<!-- 插件简介 -->\n<div class=\"tc-plugin-info\">\n <!-- 展开/收起按钮 -->\n <div class=\"tc-plugin-info-chunk tc-plugin-info-toggle\">\n <$reveal type=\"nomatch\" state=<<popup-state>> text=\"yes\">\n <$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"yes\">\n <$action-sendmessage $message=\"cpl-query-plugin\" title=<<title>>/>\n {{$:/core/images/chevron-right}}\n </$button>\n </$reveal>\n <$reveal type=\"match\" state=<<popup-state>> text=\"yes\">\n <$button class=\"tc-btn-invisible tc-btn-dropdown\" set=<<popup-state>> setTo=\"no\">\n {{$:/core/images/chevron-down}}\n </$button>\n </$reveal>\n </div>\n <!-- 插件图标 -->\n <div class=\"tc-plugin-info-chunk tc-plugin-info-icon\">\n <$list filter=\"[<icon>!is[blank]]\">\n <img src=<<icon>>/>\n </$list>\n <$list filter=\"[<icon>is[blank]]\">\n <$transclude tiddler={{{ [[$:/core/images/plugin-generic-]addsuffix<type>] }}}/>\n </$list>\n </div>\n <!-- 标题,简介,版本,是否安装,标签分类 -->\n <div class=\"tc-plugin-info-chunk tc-plugin-info-description\">\n <h1><strong><$text text=<<name>>/></strong>: <$text text=<<description>>/></h1>\n <h2><$text text=<<title>>/></h2>\n <div><em><$text text=<<version>>/></em></div>\n <div style=\"padding-top:4px;\">\n <$macrocall $name=\"tag-plain\" text={{{ [<chinese>match[yes]] :then[<category>addprefix[$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/]get[text]else[未分类]] :else[<category>] }}} icon=\"$:/core/images/folder\" bg=\"#3f51b5\" color=\"#fff\" />\n <$let bg={{{ [{$:/palette}getindex[tag-background]] }}} color={{{ [{$:/palette}getindex[foreground]] }}}>\n <$list filter=\"[enlist<tags>]\" variable=\"tag\">\n <$macrocall $name=\"tag-plain\" text=<<tag>> icon=\"$:/core/images/tag-button\" bg=<<bg>> color=<<color>> />\n </$list>\n </$let>\n </div>\n <$list filter=\"[<installedVersion>!is[blank]]\" variable=\"t\">\n <div><em>{{$:/language/ControlPanel/Plugins/AlreadyInstalled/Hint}}</em></div>\n </$list>\n <$list filter=\"[[$:/temp/CPL-Repo/instal-plugin-requesting]is[tiddler]field:plugin-title<plugin>]\">\n <$list filter=\"[{$:/temp/CPL-Repo/instal-plugin-requesting}match[yes]]\">\n <span style=\"color:#3ed044;font-weight:800;\"><$text text={{{ [<chinese>match[yes]then[安装准备中...]else[Preparing installation...]] }}}/></span>\n </$list>\n <$list filter=\"[{$:/temp/CPL-Repo/instal-plugin-requesting}!match[yes]]\">\n <span style=\"color:#fd160e;font-weight:800;\"><$text text={{{ [<chinese>match[yes]then[出错: ]else[Error: ]addsuffix{$:/temp/CPL-Repo/instal-plugin-requesting}] }}}/></span>\n </$list>\n </$list>\n <$list filter=\"[[$:/temp/CPL-Repo/installing-plugin]is[tiddler]field:plugin-title<plugin>]\">\n <$list filter=\"[{$:/temp/CPL-Repo/installing-plugin}match[yes]]\">\n <span style=\"color:#3ed044;font-weight:800;\"><$text text={{{ [<chinese>match[yes]then[安装中...]else[Installing...]] }}}/></span>\n </$list>\n <$list filter=\"[{$:/temp/CPL-Repo/installing-plugin}!match[yes]]\">\n <span style=\"color:#fd160e;font-weight:800;\"><$text text={{{ [<chinese>match[yes]then[出错: ]else[Error: ]addsuffix{$:/temp/CPL-Repo/installing-plugin}] }}}/></span>\n </$list>\n </$list>\n </div>\n <!-- 安装按钮 -->\n <div class=\"tc-plugin-info-chunk tc-plugin-info-buttons\">\n <$macrocall $name=\"install-plugin-button\" plugin=<<title>> libraryVersion=<<version>> installedVersion=<<installedVersion>> />\n </div>\n</div>\n<!-- 详情 -->\n<$list filter=\"[<popup-state>field:text[yes]]\">\n<div class=\"tc-plugin-info-dropdown\">\n <!-- 错误提示 -->\n <$list filter=\"[<detailJsonStateTitle>is[tiddler]!field:text[yes]]\">\n <div style=\"background:#e91e3db0;color:white;padding:2px 6px;margin:3px 0;border-radius:2px;backdrop-filter:blur(4px);min-height:100px;display:flex;align-items:center;justify-content:center;\">\n <$text text={{{ [<chinese>match[yes]then[出现了一些问题]else[Some errors occured]] }}}/>: <$text text={{!!text}}/>\n <$text text={{{ [<chinese>match[yes]then[请尝试刷新]else[Please try refreshing]] }}}/>\n </div>\n </$list>\n <!-- 加载中提示 -->\n <$list filter=\"[<detailJsonStateTitle>is[tiddler]field:text[yes]]\">\n <div style=\"background:#0005;color:#aaa;padding:2px 6px;margin:3px 0;border-radius:2px;backdrop-filter:blur(4px);min-height:100px;display:flex;align-items:center;justify-content:center;\">\n <$text text={{{ [<chinese>match[yes]then[加载中...]else[Loading...]] }}}/>\n </div>\n </$list>\n <!-- 插件详情 -->\n <$list filter=\"[<detailJsonStateTitle>!is[tiddler]]\" veriable=\"t\">\n <$let json={{{ [<detailJsonTitle>get[text]] }}}>\n <$let\n title={{{ [<json>jsonget[title]] }}}\n readme={{{ [<json>jsonget[readme]] }}}\n parent-plugin={{{ [<json>jsonget[parent-plugin]] }}}\n dependents={{{ [<json>jsonget[dependents]] }}}\n latest={{{ [<json>jsonget[latest]] }}}\n author={{{ [<json>jsonget[author]] }}}\n suggestions={{{ [<json>jsonget[suggestions]] }}}\n >\n <!-- 依赖 -->\n <$list filter=\"[enlist<dependents>!is[blank]] [<parent-plugin>!is[blank]] +[limit[1]] ~[<title>!is[tiddler]]\" variable=\"ignore\">\n <div style=\"background:#e91e3db0;color:white;padding:6px;\" class=\"cpl-plugin-dependencies\">\n <$list filter=\"[<title>!is[tiddler]]\">{{$:/language/ControlPanel/Plugins/NotInstalled/Hint}}</$list>\n <$list filter=\"[enlist<dependents>!is[blank]] [<parent-plugin>!is[blank]] +[limit[1]]\" variable=\"ignore\">\n <div>\n {{$:/language/ControlPanel/Plugins/AlsoRequires}} \n <$list filter=\"[enlist<dependents>] [<parent-plugin>] +[unique[]sort[name]!is[blank]]\" variable=\"dependency\">\n <span style=\"border-radius:12px;padding:3px 8px;background:#1c3b40c2;font-size:12px;line-height:24px\"><$text text=<<dependency>>/></span> \n </$list>\n </div>\n </$list>\n </div>\n </$list>\n <!-- 历史版本 -->\n <$list filter=\"[<json>jsonget[versions]count[]compare:integer:gt[1]]\" variable=\"t\">\n <details class=\"more-versions-details\">\n <summary style=\"background:#246b84;padding:4px 10px;cursor:pointer;user-select:none;\">\n <$text text={{{ [<chinese>match[yes]then[浏览其他历史版本]else[Browse older versions]] }}}/>\n </summary>\n <$list filter=\"[<json>jsonget[versions]reverse[]]\" variable=\"version\">\n <div style=\"background:#1a4655;padding:4px 12px;display:flex;flex-direction:row;align-items:center;justify-content:space-between;border-top:1px solid #15333c;\">\n <span>\n <<version>>\n <span style=\"opacity: 0.8;\"> (<$macrocall $name=\"plugin-size\" size={{{ [<json>jsonget[versions-size],<version>else[0]] }}} />)</span>\n <$list filter=\"[<latest>compare:version:eq<version>]\"> <span class=\"cpl-latest-version-icon\">{{$:/core/images/star-filled}}</span></$list>\n <$list filter=\"[<installedVersion>compare:version:eq<version>]\"> <span class=\"cpl-installed-version-icon\">{{$:/core/images/done-button}}</span></$list>\n </span>\n <div style=\"font-size:0.8em;line-height:1.2;\"><$macrocall $name=\"install-plugin-button\" plugin=<<title>> libraryVersion=<<version>> installedVersion=<<installedVersion>> /></div>\n </div>\n </$list>\n </details>\n </$list>\n <!-- 正文 -->\n <div class=\"tc-plugin-info-dropdown-body\">\n <$wikify name=\"rendered\" text=<<readme>> output=\"html\"><<rendered>></$wikify>\n </div>\n <!-- 推荐 -->\n <$list filter=\"[<__show-suggestion__>match[yes]]\" variable=\"t\">\n <div style=\"padding:10px 20px;backdrop-filter:contrast(1.1);\">\n <!-- 作者的其他插件 -->\n <$list filter=\"[{$:/temp/CPL-Repo/authors}jsonget<author>count[]compare:integer:gt[1]]\" variable=\"t\">\n <details>\n <summary style=\"padding:10px 0;\">\n <$text text={{{ [<chinese>match[yes]then[作者的其他插件]else[Other plugins of Author]] }}} />\n </summary>\n <div style=\"padding:6px;display:flex;flex-direction:column;\">\n <$list filter=\"[{$:/temp/CPL-Repo/authors}jsonget<author>] -[<title>]\" variable=\"plugin\">\n <$macrocall\n $name=\"plugin-list-item\"\n json={{{ [{$:/temp/CPL-Repo/plugins-index}jsonextract<plugin>] }}}\n field=\"$field$-author-suggestion\"\n show-suggestion=\"no\"\n class=\"cpl-plugin-info-box\"\n />\n </$list>\n </div>\n </details>\n </$list>\n <!-- 插件推荐 -->\n <$list filter=\"[enlist<suggestions>count[]compare:integer:gt[1]]\" variable=\"t\">\n <details>\n <summary style=\"padding:10px 0;\">\n <$text text={{{ [<chinese>match[yes]then[你可能感兴趣的插件]else[Plugins you may be interested in]] }}} />\n </summary>\n <div style=\"padding:6px;display:flex;flex-direction:column;\">\n <$list filter=\"[enlist<suggestions>]\" variable=\"plugin\">\n <$macrocall\n $name=\"plugin-list-item\"\n json={{{ [{$:/temp/CPL-Repo/plugins-index}jsonextract<plugin>] }}}\n field=\"$field$-author-suggestion\"\n show-suggestion=\"no\"\n class=\"cpl-plugin-info-box\"\n />\n </$list>\n </div>\n </details>\n </$list>\n </div>\n </$list>\n </$let>\n </$let>\n </$list>\n</div>\n</$list>\n</$let>\n</$let>\n</$let>\n</div>\n</$list>\n\\end"},"$:/plugins/Gk0Wk/CPL-Repo/plugin-size":{"title":"$:/plugins/Gk0Wk/CPL-Repo/plugin-size","code-body":"yes","tags":[],"type":"text/vnd.tiddlywiki","text":"\\define plugin-size(size:\"0\")\n<$list filter=\"[<__size__>compare:integer:gt[0]]\" variable=\"size\" emptyMessage=\"?\">\n<$let unit-step={{{ [<size>compare:integer:gteq[1048576]] :then[<size>compare:integer:gteq[1073741824]then[GiB#1073741824]else[MiB#1048576]] :else[<size>compare:integer:gteq[1024]then[KiB#1024]else[B#1]] }}}>\n<$let unit={{{ [<unit-step>split[#]first[]] }}} step={{{ [<unit-step>split[#]last[]] }}}>\n<$text text={{{ [<size>divide<step>fixed[2]] [<unit>] +[join[ ]] }}}/>\n</$let>\n</$let>\n</$list>\n\\end"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Beautify":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Beautify","text":"美化"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Developing":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Developing","text":"开发工具"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Fun":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Fun","text":"趣味"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Functional":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Functional","text":"功能性"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Language":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Language","text":"多语言"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Showcase":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Showcase","text":"演示"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Unknown":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Unknown","text":"未分类"},"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Visualization":{"title":"$:/plugins/Gk0Wk/CPL-Repo/PluginCategory/Visualization","text":"可视化"},"$:/plugins/Gk0Wk/CPL-Repo/popup-readme":{"title":"$:/plugins/Gk0Wk/CPL-Repo/popup-readme","subtitle":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[CPL 使用须知]else[Note to use CPL]] }}}/>","tags":[],"type":"text/vnd.tiddlywiki","text":"<$checkbox\n tiddler=\"$:/plugins/Gk0Wk/CPL-Repo/config/popup-readme-at-startup\"\n field=\"text\"\n checked={{$:/plugins/Gk0Wk/CPL-Repo/config/popup-readme-at-startup-threshold}}\n unchecked=\"0\"\n default=\"0\">\n <$text text={{{ [<chinese>match[yes]then[不再弹出该消息]else[No longer pops up this message]] }}}/>\n</$checkbox>\n\n{{$:/plugins/Gk0Wk/CPL-Repo/readme}}\n\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n\n<$list filter=\"[<chinese>match[yes]]\">\n\nCPL 的各项功能需要连接互联网、从插件数据库的静态资源网站下载 JSON 文件来实现。CPL 只会从网站上下载数据,不会将你的数据上传。\n\n未来 CPL 可能添加插件投票和下载量统计功能,如添加这些功能,会先征得你的同意。你将来可以随时关闭这类功能。\n\n你可以在这里查看 CPL 插件的逻辑代码: [[$:/plugins/Gk0Wk/CPL-Repo/core.js]]\n\nCPL 当前尚未开启自动更新检测功能,如需开启,请手动前往设置页面启动:<$button>设置<$action-sendmessage $message=\"tm-modal\" $param=\"$:/plugins/Gk0Wk/CPL-Repo/settings\" /></$button>\n\n</$list>\n\n<$list filter=\"[<chinese>match[no]]\">\n\nThe functions of the CPL require an Internet connection to download JSON files from the plug-in database's static resource site for implementation. The CPL will only download data from the site, it will not upload your data.\n\nIn the future, CPL may add plugin polling and download statistics, and will ask for your permission to add these features. You can disable these features at any time in the future.\n\nYou can view the logic code of the CPL plugin here: [[$:/plugins/Gk0Wk/CPL-Repo/core.js]]\n\nCPL has not yet enabled the automatic update detection function, if you want to enable it, please go to the settings page manually to start it: <$button>Settings<$action-sendmessage $message=\"tm-modal\" $param=\"$:/plugins/Gk0Wk/CPL-Repo/settings\" /></$button>\n\n</$list>\n\n</$list>\n"},"$:/plugins/Gk0Wk/CPL-Repo/popup-readme-at-startup":{"title":"$:/plugins/Gk0Wk/CPL-Repo/popup-readme-at-startup","code-body":"yes","tags":["$:/tags/StartupAction/PostRender"],"type":"text/vnd.tiddlywiki","text":"<$list filter=\"[{$:/plugins/Gk0Wk/CPL-Repo/config/popup-readme-at-startup}!is[blank]else[0]compare:integer:lt{$:/plugins/Gk0Wk/CPL-Repo/config/popup-readme-at-startup-threshold}]\">\n<$action-sendmessage $message=\"tm-modal\" $param=\"$:/plugins/Gk0Wk/CPL-Repo/popup-readme\" />\n</$list>"},"$:/plugins/Gk0Wk/CPL-Repo/readme":{"title":"$:/plugins/Gk0Wk/CPL-Repo/readme","tags":[],"type":"text/vnd.tiddlywiki","text":"<div style=\"display:flex;justify-content:center;\">\n{{$:/plugins/Gk0Wk/CPL-Repo/about-banner}}\n</div>\n\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n\n<$list filter=\"[<chinese>match[yes]]\">\n\n> 好用到哭,装就完了!\n\n!! 欢迎使用 CPL!\n\n使用 TW 这么久,你还在为四处寻觅好用的插件而发愁吗?还在为管理一大堆插件的更新、处理插件的依赖而苦恼吗?你还在为查找插件的用法而翻遍全网吗?你是否希望安装一个插件的某个历史版本,而非最新版本?\n\n如果你是插件的作者,你是否还在苦恼如何推广自己的插件,如何让用户及时获得最新的版本呢?\n\n你是否希望 TW 能像其他现代笔记软件一样,能够一键管理所有插件,能够更傻瓜化地查找和安装插件,甚至主动为你推广插件。是否希望 TW 能够帮助你自动保持插件的最新?\n\n这一切,在 CPL 得以实现!\n\n---\n\nCPL 是由[[太微(TiddlyWiki)中文社区|https://github.com/tiddly-gittly]]维护的、致力于搜集网络上所有与 <$text text={{{ TiddlyWiki5 }}}/> 有关插件的、希望为中国以及全世界的太微用户提供一键安装、更新插件体验的插件聚合中心。\n\n本插件有如下特点:\n\n* 聚合各种 TW 插件并保持最新当前 500+;\n* 在你的 Wiki 中搜索各种插件,提供关键词、分类和标签搜索;\n* 自动检查插件更新;\n* 安装插件时可自动递归安装依赖,并可以指定所有插件的安装版本;\n\n</$list>\n\n<$list filter=\"[<chinese>match[no]]\">\n\n> Just install it! I think you need it.\n\n!! Welcome to CPL!\n\nAfter using TW for so long, are you still worried about looking around for good plugins? Are you still struggling to manage a bunch of plugin updates and deal with plugin dependencies? Are you still searching the web to find out how to use a plugin? Do you want to install some historical version of a plugin instead of the latest version?\n\nIf you are a plugin author, do you still struggle with how to promote your plugin and how to keep users up to date with the latest version?\n\nDo you wish TW could manage all your plugins with one click like other modern note-taking software, make it more foolproof to find and install plugins, and even proactively promote plugins for you? Do you want TW to help you keep your plugins up-to-date automatically?\n\nIt's all here at CPL!\n\n---\n\nThis plugin source is maintained by the [[TiddlyWiki Chinese Community|https://github.com/tiddly-gittly]] and is dedicated to collecting all <$text text={{{ TiddlyWiki5 }}}/> related plugins on the web, hoping to provide a one-click installation and update plugin experience for TW users all around the world.\n\nThis plugin has the following features:\n\n* Aggregate various TW plugins and keep them up-to-date with the current 500+;.\n* Search for various plugins in your Wiki, providing keyword, category and tag search;.\n* Check for plugin updates automatically;\n* Install plugins with automatic recursive installation of dependencies, and you can specify the installed version of all plugins;\n\n</$list>\n\n</$list>"},"$:/plugins/Gk0Wk/CPL-Repo/settings":{"title":"$:/plugins/Gk0Wk/CPL-Repo/settings","caption":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[设置]else[Settings]] }}}/>","subtitle":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[CPL 设置]else[CPL Settings]] }}}/>","tags":[],"type":"text/vnd.tiddlywiki","text":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n\n<$list filter=\"[<chinese>match[yes]]\">\n\n在该页面内您可以对 CPL 插件的行为进行设定。\n\n; CPL 数据库镜像入口 <$select tiddler=\"$:/plugins/Gk0Wk/CPL-Repo/config/current-repo\" field=\"text\">\n<$list filter=\"[{$:/plugins/Gk0Wk/CPL-Repo/config/repos}enlist-input[]]\" variable=\"repo\">\n<option value=<<repo>>><$text text=<<repo>>/></option>\n</$list>\n</$select>\n\n<<<\n当 CPL 获取数据经常失败时,你可以尝试切换到其他镜像,目前国内推荐使用 netlify 镜像,\n\n欢迎各位大佬部署国内镜像,详情请咨询QQ交流群或在[[GitHub Issue|https://github.com/tiddly-gittly/TiddlyWiki-CPL/issues]]提问\n\n你可以手动更改数据库镜像入口:[[$:/plugins/Gk0Wk/CPL-Repo/config/current-repo]]\n<<<\n\n; 自动更新检查间隔 <$edit-text tiddler=\"$:/plugins/Gk0Wk/CPL-Repo/config/auto-update-intervals-minutes\" tag=\"input\" default=\"-1\" /> (分钟/次)\n\n<<<\n自动更新检查会在 Wiki 刚打开时进行,并每隔指定间隔进行一次检查\n\n显然自动检查需要联网,每次所消耗的流量很小,大概10KB。如果发现有插件可以更新会在右上角弹窗提醒。\n\n当值小于等于0,则关闭自动更新,也包括刚打开 Wiki 的那一次。\n\n关闭后可以手动在 [[$:/ControlPanel]] 的 [CPL] 中进行检查。\n<<<\n\n; 插件更新筛选器 <$edit-text tiddler=\"$:/plugins/Gk0Wk/CPL-Repo/config/update-filter\" tag=\"input\" default=\"\" />\n\n<<<\n插件更新是有选择的,你可以通过修改筛选器来排除一些插件。\n<<<\n\n</$list>\n\n<$list filter=\"[<chinese>match[no]]\">\n\nIn this page you can set the behavior of the CPL plugin.\n\n; CPL Database Mirror Entry <$select tiddler=\"$:/plugins/Gk0Wk/CPL-Repo/config/current-repo\" field=\"text\">\n<$list filter=\"[{$:/plugins/Gk0Wk/CPL-Repo/config/repos}enlist-input[]]\" variable=\"repo\">\n<option value=<<repo>>><$text text=<<repo>>/></option>\n</$list>\n</$select>\n\n<<<\nWhen the CPL fails to fetch the data often, you can try to switch to another mirror.\n\nIf you'd like to deploy your own mirrors, feel free to ask questions in the [[GitHub Issue|https://github.com/tiddly-gittly/TiddlyWiki-CPL/issues]]!\n\nYou can manually change the database mirror entry: [[$:/plugins/Gk0Wk/CPL-Repo/config/current-repo]]\n<<<\n\n; Automatic update of check intervals <$edit-text tiddler=\"$:/plugins/Gk0Wk/CPL-Repo/config/auto-update-intervals-minutes\" tag=\"input\" default=\"-1\" /> (minute(s) per time)\n\n<<<\nThe automatic update check is performed when the Wiki is first opened, and at specified intervals\n\nObviously auto-checking requires an internet connection and consumes very little traffic each time, about 10KB. If a plugin is found to be updatable, a pop-up window will alert you in the upper right corner.\n\nWhen the value is less than or equal to 0, auto-update is turned off, also when the Wiki is just opened.\n\nAfter closing it can be checked manually in [CPL] of [[$:/ControlPanel]].\n<<<\n\n; Plugin Update Filter <$edit-text tiddler=\"$:/plugins/Gk0Wk/CPL-Repo/config/update-filter\" tag=\"input\" default=\"\" />\n\n<<<\nPlugin updates are selective and you can exclude some plugins by modifying the filter.\n<<<\n\n</$list>\n\n</$list>\n"},"$:/plugins/Gk0Wk/CPL-Repo/style.css":{"title":"$:/plugins/Gk0Wk/CPL-Repo/style.css","tags":["$:/tags/Stylesheet"],"type":"text/vnd.tiddlywiki","text":".cpl-plugin-info-box {\n overflow: hidden;\n border: 1px solid <<colour tiddler-info-border>>;\n background-color: <<colour tiddler-info-background>>;\n}\n.cpl-plugin-dependencies {\n border-left: 0.8px solid <<colour tiddler-info-border>>;\n border-right: 0.8px solid <<colour tiddler-info-border>>;\n}\n\n.cpl-plugin-info-box > .tc-plugin-info {\n margin: 0 !important;\n border: none !important;\n}\n\n.cpl-plugin-info-box > .tc-plugin-info-dropdown {\n margin-top: 0 !important;\n border: none !important;\n}\n\n.cpl-plugin-info-box > .tc-plugin-info-dropdown,\n.cpl-plugin-info-box > .tc-plugin-info-dropdown > .tc-plugin-info-dropdown-message,\n.cpl-plugin-info-box > .tc-plugin-info-dropdown > .tc-plugin-info-dropdown-body {\n background: transparent !important;\n background-color: transparent !important;\n}\n\n.cpl-plugin-info-box > .tc-plugin-info-dropdown > .tc-plugin-info-dropdown-body {\n box-shadow: inset 0 12px 12px -12px rgba(0, 0, 0, 0.3);\n}\n\n.cpl-latest-version-icon > svg, .cpl-installed-version-icon > svg {\n height: 1em;\n width: 1em;\n}\n\n.cpl-latest-version-icon > svg {\n color: #FFC107;\n fill: #FFC107;\n}\n\n.cpl-installed-version-icon > svg {\n color: #3ccb0f;\n fill: #3ccb0f;\n}\n\n.cpl-plugin-install-request-dependents-tree {\n border-left:2px dotted <<colour very-muted-foreground>>;\n background: #0002;\n}\n\n.cpl-plugin-search {\n flex-grow: 1;\n width: 0;\n margin: 0 !important;\n}\n\n.cpl-plugin-search-go {\n border-radius: 0 !important;\n margin: 0 !important;\n padding: 10px 20px !important;\n word-break: keep-all;\n}\n\n.cpl-paged-plugin-list-control {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 40px;\n border: 2px solid <<colour tiddler-info-border>>;\n background-color: <<colour tiddler-info-background>>;\n}\n\n.cpl-paged-plugin-list-control > div {\n flex-grow: 1;\n width: 0;\n height: 100%;\n}\n\n.cpl-paged-plugin-list-control > div > button {\n width: 100%;\n height: 100%;\n border: none !important;\n background: transparent !important;\n cursor: pointer !important;\n}\n\n.cpl-paged-plugin-list-control > div > button:hover {\n backdrop-filter: contrast(0.75);\n}\n\n.cpl-paged-plugin-list-control > span {\n padding: 0 10px;\n height: 100%;\n display: flex;\n align-items: center;\n user-select: none;\n}\n\n.cpl-banner-button-group svg {\n height: 1em;\n width: 1em;\n}"},"$:/plugins/Gk0Wk/CPL-Repo/tags-gallery":{"title":"$:/plugins/Gk0Wk/CPL-Repo/tags-gallery","caption":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[标签]else[Tags]] }}} />","tags":[],"type":"text/vnd.tiddlywiki","text":"\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-list-item\n\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-size\n\\import $:/plugins/Gk0Wk/CPL-Repo/paged-plugin-list\n\n\\define tag-plain(text:\"\",icon:\"\",color:\"\",bg:\"\")\n\\whitespace trim\n<span class=\"tc-tag-label\" style=\"background-color:$bg$;color:$color$;fill:$color$;user-select:none;margin-right:6px;\">\n\t{{$icon$}}$text$\n</span>\n\\end\n\n\\define tag-plain-removable(saveTiddler,saveField:\"tags\",text:\"\",icon:\"\",color:\"\",bg:\"\")\n\\whitespace trim\n<span class=\"tc-tag-label\" style=\"background-color:$bg$;color:$color$;fill:$color$;user-select:none;margin:4px 6px 2px 0;padding:4px 10px;\">\n\t{{$icon$}}$text$\n\t<$button class=\"tc-btn-invisible tc-remove-tag-button\" style=\"background-color:$bg$;color:$color$;fill:$color$;\">\n\t\t<$action-listops $tiddler=<<__saveTiddler__>> $field=<<__saveField__>> $subfilter=\"-[<__text__>]\"/>{{$:/core/images/close-button}}\n\t</$button>\n</span>\n\\end\n\n<$let bg={{{ [{$:/palette}getindex[tag-background]] }}} color={{{ [{$:/palette}getindex[foreground]] }}} saveTiddler=\"$:/temp/CPL-Repo/search-tag-input\">\n<!-- 展示待检索的标签,以及搜索按钮 -->\n<div style=\"width:100%;display:flex;backdrop-filter:contrast(1.3);\">\n <div class=\"cpl-search-tags\" style=\"flex-grow:1;width:0;display:flex;align-items:center;padding:4px 8px;flex-wrap:wrap;\">\n <!-- 已有的标签,可删除 -->\n <$list filter=\"[<saveTiddler>get[text]enlist-input[]]\" variable=\"tag\">\n <$macrocall $name=\"tag-plain-removable\" text=<<tag>> icon=\"$:/core/images/tag-button\" bg=<<bg>> color=<<color>> saveTiddler=<<saveTiddler>> saveField=\"text\" />\n </$list>\n <div class=\"cpl-search-tags-input\">\n <!-- 输入 -->\n <$macrocall\n $name=\"keyboard-driven-input\"\n tiddler=\"$:/temp/CPL-Repo/add-search-tag-input\"\n tag=\"input\"\n placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}}\n focusPopup=\"$:/temp/CPL-Repo/add-search-tag-popup\"\n class=\"tc-edit-texteditor tc-popup-handle\"\n tabindex=<<tabIndex>>\n focus=\"yes\"\n filterMinLength=\"2\"\n configTiddlerFilter=\"[[$:/core/macros/tag-picker]]\"\n />\n <!-- 弹出 -->\n <$reveal state=\"$:/temp/CPL-Repo/add-search-tag-popup\" type=\"nomatch\" text=\"\" default=\"\">\n <div class=\"tc-block-dropdown tc-block-tags-dropdown\">\n <$list filter=\"[{$:/temp/CPL-Repo/tags}jsonget[]search{$:/temp/CPL-Repo/add-search-tag-input}]\" variable=\"tag\">\n <$button class=\"tc-btn-invisible\" tag=\"a\" tooltip={{$:/language/EditTemplate/Tags/Add/Button/Hint}}>\n <$macrocall $name=\"tag-plain\" text=<<tag>> icon=\"$:/core/images/tag-button\" bg=<<bg>> color=<<color>> />\n <$action-listops $tiddler=<<saveTiddler>> $field=\"text\" $subfilter=\"[<tag>]\"/>\n </$button>\n </$list>\n </div>\n </$reveal>\n </div>\n </div>\n <!-- 搜索按钮 -->\n <$button class=\"tc-primary-btn tc-btn-big-green cpl-plugin-search-go\" disabled={{$:/temp/CPL-Repo/searching-plugin}}>\n <$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]] :then[{$:/temp/CPL-Repo/searching-plugin}match[yes]then[搜索中...]else[搜索]] :else[{$:/temp/CPL-Repo/searching-plugin}match[yes]then[Searching...]else[Search]] }}} />\n <$action-sendmessage\n $message=\"cpl-search-plugins\"\n mode=\"tags\"\n text={{{ [<saveTiddler>get[text]] }}}\n saveTo=\"$:/temp/CPL-Repo/searchplugin-tags/result\"\n />\n </$button>\n</div>\n<$list filter=\"[[$:/temp/CPL-Repo/searching-plugin]is[tiddler]!field:text[yes]]\">\n<div style=\"background:#e91e3db0;color:white;padding:2px 6px;margin:3px 0;backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;\">\n\t<$text text={{{ [<chinese>match[yes]then[出现了一些问题]else[Some errors occured]] }}}/>: <$text text={{!!text}}/>\n</div>\n</$list>\n<$list filter=\"[[$:/temp/CPL-Repo/searchplugin-tags/result]is[tiddler]then[yes]else[no]]\" variable=\"go\">\n<!-- 有搜索结果 -->\n<$list filter=\"[<go>match[yes]]\" variable=\"t\">\n<<paged-plugin-list filter:\"[{$:/temp/CPL-Repo/searchplugin-tags/result}jsonget[]]\" field:\"tag-gallery\" class1:\"cpl-plugin-info-box\" class2:\"cpl-paged-plugin-list-control\">>\n</$list>\n<!-- 没有搜索结果,展示全部 -->\n<$list filter=\"[<go>match[no]]\" variable=\"t\">\n<<paged-plugin-list filter:\"[{$:/temp/CPL-Repo/plugins-index}jsonindexes[]!prefix[$:/language]]\" field:\"tag-gallery\" class1:\"cpl-plugin-info-box\" class2:\"cpl-paged-plugin-list-control\">>\n</$list>\n</$list>\n</$let>\n"},"$:/plugins/Gk0Wk/CPL-Repo/update-body":{"title":"$:/plugins/Gk0Wk/CPL-Repo/update-body","subtitle":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[更新列表]else[Update List]] }}}/>","tags":[],"type":"text/vnd.tiddlywiki","text":"\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-list-item\n\\import $:/plugins/Gk0Wk/CPL-Repo/plugin-size\n\\import $:/plugins/Gk0Wk/CPL-Repo/paged-plugin-list\n\n<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n<$list filter=\"[[$:/temp/CPL-Repo/update-plugins]is[tiddler]] [[$:/temp/CPL-Repo/plugins-index]is[tiddler]] +[count[]compare:integer:eq[2]then[yes]else[no]]\" variable=\"ready\">\n\n<$list filter=\"[<ready>match[yes]]\">\n<<paged-plugin-list filter:\"[{$:/temp/CPL-Repo/update-plugins}jsonget[]]\" field:\"update-list\" class1:\"cpl-plugin-info-box\" class2:\"cpl-paged-plugin-list-control\">>\n</$list>\n\n<$list filter=\"[<ready>match[no]]\">\n<!-- 错误提示 -->\n<$list filter=\"[[$:/temp/CPL-Repo/getting-plugins-index]is[tiddler]!field:text[yes]]\">\n<div style=\"background:#e91e3db0;color:white;padding:2px 6px;margin:3px 0;border-radius:2px;backdrop-filter:blur(4px);min-height:100px;display:flex;align-items:center;justify-content:center;\">\n\t<$text text={{{ [<chinese>match[yes]then[出现了一些问题]else[Some errors occured]] }}}/>: <$text text={{!!text}}/>\n\t<$text text={{{ [<chinese>match[yes]then[请尝试刷新]else[Please try refreshing]] }}}/>\n</div>\n</$list>\n<!-- 加载中提示 -->\n<$list filter=\"[[$:/temp/CPL-Repo/getting-plugins-index]is[tiddler]field:text[yes]]\">\n<div style=\"background:#0005;color:#aaa;padding:2px 6px;margin:3px 0;border-radius:2px;backdrop-filter:blur(4px);min-height:100px;display:flex;align-items:center;justify-content:center;\">\n\t<$text text={{{ [<chinese>match[yes]then[加载中...]else[Loading...]] }}}/>\n</div>\n</$list>\n</$list>\n\n</$list>\n</$list>\n"},"$:/plugins/Gk0Wk/CPL-Repo/update-manager":{"title":"$:/plugins/Gk0Wk/CPL-Repo/update-manager","caption":"<$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[更新]else[Updates]] }}} />","tags":[],"type":"text/vnd.tiddlywiki","text":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n<$button disabled={{{ [{$:/temp/CPL-Repo/getting-plugins-index}match[yes]else[no]] }}} class=\"tc-btn-big-green tc-primary-btn\">\n<$action-sendmessage $message=\"cpl-update-check\" />\n{{$:/core/images/refresh-button}}\n \n<$text text={{{ [[$:/temp/CPL-Repo/update-plugins]is[tiddler]] :then[<chinese>match[yes]then[重新获取更新]else[Refetch CPL]] :else[<chinese>match[yes]then[获取更新]else[Fetch update]] }}} />\n</$button>\n</$list>\n\n{{$:/plugins/Gk0Wk/CPL-Repo/update-body}}"},"$:/plugins/Gk0Wk/CPL-Repo/update-notify-template":{"title":"$:/plugins/Gk0Wk/CPL-Repo/update-notify-template","type":"text/vnd.tiddlywiki","text":"<$list filter=\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]\" variable=\"chinese\">\n\n<$list filter=\"[<chinese>match[yes]]\">\n\n!! CPL 更新提醒\n\n您的 Wiki 中有 <<updateCount>> 款插件在 CPL 中有更新版本, 快来更新吧!\n\n<$button>\n 更新\n <$action-sendmessage $message=\"cpl-get-plugins-index\" />\n <$action-sendmessage $message=\"tm-modal\" $param=\"$:/plugins/Gk0Wk/CPL-Repo/update-body\" />\n</$button>\n<$button>\n 设置\n <$action-sendmessage $message=\"tm-modal\" $param=\"$:/plugins/Gk0Wk/CPL-Repo/settings\" />\n</$button>\n\n</$list>\n\n<$list filter=\"[<chinese>!match[yes]]\">\n\n!! CPL Update Alert\n\nThere are <<updateCount>> plugins in your Wiki that have newer versions in CPL, so update them now!\n\n<$button>\n Update\n <$action-sendmessage $message=\"cpl-get-plugins-index\" />\n <$action-sendmessage $message=\"tm-modal\" $param=\"$:/plugins/Gk0Wk/CPL-Repo/update-body\" />\n</$button>\n<$button>\n Settings\n <$action-sendmessage $message=\"tm-modal\" $param=\"$:/plugins/Gk0Wk/CPL-Repo/settings\" />\n</$button>\n\n</$list>\n\n</$list>\n"}}} \ No newline at end of file diff --git a/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json.meta b/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json.meta index 227fed0..09a781d 100644 --- a/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json.meta +++ b/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo.json.meta @@ -1,7 +1,8 @@ author: Gk0Wk -description: Repos for CPL +description: Essential and powerful plugin manager and library +list: readme name: CPL Repo plugin-type: plugin title: $:/plugins/Gk0Wk/CPL-Repo type: application/json -version: 2022.12.28 \ No newline at end of file +version: 2023.10.11 \ No newline at end of file diff --git a/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo_install-plugin-request-model-template.tid b/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo_install-plugin-request-model-template.tid new file mode 100644 index 0000000..6c9b9f6 --- /dev/null +++ b/wiki/tiddlers/$__plugins_Gk0Wk_CPL-Repo_install-plugin-request-model-template.tid @@ -0,0 +1,126 @@ +code-body: yes +created: 20231014114531465 +modified: 20231014114532394 +subtitle: <$text text={{{ [[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[请确认安装]else[Please Confirm to Install]] }}} /> +tags: +title: $:/plugins/Gk0Wk/CPL-Repo/install-plugin-request-model-template +type: text/vnd.tiddlywiki + +\import $:/plugins/Gk0Wk/CPL-Repo/plugin-size + +\define dependents-tree(json,checked-title,versions,sizes) +<$list filter="[<__json__>jsonindexes[]]" variable="plugin"> +<div style="margin-left:1.25em;" class="cpl-plugin-install-request-dependents-tree"> +<$let install-field={{{ [[cpl-plugin#install#]addsuffix<plugin>] }}} version-field={{{ [[cpl-plugin#version#]addsuffix<plugin>] }}}> +<div style="padding:6px 8px 6px 0;display:flex;align-items:center;justify-content:space-between;"> +<span style="flex-grow:1;padding-left:1em"> + ''<$text text=<<plugin>>/>''  + <$let v={{{ [<__checked-title__>get<version-field>] }}}> + <$macrocall $name="plugin-size" size={{{ [<__sizes__>jsonget<plugin>,<v>else[0]] }}} /> + </$let> +</span> +<span> +<$checkbox tiddler=<<__checked-title__>> field=<<install-field>> checked="yes" unchecked="no" default="no"> + <$text text={{{ [<__checked-title__>get<install-field>match[yes]] :then[<chinese>match[yes]then[即将安装:]else[Will be installed:]] :else[<chinese>match[yes]then[不会安装]else[Will not be installed]] }}} /> +</$checkbox> +<$list filter="[<__checked-title__>get<install-field>match[yes]]" variable="t"> +  +<$select tiddler=<<__checked-title__>> field=<<version-field>>> +<$list filter="[<__versions__>jsonget<plugin>]" variable="version"> +<option value=<<version>>><$text text=<<version>>/></option> +</$list> +</$select> +</$list> +</span> +</div> +<$macrocall $name="dependents-tree" json={{{ [<__json__>jsonextract<plugin>] }}} checked-title=<<__checked-title__>> versions=<<__versions__>> sizes=<<__sizes__>> /> +</$let> +</div> +</$list> +\end + +<$list filter="[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]search[zh]then[yes]else[no]]" variable="chinese"> +<$let json={{{ [<requestTiddler>get[text]] }}}> + +<<< +<$let title={{{ [<json>jsonget[title]] }}}> +''<$text text={{{ [<chinese>match[yes]then[即将安装:]else[To be installed:]] }}}/>'' +<$text text=<<title>>/>    +''<$text text={{{ [<chinese>match[yes]then[选择版本:]else[Select version:]] }}}/>'' +<$select tiddler=<<requestTiddler>> field={{{ [[cpl-plugin#version#]addsuffix<title>] }}}> +<$list filter="[<json>jsonget[versions],<title>]" variable="version"> +<option value=<<version>>><$text text=<<version>>/></option> +</$list> +</$select> +</$let> +<<< + +<!-- 依赖树 --> +<$list filter="[<json>jsonextract[tree]jsonindexes[]count[]compare:integer:gt[0]]" variable="t"> +<$list filter="[<chinese>match[yes]]" variable="t"> + +这个插件有一些依赖项,在安装插件之前,将会递归地安装这些插件,如果这些插件没有被成功安装,将会回滚所有安装动作。 + +你可以自行选择安装哪些插件并选择其版本。插件依赖树如下: + +</$list> +<$list filter="[<chinese>!match[yes]]" variable="t"> + +This plugin has some dependencies that will be installed recursively before installing the plugin, and if these plugins are not installed successfully, all installation actions will be rolled back. + +It is up to you to choose which plugins to install and select their versions. The plugin dependency tree is as follows: + +</$list> +<div style="margin-left:-1em;margin-right:6px;"> + <$macrocall + $name="dependents-tree" + json={{{ [<json>jsonextract[tree]] }}} + checked-title=<<requestTiddler>> + versions={{{ [<json>jsonextract[versions]] }}} + sizes={{{ [<json>jsonextract[sizes]] }}} + /> +</div> +<hr/> +</$list> + +<$list filter="[<chinese>match[yes]]" variable="t"> + +注意:虽然 CPL 对安装失败有一定的回滚措施,但是无法避免因插件自身以及插件间相互作用所产生的潜在风险,包括但不限于 + +* 浏览器崩溃; +* Wiki 系统受损或数据丢失; +* 插件内含恶意脚本的执行造成隐私泄露或系统损坏; + +CPL [[接受恶意插件举报|https://github.com/tiddly-gittly/TiddlyWiki-CPL/issues]]并将下架这类插件,但 CPL 不能保证其中收录的所有插件均安全可用。如您在安装后出现任何问题造成损失,CPL 无法负责。 + +@@background:#e91e3db0;color:white;padding:4px;''因此,在安装任何插件前,请备份您的Wiki!''@@ + +即便如此,您依然要安装吗? + +</$list> + +<$list filter="[<chinese>!match[yes]]" variable="t"> + +Note: Although the CPL has some rollback measures for failed installations, it is not immune to the potential risks arising from the plugins themselves and from interactions between plugins, including but not limited to + +* Browser crashes; +* Damage to the Wiki system or loss of data; +* Privacy leakage or system damage caused by the execution of malicious scripts contained in the plugin; + +CPL [[accepts reports of malicious plugins|https://github.com/tiddly-gittly/TiddlyWiki-CPL/issues]] and will take down such plugins, but CPL cannot guarantee that all plugins included are safe and available. However, CPL cannot guarantee that all plugins are safe and available. CPL cannot be held responsible for any damage caused by any problem that occurs after you have installed the plugin. + +@@background:#e91e3db0;color:white;width:100%;padding:4px;''Therefore, please back up your wiki before installing any plugins!''@@ + +Even so, do you still want to install it? + +</$list> + +<$button class="tc-btn-big-green tc-primary-btn" message="tm-close-tiddler"> +<$action-sendmessage $message="cpl-install-plugin" response=<<requestTiddler>> /> +{{$:/core/images/done-button}} + +<$text text={{{ [<chinese>match[yes]then[确认安装]else[Confirm to Install]] }}} /> +</$button> + +</$let> +</$list> diff --git a/wiki/tiddlers/$__plugins_Gk0Wk_focused-tiddler.json b/wiki/tiddlers/$__plugins_Gk0Wk_focused-tiddler.json new file mode 100644 index 0000000..2016883 --- /dev/null +++ b/wiki/tiddlers/$__plugins_Gk0Wk_focused-tiddler.json @@ -0,0 +1,15 @@ +[ + { + "text": "{\"tiddlers\":{\"$:/plugins/Gk0Wk/focused-tiddler/config\":{\"title\":\"$:/plugins/Gk0Wk/focused-tiddler/config\",\"type\":\"text/vnd.tiddlywiki\",\"text\":\"<$list filter=\\\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\\\" variable=\\\"lang\\\">\\n<$list filter=\\\"[<lang>search[zh]]\\\">\\n\\n; 顶部偏移\\n: <$edit-text tiddler=\\\"$:/plugins/Gk0Wk/focused-tiddler/top-offset\\\" tag=\\\"input\\\" default=\\\"71\\\" /> (px)\\n: 条目顶部与窗口页面顶部的距离小于偏移量时,该条目会被聚焦。(单位:px)\\n\\n</$list>\\n\\n<$list filter=\\\"[<lang>!search[zh]]\\\">\\n\\n; Top Offset\\n: <$edit-text tiddler=\\\"$:/plugins/Gk0Wk/focused-tiddler/top-offset\\\" tag=\\\"input\\\" default=\\\"71\\\" /> (px)\\n: The entry is focused when the distance between the top of the entry and the top of the window page is less than the offset. (Unit: px)\\n\\n</$list>\\n</$list>\\n\"},\"$:/plugins/Gk0Wk/focused-tiddler/readme\":{\"title\":\"$:/plugins/Gk0Wk/focused-tiddler/readme\",\"type\":\"text/vnd.tiddlywiki\",\"text\":\"<$list filter=\\\"[[$:/language]get[text]removeprefix[$:/languages/]else[en-GB]]\\\" variable=\\\"lang\\\">\\n<$list filter=\\\"[<lang>search[zh]]\\\">\\n\\n! 聚焦条目\\n\\n检测你现在正在看的条目,并将其标题存在 `$:/temp/focussedTiddler`。\\n\\n判定方法:当打开新条目、滚动条目至一定位置(可配置)或者点击条目内容时,及判定为聚焦条目。\\n\\n> 本插件使用灵活而强大的 <$text text=\\\"TiddlyWiki\\\" /> 开发框架 [[Tiddly.ModernDev|https://github.com/tiddly-gittly/Modern.TiddlyDev]]\\n\\n</$list>\\n\\n<$list filter=\\\"[<lang>!search[zh]]\\\">\\n\\n! focused-tiddler\\n\\nDetecting the tiddler you are viewing, and save its title to `$:/temp/focussedTiddler`.\\n\\nJudgment method: When opening a new tiddler, scrolling the tiddler to a certain position (configurable) or clicking on the content of the tiddler, and judged to be a focused tiddler.\\n\\n> This plugin uses the flexible and powerful <$text text=\\\"TiddlyWiki\\\" /> development framework [[Tiddly.ModernDev|https://github.com/tiddly-gittly/Modern.TiddlyDev]]\\n\\n</$list>\\n</$list>\\n\"},\"$:/plugins/Gk0Wk/focused-tiddler/top-offset\":{\"title\":\"$:/plugins/Gk0Wk/focused-tiddler/top-offset\",\"text\":\"71\\n\"},\"$:/plugins/Gk0Wk/focused-tiddler/top-offset/hook.js\":{\"title\":\"$:/plugins/Gk0Wk/focused-tiddler/top-offset/hook.js\",\"module-type\":\"startup\",\"type\":\"application/javascript\",\"Modern.TiddlyDev#Origin\":\"hook.ts\",\"text\":\"\\\"use strict\\\";var __defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__export=(e,t)=>{for(var o in t)__defProp(e,o,{get:t[o],enumerable:!0})},__copyProps=(t,o,r,s)=>{if(o&&\\\"object\\\"==typeof o||\\\"function\\\"==typeof o)for(let e of __getOwnPropNames(o))__hasOwnProp.call(t,e)||e===r||__defProp(t,e,{get:()=>o[e],enumerable:!(s=__getOwnPropDesc(o,e))||s.enumerable});return t},__toCommonJS=e=>__copyProps(__defProp({},\\\"__esModule\\\",{value:!0}),e),hook_exports={},topOffset=(__export(hook_exports,{after:()=>after,name:()=>name,platforms:()=>platforms,startup:()=>startup,synchronous:()=>synchronous}),module.exports=__toCommonJS(hook_exports),71),updateTopOffset=()=>{topOffset=Number($tw.wiki.getTiddlerText(\\\"$:/plugins/Gk0Wk/focused-tiddler/top-offset\\\",\\\"71\\\").trim()),Number.isSafeInteger(topOffset)||(topOffset=71)},check=()=>{var t=document.querySelectorAll(\\\".tc-story-river .tc-tiddler-frame\\\");if(0===t.length)update(null);else{for(let e=t.length-1;0<=e;e--)if(!(100<t[e].getBoundingClientRect().top))return void update(t[e]);update(t[0])}},previousFocusedDom=null,update=e=>{var t;e!==previousFocusedDom&&(t=null!==e&&(null!=(t=e.getAttribute(\\\"data-tiddler-title\\\"))?t:null==(t=e.querySelector(\\\".tc-tiddler-title .tc-titlebar .tc-title\\\"))?void 0:t.textContent)||void 0,$tw.wiki.addTiddler({title:\\\"$:/temp/focussedTiddler\\\",text:t||\\\"\\\"}),previousFocusedDom&&$tw.utils.removeClass(previousFocusedDom,\\\"gk0wk-focused-tiddler\\\"),e&&$tw.utils.addClass(e,\\\"gk0wk-focused-tiddler\\\"),previousFocusedDom=e)},name=\\\"gk0wk-focused-tiddler\\\",platforms=[\\\"browser\\\"],after=[\\\"render\\\"],synchronous=!0,startup=()=>{updateTopOffset();let e;window.addEventListener(\\\"scroll\\\",()=>{void 0===e&&(e=setTimeout(()=>{e=void 0,check()},250))}),window.addEventListener(\\\"click\\\",({target:t})=>{var e,o;if(null!=(o=null==(e=document.querySelector(\\\".tc-story-river\\\"))?void 0:e.contains)&&o.call(e,t)){var r=document.querySelectorAll(\\\".tc-story-river .tc-tiddler-frame\\\");for(let e=r.length-1;0<=e;e--)if(r[e].contains(t))return void update(r[e])}}),$tw.wiki.addEventListener(\\\"change\\\",e=>{e[\\\"$:/plugins/Gk0Wk/focused-tiddler/top-offset\\\"]&&updateTopOffset(),(e[\\\"$:/HistoryList\\\"]||e[\\\"$:/StoryList\\\"])&&setTimeout(()=>check(),$tw.utils.getAnimationDuration()+100)})};\"}}}", + "title": "$:/plugins/Gk0Wk/focused-tiddler", + "type": "application/json", + "author": "Gk0Wk", + "dependents": "", + "description": "Detecting the tiddler you are viewing", + "list": "readme config", + "name": "Focused Tiddler", + "plugin-type": "plugin", + "version": "0.0.3", + "Modern.TiddlyDev#SHA256-Hashed": "a824f67b3fa431b7fa496185264a3cd2cdfcbce53df02f19bdad115283c88e3e" + } +] \ No newline at end of file diff --git "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json" "b/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json" deleted file mode 100644 index 57946b5..0000000 --- "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json" +++ /dev/null @@ -1,11 +0,0 @@ -{ - "title": "Draft of '图表 1'", - "text": "", - "type": "application/vnd.drawio", - "created": "20230928040603443", - "draft.of": "图表 1", - "draft.title": "图表 1", - "modified": "20230928040603445", - "revision": "0", - "bag": "default" -} \ No newline at end of file diff --git "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json.meta" "b/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json.meta" deleted file mode 100644 index ccb868b..0000000 --- "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250 1'.json.meta" +++ /dev/null @@ -1,5 +0,0 @@ -created: 20230928041037806 -modified: 20230928041037807 -tags: $:/tags/trashbin -title: $:/trashbin/Draft of '图表 1' -type: application/json \ No newline at end of file diff --git "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json" "b/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json" deleted file mode 100644 index e1defa8..0000000 --- "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json" +++ /dev/null @@ -1,11 +0,0 @@ -{ - "created": "20230928040420578", - "title": "Draft of '图表'", - "text": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" width=\"1px\" height=\"1px\" viewBox=\"-0.5 -0.5 1 1\" content=\"<mxfile host="embed.diagrams.net" modified="2023-09-28T04:22:00.619Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48" etag="j0gQ89ZAr4MVsm3KkluV" version="21.8.2" type="embed"><diagram id="9R4lw0Slr9YLJl1yey4v" name="第 1 页">ddG9DoIwEADgp+mObUScEXVxYnBu6EmbFI6UGtCnF3IgNOjSXL+79vrDRFr1FycbfUMFlvFI9UycGOcxT4ZxhBfBPt4RlM4oohXk5g0TRpM+jYI2KPSI1psmxALrGgofmHQOu7DsgTbs2sgSNpAX0m71bpTXpAk/LH4FU+q58y4+UqaSc/F0k1ZLhd2KRMZE6hA9RVWfgh3fbn4XWnf+k/0ezEHtfywYgmXvYRJ8kMg+</diagram></mxfile>\"><defs/><g/></svg>", - "type": "application/vnd.drawio", - "draft.of": "图表", - "draft.title": "图表", - "modified": "20230928042200621", - "revision": "0", - "bag": "default" -} \ No newline at end of file diff --git "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json.meta" "b/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json.meta" deleted file mode 100644 index e96ae4c..0000000 --- "a/wiki/tiddlers/$__trashbin_Draft of '\345\233\276\350\241\250'.json.meta" +++ /dev/null @@ -1,5 +0,0 @@ -created: 20230928042205350 -modified: 20230928042205351 -tags: $:/tags/trashbin -title: $:/trashbin/Draft of '图表' -type: application/json \ No newline at end of file diff --git a/wiki/tiddlers/MindMap (Elixir).tid b/wiki/tiddlers/MindMap (Elixir).tid index 330fbf4..b068f82 100644 --- a/wiki/tiddlers/MindMap (Elixir).tid +++ b/wiki/tiddlers/MindMap (Elixir).tid @@ -1,5 +1,5 @@ created: 20230614084352738 -map: {"data":{"nodeData":{"id":"8b909daff9826858","topic":"MindMap","root":true,"children":[{"topic":"A","id":"8b90bbf205015c07","direction":0,"tags":["Tag"]},{"topic":"B","id":"8b90bcd377b5c2e5","direction":1,"children":[{"topic":"1","id":"8b90c0af9b3436a1","children":[{"topic":"a","id":"8b90c2f94e5baf96"},{"topic":"b","id":"8b90c3548278997f"}],"style":{"fontWeight":"bold","color":"#f1c40e"}},{"topic":"2","id":"8b90c14613881e6f","style":{"color":"#ecf0f1","background":"#3298db"}},{"topic":"3","id":"8b90c17aa6a2fb7c"},{"topic":"4","id":"8b90c1baa39fee8d"}],"style":{"fontSize":"41"}},{"topic":"C","id":"8b90bd3664d3e5ac","direction":0,"icons":["🎉"]},{"topic":"D","id":"8b90bfcc4f169ab8","direction":1,"style":{"fontWeight":"bold"}}],"hyperLink":"https://gk0wk.github.io/TiddlySeq/"},"linkData":{},"direction":2,"theme":{"name":"Custom","palette":["#848FA0","#748BE9","#D2F9FE","#4145A5","#789AFA","#706CF4","#EF987F","#775DD5","#FCEECF","#DA7FBC"],"cssVar":{"--gap":"30px","--root-radius":"30px","--main-radius":"20px","--root-color":"#ffffff","--root-bgcolor":"#6467aa","--main-color":"#444446","--main-bgcolor":"#fafafa","--topic-padding":"5px","--color":"#ededed","--bgcolor":"#282828"}}},"options":{"draggable":true,"contextMenu":true,"toolBar":true,"nodeMenu":true,"keypress":true,"locale":"auto","overflowHidden":false,"allowUndo":false,"primaryLinkStyle":"1"}} +map: {"data":{"nodeData":{"id":"8b909daff9826858","topic":"MindMap","root":true,"children":[{"topic":"A","id":"8b90bbf205015c07","direction":0,"tags":["Tag"]},{"topic":"B","id":"8b90bcd377b5c2e5","direction":1,"children":[{"topic":"1","id":"8b90c0af9b3436a1","children":[{"topic":"a","id":"8b90c2f94e5baf96"},{"topic":"b","id":"8b90c3548278997f"}],"style":{"fontWeight":"bold","color":"#f1c40e"}},{"topic":"2","id":"8b90c14613881e6f","style":{"color":"#ecf0f1","background":"#3298db"}},{"topic":"3","id":"8b90c17aa6a2fb7c"},{"topic":"4","id":"8b90c1baa39fee8d"}],"style":{"fontSize":"41"}},{"topic":"C","id":"8b90bd3664d3e5ac","direction":0,"icons":["🎉"]},{"topic":"D","id":"8b90bfcc4f169ab8","direction":1,"style":{"fontWeight":"bold"}}],"hyperLink":"https://gk0wk.github.io/TiddlySeq/"},"linkData":{},"summaries":[],"direction":2,"theme":{"name":"Custom","palette":["#848FA0","#748BE9","#D2F9FE","#4145A5","#789AFA","#706CF4","#EF987F","#775DD5","#FCEECF","#DA7FBC"],"cssVar":{"--gap":"30px","--root-radius":"30px","--main-radius":"20px","--root-color":"#ffffff","--root-bgcolor":"#6467aa","--main-color":"#444446","--main-bgcolor":"#fafafa","--topic-padding":"5px","--color":"#ededed","--bgcolor":"#282828"}}},"options":{"draggable":true,"contextMenu":true,"toolBar":true,"nodeMenu":true,"keypress":true,"locale":"auto","overflowHidden":false,"allowUndo":false,"primaryLinkStyle":"1"}} modified: 20230614084518011 tags: ExcludeFromEmpty MyPlugins title: MindMap (Elixir)