diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json index 0e00064..eaffd30 100644 --- a/.obsidian/community-plugins.json +++ b/.obsidian/community-plugins.json @@ -3,5 +3,6 @@ "obsidian-git", "obsidian-markdown-formatting-assistant-plugin", "heading-level-indent", - "global-proxy" + "global-proxy", + "lovely-mindmap" ] \ No newline at end of file diff --git a/.obsidian/graph.json b/.obsidian/graph.json index e21a18d..42a46ec 100644 --- a/.obsidian/graph.json +++ b/.obsidian/graph.json @@ -18,5 +18,5 @@ "linkStrength": 1, "linkDistance": 250, "scale": 1, - "close": false + "close": true } \ No newline at end of file diff --git a/.obsidian/plugins/lovely-mindmap/main.js b/.obsidian/plugins/lovely-mindmap/main.js new file mode 100644 index 0000000..e767b54 --- /dev/null +++ b/.obsidian/plugins/lovely-mindmap/main.js @@ -0,0 +1,765 @@ +/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var __decorateClass = (decorators, target, key, kind) => { + var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; + for (var i = decorators.length - 1, decorator; i >= 0; i--) + if (decorator = decorators[i]) + result = (kind ? decorator(target, key, result) : decorator(result)) || result; + if (kind && result) + __defProp(target, key, result); + return result; +}; + +// src/main.ts +var main_exports = {}; +__export(main_exports, { + default: () => LovelyMindmap +}); +module.exports = __toCommonJS(main_exports); +var import_obsidian2 = require("obsidian"); + +// src/tool/index.ts +function debounce(delay = 100) { + let lastTime = 0; + let timer; + return function(target, propertyKey, descriptor) { + const originalMethod = descriptor.value; + descriptor.value = function(...args) { + const now = Date.now(); + clearTimeout(timer); + if (now - lastTime < delay) { + return; + } + timer = setTimeout(() => { + originalMethod.apply(this, args); + lastTime = 0; + }, delay); + lastTime = now; + }; + return descriptor; + }; +} +function calcDistance(a, b) { + return Math.sqrt( + (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + ); +} +function findClosestNodeByBbox(pos, nodes) { + return nodes.reduce((prev, cur, idx) => { + const a = [cur.bbox.minX, cur.bbox.minY]; + const b = [cur.bbox.maxX, cur.bbox.minY]; + const c = [cur.bbox.minX, cur.bbox.maxY]; + const d = [cur.bbox.maxX, cur.bbox.maxY]; + const distance = Math.min( + calcDistance(pos, a), + calcDistance(pos, b), + calcDistance(pos, c), + calcDistance(pos, d) + ); + if (idx === 0) { + return { + node: cur, + distance + }; + } + return distance < prev.distance ? { node: cur, distance } : prev; + }, { + node: {}, + distance: 0 + }); +} +function uuid() { + const first = Math.floor(Math.random() * 9 + 1); + const rest = String(Math.random()).slice(2, 10); + const random9 = first + rest; + return string10To64(Date.now()) + string10To64(random9); +} +function string10To64(str) { + const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + const radix = chars.length; + let num = typeof str === "string" ? parseInt(str) : str; + const res = []; + do { + const mod = num % radix; + res.push(chars[mod]); + num = (num - mod) / radix; + } while (num > 0); + return res.join(""); +} +var supportedModifiers = ["mod", "ctrl", "meta", "shift", "alt"]; +var navigationKeys = [ + "tab", + "enter", + "arrowup", + "arrowdown", + "arrowleft", + "arrowright" + /** 'backspace', 'delete', 'escape', 'space' */ +]; +function convertHotkey2Array(hotkey) { + const parts = hotkey.split("+"); + let modifier = null; + let key = null; + if (parts.length === 1) { + key = parts[0].trim(); + if (!navigationKeys.includes(key.toLocaleLowerCase()) && !/^[a-zA-Z0-9]$/.test(key)) { + throw new Error("Invalid key. Expected a single alphanumeric character or a navigation key but got " + key); + } + return [[], key]; + } else if (parts.length === 2) { + modifier = parts[0].trim(); + if (!supportedModifiers.includes(modifier.toLocaleLowerCase())) { + throw new Error(`Invalid modifier. Expected [${supportedModifiers.join(", ")}].`); + } + key = parts[1].trim(); + if (!navigationKeys.includes(key.toLocaleLowerCase()) && !/^[a-zA-Z0-9]$/.test(key)) { + throw new Error("Invalid key. Expected a single alphanumeric character or a navigation key but got " + key); + } + return [[modifier.charAt(0).toUpperCase() + modifier.slice(1)], key]; + } + throw new Error("Invalid hotkey format. Expected a single alphanumeric character or a modifier followed by a single alphanumeric character but got " + hotkey); +} + +// node_modules/autobind-decorator/lib/esm/index.js +function _typeof(obj) { + if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { + _typeof = function _typeof2(obj2) { + return typeof obj2; + }; + } else { + _typeof = function _typeof2(obj2) { + return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2; + }; + } + return _typeof(obj); +} +function boundMethod(target, key, descriptor) { + var fn = descriptor.value; + if (typeof fn !== "function") { + throw new TypeError("@boundMethod decorator can only be applied to methods not: ".concat(_typeof(fn))); + } + var definingProperty = false; + return { + configurable: true, + get: function get() { + if (definingProperty || this === target.prototype || this.hasOwnProperty(key) || typeof fn !== "function") { + return fn; + } + var boundFn = fn.bind(this); + definingProperty = true; + Object.defineProperty(this, key, { + configurable: true, + get: function get2() { + return boundFn; + }, + set: function set(value) { + fn = value; + delete this[key]; + } + }); + definingProperty = false; + return boundFn; + }, + set: function set(value) { + fn = value; + } + }; +} +function boundClass(target) { + var keys; + if (typeof Reflect !== "undefined" && typeof Reflect.ownKeys === "function") { + keys = Reflect.ownKeys(target.prototype); + } else { + keys = Object.getOwnPropertyNames(target.prototype); + if (typeof Object.getOwnPropertySymbols === "function") { + keys = keys.concat(Object.getOwnPropertySymbols(target.prototype)); + } + } + keys.forEach(function(key) { + if (key === "constructor") { + return; + } + var descriptor = Object.getOwnPropertyDescriptor(target.prototype, key); + if (typeof descriptor.value === "function") { + Object.defineProperty(target.prototype, key, boundMethod(target, key, descriptor)); + } + }); + return target; +} +function autobind() { + if (arguments.length === 1) { + return boundClass.apply(void 0, arguments); + } + return boundMethod.apply(void 0, arguments); +} + +// src/module/node.ts +var Node = class { + constructor(main) { + this.main = main; + } + getNavigationNode() { + const node = this.getSingleSelection(); + if (!node || !node.isFocused || node.isEditing) + return null; + return node; + } + getCreationNode() { + const node = this.getSingleSelection(); + if (!node || !node.isFocused || !node.isEditing) + return null; + return node; + } + getSelection() { + return this.main.canvas.selection; + } + getSingleSelection() { + const selections = this.main.canvas.selection; + if (selections.size === 0 || selections.size > 1) { + return null; + } + return selections.values().next().value; + } + getFromNodes(node) { + const fromNodeFilter = (edge) => edge.to.node.id === node.id; + return this.main.canvas.getEdgesForNode(node).filter(fromNodeFilter).map((edge) => edge.from.node); + } + getToNodes(node) { + const toNodeFilter = (edge) => edge.from.node.id === node.id; + return this.main.canvas.getEdgesForNode(node).filter(toNodeFilter).map((edge) => edge.to.node); + } + getSibNodes(target) { + const fromNodes = this.getFromNodes(target); + const toNodes = this.getToNodes(fromNodes[0]); + return toNodes.filter((node) => node.id !== target.id); + } + createChildren() { + const selection = this.getNavigationNode(); + if (!selection) + return; + const { + x, + y, + width, + height + } = selection; + const rightSideNodeFilter = (node) => { + var _a, _b, _c; + return ((_a = node == null ? void 0 : node.to) == null ? void 0 : _a.side) === "left" && selection.id !== ((_c = (_b = node == null ? void 0 : node.to) == null ? void 0 : _b.node) == null ? void 0 : _c.id); + }; + const sibNodes = this.main.canvas.getEdgesForNode(selection).filter(rightSideNodeFilter).map((node) => node.to.node); + const nextNodeY = sibNodes.length > 0 ? Math.max(...sibNodes.map((node) => node.y)) + this.main.setting.EPSILON : y; + const childNode = this.main.canvas.createTextNode({ + pos: { + x: x + width + 200, + y: nextNodeY + }, + size: { + height, + width + }, + text: "", + focus: false, + save: true + }); + const data = this.main.canvas.getData(); + this.main.canvas.importData({ + "edges": [ + ...data.edges, + { + "id": uuid(), + "fromNode": selection.id, + "fromSide": "right", + "toNode": childNode.id, + "toSide": "left" + } + ], + "nodes": data.nodes + }); + this.main.layout.useSide(selection, sibNodes.concat(childNode)); + this.main.view.zoomToNode(childNode); + } + createBeforeSibNode() { + this.createSibNodeHelper(true); + } + createAfterSibNode() { + this.createSibNodeHelper(false); + } + createSibNodeHelper(isBefore) { + const selection = this.getNavigationNode(); + if (!selection) + return; + const { + x, + y, + width, + height + } = selection; + const { EPSILON } = this.main.setting; + const fromNode = this.getFromNodes(selection)[0]; + const toNodes = this.getToNodes(fromNode); + const willInsertedNode = this.main.canvas.createTextNode({ + pos: { + x, + y: isBefore ? y - EPSILON : y + EPSILON + }, + size: { + height, + width + }, + text: "", + focus: false, + save: true + }); + const data = this.main.canvas.getData(); + this.main.canvas.importData({ + "edges": [ + ...data.edges, + { + "id": uuid(), + "fromNode": fromNode.id, + "fromSide": "right", + "toNode": willInsertedNode.id, + "toSide": "left" + } + ], + "nodes": data.nodes + }); + this.main.layout.useSide(fromNode, toNodes.concat(willInsertedNode)); + this.main.view.zoomToNode(willInsertedNode); + } +}; +__decorateClass([ + debounce() +], Node.prototype, "createChildren", 1); +__decorateClass([ + debounce() +], Node.prototype, "createBeforeSibNode", 1); +__decorateClass([ + debounce() +], Node.prototype, "createAfterSibNode", 1); +Node = __decorateClass([ + autobind +], Node); + +// src/module/keymap.ts +var Keymap = class { + constructor(main) { + this.hotkeys = []; + this.main = main; + this.node = main.node; + } + async help() { + if (this.main.view.isCreating()) + return; + console.debug("this:\n", this); + console.debug("app:\n", this.main.app); + console.debug("canvas:\n", this.main.canvas); + console.debug("selections:\n", this.main.canvas.selection.values().next()); + } + nodeNavigation(_, context) { + const { key } = context; + const selection = this.node.getSingleSelection(); + if (!selection || selection.isEditing) { + return; + } + const { OFFSET_WEIGHT } = this.main.setting; + const data = this.main.canvas.getViewportNodes(); + const offsetX = (a, b) => Math.abs(b.x - a.x); + const offsetY = (a, b) => Math.abs(b.y - a.y); + const endpointOffset = (a, b) => Math.min( + Math.abs(b.y - a.y + 2 / a.height), + Math.abs(b.y + b.height - a.y - 2 / a.height), + Math.abs(b.x - a.x + 2 / a.width), + Math.abs(b.x + b.width - a.x + 2 / a.width) + ); + const calcDistance2 = (a, b) => key === "ArrowLeft" || key === "ArrowRight" ? offsetX(a, b) + endpointOffset(a, b) ** OFFSET_WEIGHT : offsetY(a, b) + endpointOffset(a, b) ** OFFSET_WEIGHT; + const isSameDirection = (node) => { + const notSelf = node.id !== selection.id; + const strategies = { + ArrowRight: notSelf && node.x > selection.x + selection.width, + ArrowLeft: notSelf && node.x + node.width < selection.x, + ArrowUp: notSelf && node.y + node.height < selection.y, + ArrowDown: notSelf && node.y > selection.y + selection.height + }; + return strategies[key]; + }; + const midpoints = data.filter(isSameDirection).map((node) => ({ + node, + offsetX: offsetX(selection, node), + offsetY: offsetY(selection, node), + endpointOffset: endpointOffset(selection, node), + distance: calcDistance2(selection, node) + })).sort((a, b) => a.distance - b.distance); + if (midpoints.length > 0) { + this.main.view.zoomToNode(midpoints[0].node); + } + } + blurNode() { + if (this.main.view.isCreating()) { + this.main.view.creation2Navigation(); + return; + } + if (this.main.view.isNavigating()) { + this.main.view.useTouch(); + return; + } + } + focusNode() { + if (this.main.view.isTouching()) { + this.main.view.touch2Navigation(); + return; + } + const navigationNode = this.main.node.getNavigationNode(); + if (!!navigationNode) { + this.main.view.useCreation(navigationNode); + return; + } + } + register(modifiers, key, func) { + return this.main.app.scope.register(modifiers, key, func); + } + /** + * priority: options > config > default + * 1. options: function argument + * 2. config: `options.hotkeys` + * 3. default: this.register + * @param options + */ + registerAll(options) { + const { hotkeys } = this.main.setting; + const registerHotkey = (action, callback) => { + if (options == null ? void 0 : options[action]) { + this.hotkeys.push(options[action]()); + } else { + const [modifier, key] = convertHotkey2Array(hotkeys[action]); + this.hotkeys.push(this.register(modifier, key, callback)); + } + }; + registerHotkey("Focus", this.focusNode); + registerHotkey("CreateChild", this.main.node.createChildren); + registerHotkey("CreateBeforeSib", this.main.node.createBeforeSibNode); + registerHotkey("CreateAfterSib", this.main.node.createAfterSibNode); + registerHotkey("ArrowLeft", this.nodeNavigation); + registerHotkey("ArrowRight", this.nodeNavigation); + registerHotkey("ArrowUp", this.nodeNavigation); + registerHotkey("ArrowDown", this.nodeNavigation); + } + unregisterAll() { + this.hotkeys.forEach((key) => this.main.app.scope.unregister(key)); + } +}; +__decorateClass([ + debounce() +], Keymap.prototype, "help", 1); +Keymap = __decorateClass([ + autobind +], Keymap); + +// src/module/view.ts +var View = class { + constructor(main) { + this.main = main; + } + isTouching() { + return this.main.node.getSelection().size === 0; + } + isNavigating() { + const node = this.main.node.getSingleSelection(); + if (!node) + return false; + return node.isFocused && !node.isEditing; + } + isCreating() { + const node = this.main.node.getSingleSelection(); + if (!node) + return false; + return node.isFocused && node.isEditing; + } + useTouch() { + this.main.canvas.deselectAll(); + } + useCreation(node) { + setTimeout( + () => node.startEditing(), + this.main.setting.MACRO_TASK_DELAY + ); + } + creation2Navigation() { + const selection = this.main.node.getSingleSelection(); + if (!selection || !this.isCreating()) + return; + selection.blur(); + selection.focus(); + } + touch2Navigation() { + const viewportBBox = this.main.canvas.getViewportBBox(); + const centerPoint = [ + (viewportBBox.minX + viewportBBox.maxX) / 2, + (viewportBBox.minY + viewportBBox.maxY) / 2 + ]; + const viewportNodes = this.main.canvas.getViewportNodes(); + const res = findClosestNodeByBbox(centerPoint, viewportNodes); + this.zoomToNode(res.node); + } + zoomToNode(node) { + this.main.canvas.selectOnly(node); + this.main.canvas.zoomToSelection(); + if (this.main.setting.autoFocus) { + this.useCreation(node); + } + } +}; + +// src/module/setting.ts +var import_obsidian = require("obsidian"); +var DEFAULT_SETTINGS = { + autoFocus: false, + hotkeys: { + CreateChild: "Tab", + CreateBeforeSib: "Shift + Enter", + CreateAfterSib: "Enter", + Focus: "F", + ArrowUp: "Alt + ArrowUp", + ArrowDown: "Alt + ArrowDown", + ArrowLeft: "Alt + ArrowLeft", + ArrowRight: "Alt + ArrowRight" + }, + ROW_GAP: 20, + COLUMN_GAP: 200, + EPSILON: 1, + OFFSET_WEIGHT: 1.1, + MACRO_TASK_DELAY: 50 +}; +var Setting = class extends import_obsidian.PluginSettingTab { + constructor(main) { + super(main.app, main); + this.main = main; + } + display() { + const { containerEl } = this; + containerEl.empty(); + containerEl.createEl("h3", { text: "\u{1F917} Lovely Mindmap Settings" }); + this.addAutoFocus(); + this.addCreateChildHotkey(); + this.addCreateBeforeSibHotKey(); + this.addCreateAfterSibHotKey(); + } + addAutoFocus() { + new import_obsidian.Setting(this.containerEl).setName("Auto Focus").setDesc("auto focus node when create new node").addToggle( + (component) => component.setValue(this.main.setting.autoFocus).onChange(async (open) => { + this.main.setting.autoFocus = open; + await this.main.saveData(this.main.setting); + }) + ); + } + addCreateChildHotkey() { + let _hotKey = this.main.setting.hotkeys.CreateChild; + let errorText = ""; + new import_obsidian.Setting(this.containerEl).setName("Create Child Node").setDesc(`Custom your hotkey to create a child node, default is Tab. + You can use any letter, number, or modifier combined with + a letter or number, e.g., \u300CC\u300Dor\u300Ccmd + C\u300Dto create a child node. + Use\u300C+\u300Dto separate modifiers and alphanumeric characters.`).addText((text) => text.setPlaceholder("Enter hotkey").setValue(_hotKey).onChange(async (value) => { + _hotKey = value; + errorText = ""; + })).addButton( + (button) => button.setButtonText("Save").setCta().onClick(async () => { + if (errorText) { + new import_obsidian.Notice(errorText); + return; + } + try { + const [modifier, key] = convertHotkey2Array(_hotKey); + this.main.setting.hotkeys.CreateChild = _hotKey; + await this.main.saveData(this.main.setting); + this.main.keymap.unregisterAll(); + this.main.keymap.registerAll({ + CreateChild: () => this.main.keymap.register(modifier, key, this.main.node.createChildren) + }); + new import_obsidian.Notice("Save successfully!"); + } catch (error) { + new import_obsidian.Notice(error.message); + } + }) + ); + } + addCreateBeforeSibHotKey() { + let _hotKey = this.main.setting.hotkeys.CreateBeforeSib || "Shift+Enter"; + let errorText = ""; + new import_obsidian.Setting(this.containerEl).setName("Create Sibling Node Before").setDesc(`Custom your hotkey to create a sibling node before the current node. Default is Shift+Enter. Same as 'Create Child Node'.`).addText((text) => text.setPlaceholder("Enter hotkey").setValue(_hotKey).onChange(async (value) => { + _hotKey = value; + errorText = ""; + })).addButton( + (button) => button.setButtonText("Save").setCta().onClick(async () => { + if (errorText) { + new import_obsidian.Notice(errorText); + return; + } + try { + const [modifier, key] = convertHotkey2Array(_hotKey); + this.main.setting.hotkeys.CreateBeforeSib = _hotKey; + await this.main.saveData(this.main.setting); + this.main.keymap.unregisterAll(); + this.main.keymap.registerAll({ + CreateBeforeSib: () => this.main.keymap.register(modifier, key, this.main.node.createBeforeSibNode) + }); + new import_obsidian.Notice("Save successfully!"); + } catch (error) { + new import_obsidian.Notice(error.message); + } + }) + ); + } + addCreateAfterSibHotKey() { + let _hotKey = this.main.setting.hotkeys.CreateAfterSib || "Enter"; + let errorText = ""; + new import_obsidian.Setting(this.containerEl).setName("Create Sibling Node After").setDesc(`Custom your hotkey to create a sibling node after the current node. Default is Enter. Same as 'Create Child Node'.`).addText((text) => text.setPlaceholder("Enter hotkey").setValue(_hotKey).onChange(async (value) => { + _hotKey = value; + errorText = ""; + })).addButton( + (button) => button.setButtonText("Save").setCta().onClick(async () => { + if (errorText) { + new import_obsidian.Notice(errorText); + return; + } + try { + const [modifier, key] = convertHotkey2Array(_hotKey); + this.main.setting.hotkeys.CreateAfterSib = _hotKey; + await this.main.saveData(this.main.setting); + this.main.keymap.unregisterAll(); + this.main.keymap.registerAll({ + CreateAfterSib: () => this.main.keymap.register(modifier, key, this.main.node.createAfterSibNode) + }); + new import_obsidian.Notice("Save successfully!"); + } catch (error) { + new import_obsidian.Notice(error.message); + } + }) + ); + } + async loadSettings() { + this.main.setting = { ...DEFAULT_SETTINGS, ...await this.main.loadData() }; + } +}; + +// src/module/layout.ts +var Layout = class { + constructor(main) { + this.main = main; + } + useSide(parent, child) { + const { ROW_GAP, COLUMN_GAP } = this.main.setting; + const bbox = child.reduce((prev, node, idx) => { + return idx > 0 ? { + height: prev.height + node.height + ROW_GAP, + heightNodes: prev.heightNodes.concat(node.height) + } : { + height: prev.height + node.height, + heightNodes: prev.heightNodes.concat(node.height) + }; + }, { + height: 0, + heightNodes: [] + }); + const top = parent.y + parent.height * 0.5 - bbox.height * 0.5; + const getSum = (arr) => arr.reduce((sum, cur) => sum + cur, 0); + child.sort((a, b) => a.y - b.y).forEach((node, i) => { + node.moveTo({ + x: parent.width + parent.x + COLUMN_GAP, + y: top + ROW_GAP * i + getSum(bbox.heightNodes.slice(0, i)) + }); + }); + } + useSurround() { + } +}; + +// src/main.ts +var LovelyMindmap = class extends import_obsidian2.Plugin { + constructor(app2, manifest) { + super(app2, manifest); + this.canvas = null; + this.intervalTimer = /* @__PURE__ */ new Map(); + this.node = new Node(this); + this.keymap = new Keymap(this); + this.view = new View(this); + this.setting = new Setting(this); + this.layout = new Layout(this); + } + createCanvasInstance() { + const timer = setInterval(() => { + var _a, _b; + this.canvas = (_b = (_a = app.workspace.getLeavesOfType("canvas").first()) == null ? void 0 : _a.view) == null ? void 0 : _b.canvas; + if (!!this.canvas) { + clearInterval(this.intervalTimer.get("canvas")); + } + }, 100); + if (!this.intervalTimer.get("canvas")) { + this.intervalTimer.set("canvas", timer); + } + } + onActiveLeafChange() { + this.app.workspace.on("active-leaf-change", async (leaf) => { + var _a, _b; + const extension = (_b = (_a = leaf == null ? void 0 : leaf.view) == null ? void 0 : _a.file) == null ? void 0 : _b.extension; + if (extension === "canvas") { + this.onKeymap(); + return; + } + this.onunload(); + }); + } + /** + * A series of events for canvas initialization + * + * - When switching away from the canvas viewport, remove the keyboard shortcuts and canvas instance. + * - When switching back to the canvas viewport, re-register the keyboard shortcuts and canvas instance. + */ + onKeymap() { + this.createCanvasInstance(); + this.keymap.registerAll(); + this.addCommand({ + id: "blurNode", + name: "Blur node", + hotkeys: [ + { + modifiers: ["Mod"], + key: "Escape" + } + ], + checkCallback: () => this.keymap.blurNode() + }); + } + async onload() { + await this.setting.loadSettings(); + this.addSettingTab(new Setting(this)); + this.onActiveLeafChange(); + this.onKeymap(); + } + onunload() { + this.keymap.unregisterAll(); + this.intervalTimer.forEach(clearInterval); + } +}; + +/* nosourcemap */ \ No newline at end of file diff --git a/.obsidian/plugins/lovely-mindmap/manifest.json b/.obsidian/plugins/lovely-mindmap/manifest.json new file mode 100644 index 0000000..36f8a1f --- /dev/null +++ b/.obsidian/plugins/lovely-mindmap/manifest.json @@ -0,0 +1,15 @@ +{ + "id": "lovely-mindmap", + "name": "Lovely-Mindmap", + "version": "1.0.4", + "minAppVersion": "0.15.0", + "description": "Build your own knowledge graph with smiles :-)", + "author": "shaun", + "authorUrl": "https://github.com/xincan1949", + "fundingUrl": { + "By Me a Coffee": "https://www.buymeacoffee.com/xincan1949", + "支付宝": "https://cdn.jsdelivr.net/gh/xincan1949/xincan1949.github.io@master/Alipay.jpeg", + "微信": "https://cdn.jsdelivr.net/gh/xincan1949/xincan1949.github.io@master/WeChatPay.png" + }, + "isDesktopOnly": false +} diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 2468437..6148676 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -4,21 +4,24 @@ "type": "split", "children": [ { - "id": "c0444def8ff3cca9", + "id": "1264f9922b3f4518", "type": "tabs", "children": [ { - "id": "696f0fc9c13f8fbb", + "id": "86a6b4067288b6c1", "type": "leaf", "state": { - "type": "markdown", + "type": "canvas", "state": { - "file": "公司/座椅调节模块/需求整理.md", - "mode": "source", - "source": false + "file": "家里/宝宝/需要准备的东西.canvas", + "viewState": { + "x": 633.1666259765625, + "y": 82, + "zoom": 0 + } }, - "icon": "lucide-file", - "title": "需求整理" + "icon": "lucide-layout-dashboard", + "title": "需要准备的东西" } } ] @@ -139,10 +142,10 @@ "state": { "type": "outline", "state": { - "file": "公司/座椅调节模块/需求整理.md" + "file": "家里/宝宝/需要准备的东西.canvas" }, "icon": "lucide-list", - "title": "需求整理 的大纲" + "title": "需要准备的东西 的大纲" } }, { @@ -166,11 +169,11 @@ } } ], - "currentTab": 3 + "currentTab": 4 } ], "direction": "horizontal", - "width": 326.5 + "width": 336.5 }, "left-ribbon": { "hiddenItems": { @@ -184,11 +187,15 @@ "obsidian-markdown-formatting-assistant-plugin:Open Markdown Formatting Assistant": false } }, - "active": "696f0fc9c13f8fbb", + "active": "86a6b4067288b6c1", "lastOpenFiles": [ + "家里/宝宝/需要准备的东西.canvas", + "家里/宝宝/未命名.md", + "家里/宝宝", + "家里", + "公司/座椅调节模块/需求整理.md", "daily", "未命名.canvas", - "公司/座椅调节模块/需求整理.md", "未命名 1.canvas", "日记", "Pasted image 20241106105842.png", diff --git a/家里/宝宝/需要准备的东西.canvas b/家里/宝宝/需要准备的东西.canvas new file mode 100644 index 0000000..386262f --- /dev/null +++ b/家里/宝宝/需要准备的东西.canvas @@ -0,0 +1,6 @@ +{ + "nodes":[ + {"id":"6a447c433bad6e8f","type":"text","text":"","x":-108,"y":136,"width":250,"height":60} + ], + "edges":[] +} \ No newline at end of file