├── .obsidian ├── app.json ├── appearance.json ├── community-plugins.json ├── core-plugins.json ├── graph.json ├── hotkeys.json ├── plugins │ ├── calendar │ │ ├── data.json │ │ ├── main.js │ │ └── manifest.json │ ├── hotkeysplus-obsidian │ │ ├── main.js │ │ └── manifest.json │ ├── maximise-active-pane-obsidian │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── nldates-obsidian │ │ ├── data.json │ │ ├── main.js │ │ └── manifest.json │ ├── note-refactor-obsidian │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── novel-word-count │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── obsidian-auto-link-title │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── obsidian-languagetool-plugin │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── obsidian-reading-time │ │ ├── main.js │ │ └── manifest.json │ ├── obsidian-tasks-plugin │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── periodic-notes │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── table-editor-obsidian │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ └── templater-obsidian │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css ├── starred.json └── workspace ├── 00 ♻ Memory Flow Interface.md ├── 00 📝 Directory.md ├── 000 Inbox ├── Important Project │ ├── bad apple.md │ ├── it.md │ └── pls rember.md └── What a save!.md ├── 01 🏠 Main Dashboard.md ├── 02 🎨 Arts Dashboard.md ├── 100 Staging └── Harumachi Clover Is THE Song.md ├── 200 Resources ├── Agile Project Management.md ├── Alignment.md ├── Answering Big Questions with Alignment.md ├── Dashboard.md ├── Done (Working State).md ├── Folders as Working States.md ├── Getting Things Done.md ├── Kanban (Agile).md ├── Open-Ended Problem-Solving.md ├── Organizing Tasks With Tags.md ├── Organizing by Folders vs Tags.md ├── Periodic Notes for Alignment.md ├── Personal Knowledge Database.md ├── Personal Knowledge Management.md ├── Pillars, Pipelines, Vaults (PPV).md ├── Practical Workflow of MFI.md ├── Projects.md ├── Rambling.md ├── Scrum (Agile).md ├── Staging (Working State).md ├── Stale (Working State).md ├── Tags are Disciplines.md ├── Tags.md ├── Tasks.md └── Working (Working State).md ├── 300 Alignment └── 2022-06-11.md ├── 800 Templates ├── em dash.md ├── guide.md └── task.md ├── 900 Archive └── abandoned note.md └── README.md /.obsidian/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "foldHeading": true, 3 | "foldIndent": true, 4 | "newFileLocation": "current", 5 | "attachmentFolderPath": "./", 6 | "alwaysUpdateLinks": true, 7 | "spellcheckDictionary": [ 8 | "setup", 9 | "Ikigai", 10 | "Readme", 11 | "frontmatter", 12 | "Ikigai", 13 | "Zettelkasten", 14 | "ikigai", 15 | "killsets ", 16 | "skillsets", 17 | "codeblocks", 18 | "Ikigais", 19 | "ikigais", 20 | "Frontmatter", 21 | "Disciplines", 22 | "checklisted" 23 | ], 24 | "legacyEditor": false, 25 | "livePreview": true, 26 | "promptDelete": false 27 | } -------------------------------------------------------------------------------- /.obsidian/appearance.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseFontSize": 15 3 | } -------------------------------------------------------------------------------- /.obsidian/community-plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "calendar", 3 | "nldates-obsidian", 4 | "periodic-notes", 5 | "obsidian-tasks-plugin", 6 | "templater-obsidian", 7 | "maximise-active-pane-obsidian", 8 | "hotkeysplus-obsidian", 9 | "note-refactor-obsidian", 10 | "obsidian-languagetool-plugin", 11 | "obsidian-auto-link-title", 12 | "table-editor-obsidian", 13 | "novel-word-count", 14 | "obsidian-reading-time" 15 | ] -------------------------------------------------------------------------------- /.obsidian/core-plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "file-explorer", 3 | "global-search", 4 | "switcher", 5 | "graph", 6 | "backlink", 7 | "tag-pane", 8 | "page-preview", 9 | "note-composer", 10 | "command-palette", 11 | "starred", 12 | "markdown-importer", 13 | "outline", 14 | "word-count", 15 | "open-with-default-app", 16 | "file-recovery" 17 | ] -------------------------------------------------------------------------------- /.obsidian/graph.json: -------------------------------------------------------------------------------- 1 | { 2 | "collapse-filter": false, 3 | "search": "Projects", 4 | "showTags": false, 5 | "showAttachments": false, 6 | "hideUnresolved": false, 7 | "showOrphans": true, 8 | "collapse-color-groups": true, 9 | "colorGroups": [ 10 | { 11 | "query": "", 12 | "color": { 13 | "a": 1, 14 | "rgb": 14701138 15 | } 16 | } 17 | ], 18 | "collapse-display": true, 19 | "showArrow": false, 20 | "textFadeMultiplier": 0, 21 | "nodeSizeMultiplier": 1, 22 | "lineSizeMultiplier": 1, 23 | "collapse-forces": true, 24 | "centerStrength": 0.518713248970312, 25 | "repelStrength": 10, 26 | "linkStrength": 1, 27 | "linkDistance": 250, 28 | "scale": 1.476986098068651, 29 | "close": false 30 | } -------------------------------------------------------------------------------- /.obsidian/hotkeys.json: -------------------------------------------------------------------------------- 1 | { 2 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-1": [ 3 | { 4 | "modifiers": [ 5 | "Alt", 6 | "Shift" 7 | ], 8 | "key": "1" 9 | } 10 | ], 11 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-2": [ 12 | { 13 | "modifiers": [ 14 | "Alt", 15 | "Shift" 16 | ], 17 | "key": "2" 18 | } 19 | ], 20 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-5": [ 21 | { 22 | "modifiers": [ 23 | "Alt", 24 | "Shift" 25 | ], 26 | "key": "5" 27 | } 28 | ], 29 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-6": [ 30 | { 31 | "modifiers": [ 32 | "Alt", 33 | "Shift" 34 | ], 35 | "key": "6" 36 | } 37 | ], 38 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-3": [ 39 | { 40 | "modifiers": [ 41 | "Alt", 42 | "Shift" 43 | ], 44 | "key": "3" 45 | } 46 | ], 47 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-4": [ 48 | { 49 | "modifiers": [ 50 | "Alt", 51 | "Shift" 52 | ], 53 | "key": "4" 54 | } 55 | ], 56 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-7": [ 57 | { 58 | "modifiers": [ 59 | "Alt", 60 | "Shift" 61 | ], 62 | "key": "7" 63 | } 64 | ], 65 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-8": [ 66 | { 67 | "modifiers": [ 68 | "Alt", 69 | "Shift" 70 | ], 71 | "key": "8" 72 | } 73 | ], 74 | "obsidian-shortcuts-for-starred-files:open-file-in-new-pane-9": [ 75 | { 76 | "modifiers": [ 77 | "Alt", 78 | "Shift" 79 | ], 80 | "key": "9" 81 | } 82 | ], 83 | "obsidian-shortcuts-for-starred-files:open-file-1": [ 84 | { 85 | "modifiers": [ 86 | "Alt" 87 | ], 88 | "key": "1" 89 | } 90 | ], 91 | "obsidian-shortcuts-for-starred-files:open-file-2": [ 92 | { 93 | "modifiers": [ 94 | "Alt" 95 | ], 96 | "key": "2" 97 | } 98 | ], 99 | "obsidian-shortcuts-for-starred-files:open-file-3": [ 100 | { 101 | "modifiers": [ 102 | "Alt" 103 | ], 104 | "key": "3" 105 | } 106 | ], 107 | "obsidian-shortcuts-for-starred-files:open-file-4": [ 108 | { 109 | "modifiers": [ 110 | "Alt" 111 | ], 112 | "key": "4" 113 | } 114 | ], 115 | "obsidian-shortcuts-for-starred-files:open-file-5": [ 116 | { 117 | "modifiers": [ 118 | "Alt" 119 | ], 120 | "key": "5" 121 | } 122 | ], 123 | "obsidian-shortcuts-for-starred-files:open-file-6": [ 124 | { 125 | "modifiers": [ 126 | "Alt" 127 | ], 128 | "key": "6" 129 | } 130 | ], 131 | "obsidian-shortcuts-for-starred-files:open-file-7": [ 132 | { 133 | "modifiers": [ 134 | "Alt" 135 | ], 136 | "key": "7" 137 | } 138 | ], 139 | "obsidian-shortcuts-for-starred-files:open-file-8": [ 140 | { 141 | "modifiers": [ 142 | "Alt" 143 | ], 144 | "key": "8" 145 | } 146 | ], 147 | "obsidian-shortcuts-for-starred-files:open-file-9": [ 148 | { 149 | "modifiers": [ 150 | "Alt" 151 | ], 152 | "key": "9" 153 | } 154 | ], 155 | "editor:swap-line-up": [ 156 | { 157 | "modifiers": [ 158 | "Alt" 159 | ], 160 | "key": "W" 161 | } 162 | ], 163 | "editor:swap-line-down": [ 164 | { 165 | "modifiers": [ 166 | "Alt" 167 | ], 168 | "key": "S" 169 | } 170 | ], 171 | "note-refactor-obsidian:app:extract-selection-first-line": [ 172 | { 173 | "modifiers": [ 174 | "Mod", 175 | "Shift" 176 | ], 177 | "key": "M" 178 | } 179 | ], 180 | "note-refactor-obsidian:app:extract-selection-content-only": [ 181 | { 182 | "modifiers": [ 183 | "Alt", 184 | "Shift" 185 | ], 186 | "key": "M" 187 | } 188 | ], 189 | "hotkeysplus-obsidian:toggle-bullet-number": [ 190 | { 191 | "modifiers": [ 192 | "Mod" 193 | ], 194 | "key": "3" 195 | } 196 | ], 197 | "periodic-notes:open-daily-note": [ 198 | { 199 | "modifiers": [ 200 | "Mod" 201 | ], 202 | "key": "T" 203 | } 204 | ] 205 | } -------------------------------------------------------------------------------- /.obsidian/plugins/calendar/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "shouldConfirmBeforeCreate": true, 3 | "weekStart": "locale", 4 | "wordsPerDot": 250, 5 | "showWeeklyNote": true, 6 | "weeklyNoteFormat": "", 7 | "weeklyNoteTemplate": "", 8 | "weeklyNoteFolder": "", 9 | "localeOverride": "system-default" 10 | } -------------------------------------------------------------------------------- /.obsidian/plugins/calendar/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "calendar", 3 | "name": "Calendar", 4 | "description": "Calendar view of your daily notes", 5 | "version": "1.5.10", 6 | "author": "Liam Cain", 7 | "authorUrl": "https://github.com/liamcain/", 8 | "isDesktopOnly": false, 9 | "minAppVersion": "0.9.11" 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/hotkeysplus-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "hotkeysplus-obsidian", 3 | "name": "Hotkeys++", 4 | "description": "Additional hotkeys to do common things in Obsidian", 5 | "version": "0.2.7", 6 | "author": "Argentina Ortega Sainz", 7 | "authorUrl": "https://argentinaos.com", 8 | "isDesktopOnly": false, 9 | "minAppVersion": "0.12.19" 10 | } -------------------------------------------------------------------------------- /.obsidian/plugins/maximise-active-pane-obsidian/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var obsidian = require('obsidian'); 4 | 5 | /*! ***************************************************************************** 6 | Copyright (c) Microsoft Corporation. 7 | 8 | Permission to use, copy, modify, and/or distribute this software for any 9 | purpose with or without fee is hereby granted. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 12 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 14 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 16 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 | PERFORMANCE OF THIS SOFTWARE. 18 | ***************************************************************************** */ 19 | /* global Reflect, Promise */ 20 | 21 | var extendStatics = function(d, b) { 22 | extendStatics = Object.setPrototypeOf || 23 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 24 | function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 25 | return extendStatics(d, b); 26 | }; 27 | 28 | function __extends(d, b) { 29 | if (typeof b !== "function" && b !== null) 30 | throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 31 | extendStatics(d, b); 32 | function __() { this.constructor = d; } 33 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 34 | } 35 | 36 | function __awaiter(thisArg, _arguments, P, generator) { 37 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 38 | return new (P || (P = Promise))(function (resolve, reject) { 39 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 40 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 41 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 42 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 43 | }); 44 | } 45 | 46 | function __generator(thisArg, body) { 47 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 48 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 49 | function verb(n) { return function (v) { return step([n, v]); }; } 50 | function step(op) { 51 | if (f) throw new TypeError("Generator is already executing."); 52 | while (_) try { 53 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 54 | if (y = 0, t) op = [op[0] & 2, t.value]; 55 | switch (op[0]) { 56 | case 0: case 1: t = op; break; 57 | case 4: _.label++; return { value: op[1], done: false }; 58 | case 5: _.label++; y = op[1]; op = [0]; continue; 59 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 60 | default: 61 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 62 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 63 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 64 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 65 | if (t[2]) _.ops.pop(); 66 | _.trys.pop(); continue; 67 | } 68 | op = body.call(thisArg, _); 69 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 70 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 71 | } 72 | } 73 | 74 | var PluginBase = /** @class */ (function (_super) { 75 | __extends(PluginBase, _super); 76 | function PluginBase() { 77 | return _super !== null && _super.apply(this, arguments) || this; 78 | } 79 | Object.defineProperty(PluginBase.prototype, "className", { 80 | get: function () { 81 | if (!this._cachedClassName) { 82 | this._cachedClassName = 'plugin-' + this.manifest.id; 83 | if (this._cachedClassName.endsWith('-obsidian')) { 84 | this._cachedClassName = this._cachedClassName.substring(0, this._cachedClassName.lastIndexOf('-obsidian')); 85 | } 86 | } 87 | return this._cachedClassName; 88 | }, 89 | enumerable: false, 90 | configurable: true 91 | }); 92 | Object.defineProperty(PluginBase.prototype, "rootSplit", { 93 | // helper property to get the rootSplit with some extra properties 94 | get: function () { return this.app.workspace.rootSplit; }, 95 | enumerable: false, 96 | configurable: true 97 | }); 98 | // is this deprecated now, or what? 99 | PluginBase.prototype.onInit = function () { 100 | return __awaiter(this, void 0, void 0, function () { 101 | return __generator(this, function (_a) { 102 | return [2 /*return*/]; 103 | }); 104 | }); 105 | }; 106 | // runs when the plugin is loaded 107 | PluginBase.prototype.onload = function () { 108 | var _this = this; 109 | // add in the required command pallete commands 110 | this.addCommands(); 111 | // add in any settings 112 | this.addSettings(); 113 | // wait for layout to be ready to perform the rest 114 | this.app.workspace.layoutReady ? this.enable() : this.app.workspace.on('layout-ready', function () { return _this.enable(); }); 115 | }; 116 | // runs when the plugin is onloaded 117 | PluginBase.prototype.onunload = function () { 118 | // run through the disable steps 119 | this.disable(); 120 | }; 121 | // perform any setup required to enable the plugin 122 | PluginBase.prototype.enable = function () { 123 | document.body.toggleClass(this.className, true); 124 | }; 125 | // perform any required disable steps, leave nothing behind 126 | PluginBase.prototype.disable = function () { 127 | document.body.toggleClass(this.className, false); 128 | }; 129 | // add in any required command pallete commands 130 | PluginBase.prototype.addCommands = function () { }; 131 | // add in any settings 132 | PluginBase.prototype.addSettings = function () { }; 133 | return PluginBase; 134 | }(obsidian.Plugin)); 135 | 136 | // The actual plugin class 137 | var MaximiseActivePanePlugin = /** @class */ (function (_super) { 138 | __extends(MaximiseActivePanePlugin, _super); 139 | function MaximiseActivePanePlugin() { 140 | return _super !== null && _super.apply(this, arguments) || this; 141 | } 142 | // perform any setup required to enable the plugin 143 | MaximiseActivePanePlugin.prototype.enable = function () { 144 | _super.prototype.enable.call(this); 145 | }; 146 | // perform any required disable steps, leave nothing behind 147 | MaximiseActivePanePlugin.prototype.disable = function () { 148 | _super.prototype.disable.call(this); 149 | // remove the maximised class if necessary 150 | this.rootSplit.containerEl.toggleClass('maximised', false); 151 | }; 152 | // add in the required command pallete commands 153 | MaximiseActivePanePlugin.prototype.addCommands = function () { 154 | var _this = this; 155 | // add the maximise command 156 | this.addCommand({ 157 | id: 'maximise-active-pane', 158 | name: 'Toggle', 159 | hotkeys: [{ modifiers: ['Mod', 'Shift'], key: 'x' }], 160 | callback: function () { 161 | // simply toggle the 'maximised' class and let the css do its thing 162 | _this.rootSplit.containerEl.toggleClass('maximised', !_this.rootSplit.containerEl.hasClass('maximised')); 163 | _this.app.workspace.onLayoutChange(); 164 | } 165 | }); 166 | }; 167 | return MaximiseActivePanePlugin; 168 | }(PluginBase)); 169 | 170 | module.exports = MaximiseActivePanePlugin; 171 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy9oZWxwZXJzLnRzIiwic3JjL21haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9KTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20pIHtcclxuICAgIGZvciAodmFyIGkgPSAwLCBpbCA9IGZyb20ubGVuZ3RoLCBqID0gdG8ubGVuZ3RoOyBpIDwgaWw7IGkrKywgaisrKVxyXG4gICAgICAgIHRvW2pdID0gZnJvbVtpXTtcclxuICAgIHJldHVybiB0bztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgcHJpdmF0ZU1hcCkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIGdldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcml2YXRlTWFwLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBwcml2YXRlTWFwLCB2YWx1ZSkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIHNldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHByaXZhdGVNYXAuc2V0KHJlY2VpdmVyLCB2YWx1ZSk7XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuIiwiaW1wb3J0ICcuL3N0eWxlcy5zY3NzJ1xuaW1wb3J0IHsgUGx1Z2luLCBXb3Jrc3BhY2VTcGxpdCB9IGZyb20gJ29ic2lkaWFuJztcblxuLy8gaW50ZXJmYWNlIGZvciBleHRlbmRpbmcgV29ya3NwYWNlU3BsaXQgd2l0aCB1bmRvY3VtZW50ZWQgcHJvcGVydGllc1xuZXhwb3J0IGludGVyZmFjZSBXb3Jrc3BhY2VTcGxpdEV4dCBleHRlbmRzIFdvcmtzcGFjZVNwbGl0IHtcbiAgLy8gdGhlIGNvbnRhaW5lciBlbGVtZW50IG9mIGEgbGVhZlxuICBjb250YWluZXJFbDogSFRNTEVsZW1lbnQ7XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQbHVnaW5CYXNlIGV4dGVuZHMgUGx1Z2luIHtcblxuICAvLyBnZXQgdGhlIGNsYXNzIG5hbWUgZm9yIHRoZSBwbHVnaW5cbiAgcHJpdmF0ZSBfY2FjaGVkQ2xhc3NOYW1lOiBzdHJpbmc7XG4gIGdldCBjbGFzc05hbWUoKSB7XG4gICAgaWYgKCF0aGlzLl9jYWNoZWRDbGFzc05hbWUpIHtcbiAgICAgIHRoaXMuX2NhY2hlZENsYXNzTmFtZSA9ICdwbHVnaW4tJyArIHRoaXMubWFuaWZlc3QuaWQ7XG4gICAgICBpZiAodGhpcy5fY2FjaGVkQ2xhc3NOYW1lLmVuZHNXaXRoKCctb2JzaWRpYW4nKSkge1xuICAgICAgICB0aGlzLl9jYWNoZWRDbGFzc05hbWUgPSB0aGlzLl9jYWNoZWRDbGFzc05hbWUuc3Vic3RyaW5nKDAsIHRoaXMuX2NhY2hlZENsYXNzTmFtZS5sYXN0SW5kZXhPZignLW9ic2lkaWFuJykpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jYWNoZWRDbGFzc05hbWU7XG4gIH1cblxuICAvLyBoZWxwZXIgcHJvcGVydHkgdG8gZ2V0IHRoZSByb290U3BsaXQgd2l0aCBzb21lIGV4dHJhIHByb3BlcnRpZXNcbiAgZ2V0IHJvb3RTcGxpdCgpIHsgcmV0dXJuIHRoaXMuYXBwLndvcmtzcGFjZS5yb290U3BsaXQgYXMgV29ya3NwYWNlU3BsaXRFeHQ7IH1cblxuICAvLyBpcyB0aGlzIGRlcHJlY2F0ZWQgbm93LCBvciB3aGF0P1xuICBhc3luYyBvbkluaXQoKSB7XG4gIH1cblxuICAvLyBydW5zIHdoZW4gdGhlIHBsdWdpbiBpcyBsb2FkZWRcbiAgb25sb2FkKCkge1xuICAgIC8vIGFkZCBpbiB0aGUgcmVxdWlyZWQgY29tbWFuZCBwYWxsZXRlIGNvbW1hbmRzXG4gICAgdGhpcy5hZGRDb21tYW5kcygpO1xuXG4gICAgLy8gYWRkIGluIGFueSBzZXR0aW5nc1xuICAgIHRoaXMuYWRkU2V0dGluZ3MoKTtcblxuICAgIC8vIHdhaXQgZm9yIGxheW91dCB0byBiZSByZWFkeSB0byBwZXJmb3JtIHRoZSByZXN0XG4gICAgdGhpcy5hcHAud29ya3NwYWNlLmxheW91dFJlYWR5ID8gdGhpcy5lbmFibGUoKSA6IHRoaXMuYXBwLndvcmtzcGFjZS5vbignbGF5b3V0LXJlYWR5JywgKCkgPT4gdGhpcy5lbmFibGUoKSk7XG4gIH1cblxuICAvLyBydW5zIHdoZW4gdGhlIHBsdWdpbiBpcyBvbmxvYWRlZFxuICBvbnVubG9hZCgpIHtcbiAgICAvLyBydW4gdGhyb3VnaCB0aGUgZGlzYWJsZSBzdGVwc1xuICAgIHRoaXMuZGlzYWJsZSgpO1xuICB9XG4gIFxuICAgLy8gcGVyZm9ybSBhbnkgc2V0dXAgcmVxdWlyZWQgdG8gZW5hYmxlIHRoZSBwbHVnaW5cbiAgZW5hYmxlKCk6IHZvaWQge1xuICAgIGRvY3VtZW50LmJvZHkudG9nZ2xlQ2xhc3ModGhpcy5jbGFzc05hbWUsIHRydWUpO1xuICB9XG5cbiAgLy8gcGVyZm9ybSBhbnkgcmVxdWlyZWQgZGlzYWJsZSBzdGVwcywgbGVhdmUgbm90aGluZyBiZWhpbmRcbiAgZGlzYWJsZSgpOiB2b2lkIHtcbiAgICBkb2N1bWVudC5ib2R5LnRvZ2dsZUNsYXNzKHRoaXMuY2xhc3NOYW1lLCBmYWxzZSk7XG4gIH1cblxuICAvLyBhZGQgaW4gYW55IHJlcXVpcmVkIGNvbW1hbmQgcGFsbGV0ZSBjb21tYW5kc1xuICBhZGRDb21tYW5kcygpOiB2b2lkIHsgfTtcblxuICAvLyBhZGQgaW4gYW55IHNldHRpbmdzXG4gIGFkZFNldHRpbmdzKCk6IHZvaWQgeyB9O1xufVxuIiwiaW1wb3J0IHsgUGx1Z2luQmFzZSB9IGZyb20gJy4vaGVscGVycydcblxuLy8gVGhlIGFjdHVhbCBwbHVnaW4gY2xhc3NcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1heGltaXNlQWN0aXZlUGFuZVBsdWdpbiBleHRlbmRzIFBsdWdpbkJhc2Uge1xuXG4gIC8vIHBlcmZvcm0gYW55IHNldHVwIHJlcXVpcmVkIHRvIGVuYWJsZSB0aGUgcGx1Z2luXG4gIGVuYWJsZSgpIHtcbiAgICBzdXBlci5lbmFibGUoKTtcbiAgfVxuXG4gIC8vIHBlcmZvcm0gYW55IHJlcXVpcmVkIGRpc2FibGUgc3RlcHMsIGxlYXZlIG5vdGhpbmcgYmVoaW5kXG4gIGRpc2FibGUoKSB7XG4gICAgc3VwZXIuZGlzYWJsZSgpO1xuXG4gICAgLy8gcmVtb3ZlIHRoZSBtYXhpbWlzZWQgY2xhc3MgaWYgbmVjZXNzYXJ5XG4gICAgdGhpcy5yb290U3BsaXQuY29udGFpbmVyRWwudG9nZ2xlQ2xhc3MoJ21heGltaXNlZCcsIGZhbHNlKTtcbiAgfVxuXG4gIC8vIGFkZCBpbiB0aGUgcmVxdWlyZWQgY29tbWFuZCBwYWxsZXRlIGNvbW1hbmRzXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIC8vIGFkZCB0aGUgbWF4aW1pc2UgY29tbWFuZFxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICBpZDogJ21heGltaXNlLWFjdGl2ZS1wYW5lJyxcbiAgICAgIG5hbWU6ICdUb2dnbGUnLFxuICAgICAgaG90a2V5czogW3ttb2RpZmllcnM6IFsnTW9kJywgJ1NoaWZ0J10sIGtleTogJ3gnfV0sXG4gICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICAvLyBzaW1wbHkgdG9nZ2xlIHRoZSAnbWF4aW1pc2VkJyBjbGFzcyBhbmQgbGV0IHRoZSBjc3MgZG8gaXRzIHRoaW5nXG4gICAgICAgIHRoaXMucm9vdFNwbGl0LmNvbnRhaW5lckVsLnRvZ2dsZUNsYXNzKCdtYXhpbWlzZWQnLCAhdGhpcy5yb290U3BsaXQuY29udGFpbmVyRWwuaGFzQ2xhc3MoJ21heGltaXNlZCcpKTtcbiAgICAgICAgdGhpcy5hcHAud29ya3NwYWNlLm9uTGF5b3V0Q2hhbmdlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJQbHVnaW4iXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksYUFBYSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNuQyxJQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsY0FBYztBQUN6QyxTQUFTLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxZQUFZLEtBQUssSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDcEYsUUFBUSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDMUcsSUFBSSxPQUFPLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0IsQ0FBQyxDQUFDO0FBQ0Y7QUFDTyxTQUFTLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2hDLElBQUksSUFBSSxPQUFPLENBQUMsS0FBSyxVQUFVLElBQUksQ0FBQyxLQUFLLElBQUk7QUFDN0MsUUFBUSxNQUFNLElBQUksU0FBUyxDQUFDLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRywrQkFBK0IsQ0FBQyxDQUFDO0FBQ2xHLElBQUksYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4QixJQUFJLFNBQVMsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsRUFBRTtBQUMzQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxLQUFLLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDekYsQ0FBQztBQXVDRDtBQUNPLFNBQVMsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRTtBQUM3RCxJQUFJLFNBQVMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLE9BQU8sS0FBSyxZQUFZLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsVUFBVSxPQUFPLEVBQUUsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNoSCxJQUFJLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRTtBQUMvRCxRQUFRLFNBQVMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDbkcsUUFBUSxTQUFTLFFBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDdEcsUUFBUSxTQUFTLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQUU7QUFDdEgsUUFBUSxJQUFJLENBQUMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsVUFBVSxJQUFJLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDOUUsS0FBSyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBQ0Q7QUFDTyxTQUFTLFdBQVcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFO0FBQzNDLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNySCxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FB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 172 | -------------------------------------------------------------------------------- /.obsidian/plugins/maximise-active-pane-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "maximise-active-pane-obsidian", 3 | "name": "Maximise Active Pane", 4 | "author": "death_au", 5 | "description": "Simply fills the workspace with the active pane", 6 | "isDesktopOnly": false, 7 | "version": "0.0.3" 8 | } -------------------------------------------------------------------------------- /.obsidian/plugins/maximise-active-pane-obsidian/styles.css: -------------------------------------------------------------------------------- 1 | .plugin-maximise-active-pane .workspace-split.maximised .workspace-leaf:not(.mod-active), 2 | .plugin-maximise-active-pane .workspace-split.maximised .workspace-leaf.mod-active ~ .workspace-split { 3 | display: none; 4 | } 5 | .plugin-maximise-active-pane .workspace-split.maximised .workspace-leaf.mod-active { 6 | flex-basis: calc(100% - 4px); 7 | } -------------------------------------------------------------------------------- /.obsidian/plugins/nldates-obsidian/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "autosuggestToggleLink": false, 3 | "autocompleteTriggerPhrase": "@", 4 | "isAutosuggestEnabled": true, 5 | "format": "YYYY-MM-DD", 6 | "timeFormat": "HH:mm", 7 | "separator": " ", 8 | "weekStart": "Monday", 9 | "modalToggleTime": false, 10 | "modalToggleLink": false, 11 | "modalMomentFormat": "YYYY-MM-DD HH:mm" 12 | } -------------------------------------------------------------------------------- /.obsidian/plugins/nldates-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "nldates-obsidian", 3 | "name": "Natural Language Dates", 4 | "description": "Create date-links based on natural language", 5 | "version": "0.6.1", 6 | "author": "Argentina Ortega Sainz", 7 | "authorUrl": "https://argentinaos.com/", 8 | "isDesktopOnly": false, 9 | "minAppVersion": "0.13.0" 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/note-refactor-obsidian/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "includeFirstLineAsNoteHeading": false, 3 | "excludeFirstLineInNote": false, 4 | "headingFormat": "#", 5 | "newFileLocation": 1, 6 | "customFolder": "", 7 | "fileNamePrefix": "", 8 | "transcludeByDefault": false, 9 | "noteLinkTemplate": "", 10 | "refactoredNoteTemplate": "" 11 | } -------------------------------------------------------------------------------- /.obsidian/plugins/note-refactor-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "note-refactor-obsidian", 3 | "name": "Note Refactor", 4 | "version": "1.7.1", 5 | "description": "Extract note content into new notes and split notes", 6 | "isDesktopOnly": false, 7 | "js": "main.js", 8 | "css": "style.css" 9 | } -------------------------------------------------------------------------------- /.obsidian/plugins/note-refactor-obsidian/styles.css: -------------------------------------------------------------------------------- 1 | .note-refactor-filename .setting-item-info { 2 | margin-right: 0; 3 | } 4 | 5 | .note-refactor-filename .setting-item-name { 6 | padding-top: 10px; 7 | } -------------------------------------------------------------------------------- /.obsidian/plugins/novel-word-count/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "countType": "word", 4 | "abbreviateDescriptions": false, 5 | "alignment": "inline", 6 | "debugMode": false 7 | }, 8 | "cachedCounts": { 9 | "README.md": { 10 | "wordCount": 486, 11 | "pageCount": 2, 12 | "characterCount": 3341, 13 | "createdDate": 1655091574383, 14 | "modifiedDate": 1655093164091 15 | }, 16 | "900 Archive/abandoned note.md": { 17 | "wordCount": 42, 18 | "pageCount": 1, 19 | "characterCount": 222, 20 | "createdDate": 1654992729806, 21 | "modifiedDate": 1654992820547 22 | }, 23 | "800 Templates/task.md": { 24 | "wordCount": 1, 25 | "pageCount": 1, 26 | "characterCount": 6, 27 | "createdDate": 1654883577588, 28 | "modifiedDate": 1654883677395 29 | }, 30 | "800 Templates/guide.md": { 31 | "wordCount": 8, 32 | "pageCount": 1, 33 | "characterCount": 45, 34 | "createdDate": 1654889734922, 35 | "modifiedDate": 1654975764467 36 | }, 37 | "800 Templates/em dash.md": { 38 | "wordCount": 1, 39 | "pageCount": 1, 40 | "characterCount": 1, 41 | "createdDate": 1654891139206, 42 | "modifiedDate": 1654891141385 43 | }, 44 | "300 Alignment/2022-06-11.md": { 45 | "wordCount": 211, 46 | "pageCount": 1, 47 | "characterCount": 1221, 48 | "createdDate": 1654998760641, 49 | "modifiedDate": 1655075818043 50 | }, 51 | "200 Resources/Working (Working State).md": { 52 | "wordCount": 105, 53 | "pageCount": 1, 54 | "characterCount": 717, 55 | "createdDate": 1654889657448, 56 | "modifiedDate": 1655085609199 57 | }, 58 | "200 Resources/Tasks.md": { 59 | "wordCount": 221, 60 | "pageCount": 1, 61 | "characterCount": 1418, 62 | "createdDate": 1654905977899, 63 | "modifiedDate": 1655091943726 64 | }, 65 | "200 Resources/Tags.md": { 66 | "wordCount": 226, 67 | "pageCount": 1, 68 | "characterCount": 1413, 69 | "createdDate": 1654905524648, 70 | "modifiedDate": 1655086356250 71 | }, 72 | "200 Resources/Tags are Disciplines.md": { 73 | "wordCount": 220, 74 | "pageCount": 1, 75 | "characterCount": 1470, 76 | "createdDate": 1654890645371, 77 | "modifiedDate": 1655086121829 78 | }, 79 | "200 Resources/Staging (Working State).md": { 80 | "wordCount": 61, 81 | "pageCount": 1, 82 | "characterCount": 467, 83 | "createdDate": 1654889661799, 84 | "modifiedDate": 1655086430502 85 | }, 86 | "200 Resources/Stale (Working State).md": { 87 | "wordCount": 80, 88 | "pageCount": 1, 89 | "characterCount": 542, 90 | "createdDate": 1654889656374, 91 | "modifiedDate": 1655086379918 92 | }, 93 | "200 Resources/Scrum (Agile).md": { 94 | "wordCount": 87, 95 | "pageCount": 1, 96 | "characterCount": 618, 97 | "createdDate": 1655045480290, 98 | "modifiedDate": 1655086480666 99 | }, 100 | "200 Resources/Rambling.md": { 101 | "wordCount": 393, 102 | "pageCount": 2, 103 | "characterCount": 2429, 104 | "createdDate": 1654903106656, 105 | "modifiedDate": 1655086760244 106 | }, 107 | "200 Resources/Projects.md": { 108 | "wordCount": 295, 109 | "pageCount": 1, 110 | "characterCount": 1870, 111 | "createdDate": 1654888197234, 112 | "modifiedDate": 1655087492249 113 | }, 114 | "200 Resources/Practical Workflow of MFI.md": { 115 | "wordCount": 431, 116 | "pageCount": 2, 117 | "characterCount": 2799, 118 | "createdDate": 1654884438615, 119 | "modifiedDate": 1655088613515 120 | }, 121 | "200 Resources/Pillars, Pipelines, Vaults (PPV).md": { 122 | "wordCount": 614, 123 | "pageCount": 3, 124 | "characterCount": 3770, 125 | "createdDate": 1655045455833, 126 | "modifiedDate": 1655088834520 127 | }, 128 | "200 Resources/Personal Knowledge Management.md": { 129 | "wordCount": 144, 130 | "pageCount": 1, 131 | "characterCount": 929, 132 | "createdDate": 1654891541607, 133 | "modifiedDate": 1655089211690 134 | }, 135 | "200 Resources/Personal Knowledge Database.md": { 136 | "wordCount": 61, 137 | "pageCount": 1, 138 | "characterCount": 456, 139 | "createdDate": 1655088956035, 140 | "modifiedDate": 1655089203053 141 | }, 142 | "200 Resources/Periodic Notes for Alignment.md": { 143 | "wordCount": 119, 144 | "pageCount": 1, 145 | "characterCount": 771, 146 | "createdDate": 1654911238991, 147 | "modifiedDate": 1655089252827 148 | }, 149 | "200 Resources/Organizing Tasks With Tags.md": { 150 | "wordCount": 92, 151 | "pageCount": 1, 152 | "characterCount": 547, 153 | "createdDate": 1654907045385, 154 | "modifiedDate": 1655091946242 155 | }, 156 | "200 Resources/Organizing by Folders vs Tags.md": { 157 | "wordCount": 290, 158 | "pageCount": 1, 159 | "characterCount": 1903, 160 | "createdDate": 1654886189230, 161 | "modifiedDate": 1655089618100 162 | }, 163 | "200 Resources/Open-Ended Problem-Solving.md": { 164 | "wordCount": 286, 165 | "pageCount": 1, 166 | "characterCount": 1554, 167 | "createdDate": 1654888255033, 168 | "modifiedDate": 1655089641283 169 | }, 170 | "200 Resources/Kanban (Agile).md": { 171 | "wordCount": 184, 172 | "pageCount": 1, 173 | "characterCount": 1145, 174 | "createdDate": 1655045496133, 175 | "modifiedDate": 1655089796239 176 | }, 177 | "200 Resources/Getting Things Done.md": { 178 | "wordCount": 602, 179 | "pageCount": 3, 180 | "characterCount": 3562, 181 | "createdDate": 1655045369982, 182 | "modifiedDate": 1655075150194 183 | }, 184 | "200 Resources/Folders as Working States.md": { 185 | "wordCount": 293, 186 | "pageCount": 1, 187 | "characterCount": 1842, 188 | "createdDate": 1654887102344, 189 | "modifiedDate": 1655090051326 190 | }, 191 | "200 Resources/Dashboard.md": { 192 | "wordCount": 251, 193 | "pageCount": 1, 194 | "characterCount": 1579, 195 | "createdDate": 1654973326382, 196 | "modifiedDate": 1655091946264 197 | }, 198 | "200 Resources/Done (Working State).md": { 199 | "wordCount": 72, 200 | "pageCount": 1, 201 | "characterCount": 487, 202 | "createdDate": 1654889624500, 203 | "modifiedDate": 1655090080905 204 | }, 205 | "200 Resources/Answering Big Questions with Alignment.md": { 206 | "wordCount": 174, 207 | "pageCount": 1, 208 | "characterCount": 996, 209 | "createdDate": 1654911135850, 210 | "modifiedDate": 1655090633613 211 | }, 212 | "200 Resources/Alignment.md": { 213 | "wordCount": 400, 214 | "pageCount": 2, 215 | "characterCount": 2329, 216 | "createdDate": 1654903870990, 217 | "modifiedDate": 1655090960394 218 | }, 219 | "200 Resources/Agile Project Management.md": { 220 | "wordCount": 316, 221 | "pageCount": 2, 222 | "characterCount": 2096, 223 | "createdDate": 1655045468836, 224 | "modifiedDate": 1655091096841 225 | }, 226 | "100 Staging/Harumachi Clover Is THE Song.md": { 227 | "wordCount": 345, 228 | "pageCount": 2, 229 | "characterCount": 2044, 230 | "createdDate": 1654994217520, 231 | "modifiedDate": 1654998286932 232 | }, 233 | "02 🎨 Arts Dashboard.md": { 234 | "wordCount": 36, 235 | "pageCount": 1, 236 | "characterCount": 232, 237 | "createdDate": 1654998225645, 238 | "modifiedDate": 1655090439972 239 | }, 240 | "01 🏠 Main Dashboard.md": { 241 | "wordCount": 29, 242 | "pageCount": 1, 243 | "characterCount": 170, 244 | "createdDate": 1654881370321, 245 | "modifiedDate": 1654998589013 246 | }, 247 | "000 Inbox/What a save!.md": { 248 | "wordCount": 34, 249 | "pageCount": 1, 250 | "characterCount": 177, 251 | "createdDate": 1654991852434, 252 | "modifiedDate": 1654996268286 253 | }, 254 | "000 Inbox/Important Project/pls rember.md": { 255 | "wordCount": 37, 256 | "pageCount": 1, 257 | "characterCount": 241, 258 | "createdDate": 1654993105587, 259 | "modifiedDate": 1654995985705 260 | }, 261 | "000 Inbox/Important Project/it.md": { 262 | "wordCount": 9, 263 | "pageCount": 1, 264 | "characterCount": 196, 265 | "createdDate": 1654996532828, 266 | "modifiedDate": 1654998456801 267 | }, 268 | "000 Inbox/Important Project/bad apple.md": { 269 | "wordCount": 125, 270 | "pageCount": 1, 271 | "characterCount": 1881, 272 | "createdDate": 1654993082858, 273 | "modifiedDate": 1654996077859 274 | }, 275 | "00 📝 Directory.md": { 276 | "wordCount": 28, 277 | "pageCount": 1, 278 | "characterCount": 231, 279 | "createdDate": 1654998619996, 280 | "modifiedDate": 1655050677629 281 | }, 282 | "00 ♻ Memory Flow Interface.md": { 283 | "wordCount": 1067, 284 | "pageCount": 4, 285 | "characterCount": 6974, 286 | "createdDate": 1654998037365, 287 | "modifiedDate": 1655092901555 288 | } 289 | } 290 | } -------------------------------------------------------------------------------- /.obsidian/plugins/novel-word-count/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD 3 | if you want to view the source, please visit the github repository of this plugin 4 | */ 5 | 6 | var __create = Object.create; 7 | var __defProp = Object.defineProperty; 8 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 9 | var __getOwnPropNames = Object.getOwnPropertyNames; 10 | var __getProtoOf = Object.getPrototypeOf; 11 | var __hasOwnProp = Object.prototype.hasOwnProperty; 12 | var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); 13 | var __export = (target, all) => { 14 | __markAsModule(target); 15 | for (var name in all) 16 | __defProp(target, name, { get: all[name], enumerable: true }); 17 | }; 18 | var __reExport = (target, module2, desc) => { 19 | if (module2 && typeof module2 === "object" || typeof module2 === "function") { 20 | for (let key of __getOwnPropNames(module2)) 21 | if (!__hasOwnProp.call(target, key) && key !== "default") 22 | __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); 23 | } 24 | return target; 25 | }; 26 | var __toModule = (module2) => { 27 | return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); 28 | }; 29 | var __async = (__this, __arguments, generator) => { 30 | return new Promise((resolve, reject) => { 31 | var fulfilled = (value) => { 32 | try { 33 | step(generator.next(value)); 34 | } catch (e) { 35 | reject(e); 36 | } 37 | }; 38 | var rejected = (value) => { 39 | try { 40 | step(generator.throw(value)); 41 | } catch (e) { 42 | reject(e); 43 | } 44 | }; 45 | var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); 46 | step((generator = generator.apply(__this, __arguments)).next()); 47 | }); 48 | }; 49 | 50 | // main.ts 51 | __export(exports, { 52 | default: () => NovelWordCountPlugin 53 | }); 54 | 55 | // logic/debug.ts 56 | var DebugHelper = class { 57 | constructor() { 58 | this.debugMode = false; 59 | } 60 | setDebugMode(debug) { 61 | this.debugMode = debug; 62 | } 63 | debug(...args) { 64 | if (!this.debugMode) { 65 | return; 66 | } 67 | console.log("novel-word-count:", ...args); 68 | } 69 | debugStart(name) { 70 | if (!this.debugMode) { 71 | return () => { 72 | }; 73 | } 74 | var qualifiedName = `novel-word-count|${name}`; 75 | console.time(qualifiedName); 76 | return () => console.timeEnd(qualifiedName); 77 | } 78 | }; 79 | 80 | // logic/file.ts 81 | var import_obsidian = __toModule(require("obsidian")); 82 | var FileHelper = class { 83 | constructor(vault) { 84 | this.vault = vault; 85 | this.debugHelper = new DebugHelper(); 86 | } 87 | getAllFileCounts() { 88 | return __async(this, null, function* () { 89 | const debugEnd = this.debugHelper.debugStart("getAllFileCounts"); 90 | const files = this.vault.getMarkdownFiles(); 91 | const counts = {}; 92 | for (const file of files) { 93 | const contents = yield this.vault.cachedRead(file); 94 | const wordCount = this.countWords(contents); 95 | this.setCounts(counts, file, wordCount, contents); 96 | } 97 | debugEnd(); 98 | return counts; 99 | }); 100 | } 101 | getCountDataForPath(counts, path) { 102 | if (counts.hasOwnProperty(path)) { 103 | return counts[path]; 104 | } 105 | const childPaths = Object.keys(counts).filter((countPath) => path === "/" || countPath.startsWith(path + "/")); 106 | return childPaths.reduce((total, childPath) => { 107 | const childCount = this.getCountDataForPath(counts, childPath); 108 | total.wordCount += childCount.wordCount; 109 | total.pageCount += childCount.pageCount; 110 | total.characterCount += childCount.characterCount; 111 | total.createdDate = total.createdDate === 0 ? childCount.createdDate : Math.min(total.createdDate, childCount.createdDate); 112 | total.modifiedDate = Math.max(total.modifiedDate, childCount.modifiedDate); 113 | return total; 114 | }, { 115 | wordCount: 0, 116 | pageCount: 0, 117 | characterCount: 0, 118 | createdDate: 0, 119 | modifiedDate: 0 120 | }); 121 | } 122 | setDebugMode(debug) { 123 | this.debugHelper.setDebugMode(debug); 124 | } 125 | updateFileCounts(abstractFile, counts) { 126 | return __async(this, null, function* () { 127 | if (abstractFile instanceof import_obsidian.TFolder) { 128 | this.debugHelper.debug("updateFileCounts called on instance of TFolder"); 129 | Object.assign(counts, this.getAllFileCounts()); 130 | return; 131 | } 132 | if (abstractFile instanceof import_obsidian.TFile) { 133 | const contents = yield this.vault.cachedRead(abstractFile); 134 | const wordCount = this.countWords(contents); 135 | this.setCounts(counts, abstractFile, wordCount, contents); 136 | } 137 | }); 138 | } 139 | countWords(content) { 140 | return (content.match(/[^\s]+/g) || []).length; 141 | } 142 | setCounts(counts, file, wordCount, content) { 143 | counts[file.path] = { 144 | wordCount, 145 | pageCount: Math.ceil(wordCount / 300), 146 | characterCount: content.length, 147 | createdDate: file.stat.ctime, 148 | modifiedDate: file.stat.mtime 149 | }; 150 | } 151 | }; 152 | 153 | // main.ts 154 | var import_obsidian2 = __toModule(require("obsidian")); 155 | var CountType; 156 | (function(CountType2) { 157 | CountType2["Word"] = "word"; 158 | CountType2["Page"] = "page"; 159 | CountType2["Character"] = "character"; 160 | CountType2["Created"] = "created"; 161 | CountType2["Modified"] = "modified"; 162 | })(CountType || (CountType = {})); 163 | var countTypes = [ 164 | CountType.Word, 165 | CountType.Page, 166 | CountType.Character, 167 | CountType.Created, 168 | CountType.Modified 169 | ]; 170 | var AlignmentType; 171 | (function(AlignmentType2) { 172 | AlignmentType2["Inline"] = "inline"; 173 | AlignmentType2["Right"] = "right"; 174 | AlignmentType2["Below"] = "below"; 175 | })(AlignmentType || (AlignmentType = {})); 176 | var alignmentTypes = [ 177 | AlignmentType.Inline, 178 | AlignmentType.Right, 179 | AlignmentType.Below 180 | ]; 181 | var DEFAULT_SETTINGS = { 182 | countType: CountType.Word, 183 | abbreviateDescriptions: false, 184 | alignment: AlignmentType.Inline, 185 | debugMode: false 186 | }; 187 | var NovelWordCountPlugin = class extends import_obsidian2.Plugin { 188 | constructor(app, manifest) { 189 | super(app, manifest); 190 | this.debugHelper = new DebugHelper(); 191 | this.fileHelper = new FileHelper(this.app.vault); 192 | } 193 | get settings() { 194 | return this.savedData.settings; 195 | } 196 | onload() { 197 | return __async(this, null, function* () { 198 | yield this.loadSettings(); 199 | this.fileHelper.setDebugMode(this.savedData.settings.debugMode); 200 | this.debugHelper.setDebugMode(this.savedData.settings.debugMode); 201 | this.debugHelper.debug("onload lifecycle hook"); 202 | this.addSettingTab(new NovelWordCountSettingTab(this.app, this)); 203 | this.addCommand({ 204 | id: "recount-vault", 205 | name: "Reanalyze (recount) all documents in vault", 206 | callback: () => __async(this, null, function* () { 207 | this.debugHelper.debug("[Reanalyze] command triggered"); 208 | yield this.initialize(); 209 | }) 210 | }); 211 | this.addCommand({ 212 | id: "cycle-count-type", 213 | name: "Change data type to display", 214 | callback: () => __async(this, null, function* () { 215 | this.debugHelper.debug("[Change data type] command triggered"); 216 | this.settings.countType = countTypes[(countTypes.indexOf(this.settings.countType) + 1) % countTypes.length]; 217 | yield this.saveSettings(); 218 | this.updateDisplayedCounts(); 219 | }) 220 | }); 221 | this.handleEvents(); 222 | this.initialize(); 223 | }); 224 | } 225 | onunload() { 226 | return __async(this, null, function* () { 227 | this.saveSettings(); 228 | }); 229 | } 230 | loadSettings() { 231 | return __async(this, null, function* () { 232 | this.savedData = Object.assign({}, yield this.loadData()); 233 | this.savedData.settings = Object.assign({}, DEFAULT_SETTINGS, this.savedData.settings); 234 | }); 235 | } 236 | saveSettings() { 237 | return __async(this, null, function* () { 238 | yield this.saveData(this.savedData); 239 | }); 240 | } 241 | initialize(refreshAllCounts = true) { 242 | return __async(this, null, function* () { 243 | this.debugHelper.debug("initialize"); 244 | if (refreshAllCounts) { 245 | yield this.refreshAllCounts(); 246 | } 247 | try { 248 | yield this.updateDisplayedCounts(); 249 | } catch (err) { 250 | setTimeout(() => { 251 | this.initialize(false); 252 | }, 1e3); 253 | } 254 | }); 255 | } 256 | updateDisplayedCounts(file = null) { 257 | return __async(this, null, function* () { 258 | const debugEnd = this.debugHelper.debugStart("updateDisplayedCounts"); 259 | if (!Object.keys(this.savedData.cachedCounts).length) { 260 | this.debugHelper.debug("No cached data found; refreshing all counts."); 261 | yield this.refreshAllCounts(); 262 | } 263 | const fileExplorerLeaf = yield this.getFileExplorerLeaf(); 264 | this.setContainerClass(fileExplorerLeaf); 265 | const fileItems = fileExplorerLeaf.view.fileItems; 266 | if (file) { 267 | const relevantItems = Object.keys(fileItems).filter((path) => file.path.includes(path)); 268 | this.debugHelper.debug("Setting display counts for", relevantItems.length, "fileItems matching path", file.path); 269 | } else { 270 | this.debugHelper.debug(`Setting display counts for ${Object.keys(fileItems).length} fileItems`); 271 | } 272 | for (const path in fileItems) { 273 | if (file && !file.path.includes(path)) { 274 | continue; 275 | } 276 | const counts = this.fileHelper.getCountDataForPath(this.savedData.cachedCounts, path); 277 | const item = fileItems[path]; 278 | item.titleEl.setAttribute("data-novel-word-count-plugin", this.getNodeLabel(counts)); 279 | } 280 | debugEnd(); 281 | }); 282 | } 283 | getFileExplorerLeaf() { 284 | return __async(this, null, function* () { 285 | return new Promise((resolve, reject) => { 286 | let foundLeaf = null; 287 | this.app.workspace.iterateAllLeaves((leaf) => { 288 | if (foundLeaf) { 289 | return; 290 | } 291 | const view = leaf.view; 292 | if (!view || !view.fileItems) { 293 | return; 294 | } 295 | foundLeaf = leaf; 296 | resolve(foundLeaf); 297 | }); 298 | if (!foundLeaf) { 299 | reject(Error("Could not find file explorer leaf.")); 300 | } 301 | }); 302 | }); 303 | } 304 | getNodeLabel(counts) { 305 | if (!counts || typeof counts.wordCount !== "number") { 306 | return ""; 307 | } 308 | switch (this.settings.countType) { 309 | case CountType.Word: 310 | return this.settings.abbreviateDescriptions ? `${counts.wordCount.toLocaleString()}w` : `${counts.wordCount.toLocaleString()} word${counts.wordCount === 1 ? "" : "s"}`; 311 | case CountType.Page: 312 | return this.settings.abbreviateDescriptions ? `${counts.pageCount.toLocaleString()}p` : `${counts.pageCount.toLocaleString()} page${counts.pageCount === 1 ? "" : "s"}`; 313 | case CountType.Character: 314 | return this.settings.abbreviateDescriptions ? `${counts.characterCount.toLocaleString()}ch` : `${counts.characterCount.toLocaleString()} character${counts.characterCount === 1 ? "" : "s"}`; 315 | case CountType.Created: 316 | if (counts.createdDate === 0) { 317 | return ""; 318 | } 319 | return this.settings.abbreviateDescriptions ? `${new Date(counts.createdDate).toLocaleDateString()}/c` : `Created ${new Date(counts.createdDate).toLocaleDateString()}`; 320 | case CountType.Modified: 321 | if (counts.modifiedDate === 0) { 322 | return ""; 323 | } 324 | return this.settings.abbreviateDescriptions ? `${new Date(counts.modifiedDate).toLocaleDateString()}/u` : `Updated ${new Date(counts.modifiedDate).toLocaleDateString()}`; 325 | } 326 | return ""; 327 | } 328 | handleEvents() { 329 | this.registerEvent(this.app.vault.on("modify", (file) => __async(this, null, function* () { 330 | this.debugHelper.debug("[modify] vault hook fired, recounting file", file.path); 331 | yield this.fileHelper.updateFileCounts(file, this.savedData.cachedCounts); 332 | yield this.updateDisplayedCounts(file); 333 | }))); 334 | function recalculateAll(hookName, file) { 335 | return __async(this, null, function* () { 336 | this.debugHelper.debug(`[${hookName}] vault hook fired by file`, file.path, "recounting all files"); 337 | yield this.refreshAllCounts(); 338 | yield this.updateDisplayedCounts(); 339 | }); 340 | } 341 | this.registerEvent(this.app.vault.on("rename", (0, import_obsidian2.debounce)(recalculateAll.bind(this, "rename"), 1e3))); 342 | this.registerEvent(this.app.vault.on("create", (0, import_obsidian2.debounce)(recalculateAll.bind(this, "create"), 1e3))); 343 | this.registerEvent(this.app.vault.on("delete", (0, import_obsidian2.debounce)(recalculateAll.bind(this, "delete"), 1e3))); 344 | } 345 | refreshAllCounts() { 346 | return __async(this, null, function* () { 347 | this.debugHelper.debug("refreshAllCounts"); 348 | this.savedData.cachedCounts = yield this.fileHelper.getAllFileCounts(); 349 | yield this.saveSettings(); 350 | }); 351 | } 352 | setContainerClass(leaf) { 353 | const container = leaf.view.containerEl; 354 | const prefix = `novel-word-count--`; 355 | const alignmentClasses = alignmentTypes.map((at) => prefix + at); 356 | for (const ac of alignmentClasses) { 357 | container.toggleClass(ac, false); 358 | } 359 | container.toggleClass(prefix + this.settings.alignment, true); 360 | } 361 | }; 362 | var NovelWordCountSettingTab = class extends import_obsidian2.PluginSettingTab { 363 | constructor(app, plugin) { 364 | super(app, plugin); 365 | this.plugin = plugin; 366 | } 367 | display() { 368 | const { containerEl } = this; 369 | containerEl.empty(); 370 | containerEl.createEl("h2", { text: "Novel word count settings" }); 371 | new import_obsidian2.Setting(containerEl).setName("Data to show").setDesc("What to show next to each file and folder").addDropdown((drop) => drop.addOption(CountType.Word, "Word Count").addOption(CountType.Page, "Page Count").addOption(CountType.Character, "Character Count").addOption(CountType.Created, "Created Date").addOption(CountType.Modified, "Last Updated Date").setValue(this.plugin.settings.countType).onChange((value) => __async(this, null, function* () { 372 | this.plugin.settings.countType = value; 373 | yield this.plugin.saveSettings(); 374 | yield this.plugin.updateDisplayedCounts(); 375 | }))); 376 | new import_obsidian2.Setting(containerEl).setName("Abbreviate descriptions").setDesc("E.g. show '120w' instead of '120 words'").addToggle((toggle) => toggle.setValue(this.plugin.settings.abbreviateDescriptions).onChange((value) => __async(this, null, function* () { 377 | this.plugin.settings.abbreviateDescriptions = value; 378 | yield this.plugin.saveSettings(); 379 | yield this.plugin.updateDisplayedCounts(); 380 | }))); 381 | new import_obsidian2.Setting(containerEl).setName("Alignment").setDesc("Show data inline with file/folder names, right-aligned, or underneath").addDropdown((drop) => { 382 | drop.addOption(AlignmentType.Inline, "Inline").addOption(AlignmentType.Right, "Right-aligned").addOption(AlignmentType.Below, "Below").setValue(this.plugin.settings.alignment).onChange((value) => __async(this, null, function* () { 383 | this.plugin.settings.alignment = value; 384 | yield this.plugin.saveSettings(); 385 | yield this.plugin.updateDisplayedCounts(); 386 | })); 387 | }); 388 | new import_obsidian2.Setting(containerEl).setName("Reanalyze all documents").setDesc("If changes have occurred outside of Obsidian, you may need to trigger a manual analysis").addButton((button) => button.setButtonText("Reanalyze").setCta().onClick(() => __async(this, null, function* () { 389 | button.disabled = true; 390 | yield this.plugin.initialize(); 391 | button.setButtonText("Done"); 392 | button.removeCta(); 393 | setTimeout(() => { 394 | button.setButtonText("Reanalyze"); 395 | button.setCta(); 396 | button.disabled = false; 397 | }, 1e3); 398 | }))); 399 | new import_obsidian2.Setting(containerEl).setName("Debug mode").setDesc("Log debugging information to the developer console").addToggle((toggle) => toggle.setValue(this.plugin.settings.debugMode).onChange((value) => __async(this, null, function* () { 400 | this.plugin.settings.debugMode = value; 401 | this.plugin.debugHelper.setDebugMode(value); 402 | this.plugin.fileHelper.setDebugMode(value); 403 | yield this.plugin.saveSettings(); 404 | }))); 405 | } 406 | }; 407 | -------------------------------------------------------------------------------- /.obsidian/plugins/novel-word-count/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "novel-word-count", 3 | "name": "Novel word count", 4 | "version": "2.5.0", 5 | "minAppVersion": "0.13.31", 6 | "description": "Displays a word count (and more!) for each file, folder and vault in the File Explorer pane.", 7 | "author": "Isaac Lyman", 8 | "authorUrl": "https://isaaclyman.com", 9 | "isDesktopOnly": false 10 | } -------------------------------------------------------------------------------- /.obsidian/plugins/novel-word-count/styles.css: -------------------------------------------------------------------------------- 1 | .nav-files-container .nav-folder-title::after, .nav-files-container .nav-file-title::after { 2 | align-items: center; 3 | content: attr(data-novel-word-count-plugin); 4 | display: flex; 5 | flex-direction: row; 6 | font-size: 0.8em; 7 | opacity: 0.75; 8 | padding: 0 4px; 9 | position: relative; 10 | text-overflow: ellipsis; 11 | white-space: nowrap; 12 | } 13 | .novel-word-count--right .nav-files-container .nav-folder-title-content, .novel-word-count--right .nav-files-container .nav-file-title-content { 14 | flex: 1; 15 | } 16 | .novel-word-count--below .nav-files-container .nav-folder-title, .novel-word-count--below .nav-files-container .nav-file-title { 17 | flex-wrap: wrap; 18 | } 19 | .novel-word-count--below .nav-files-container .nav-folder-title-content, .novel-word-count--below .nav-files-container .nav-file-title-content { 20 | flex: 100%; 21 | } 22 | .novel-word-count--below .nav-files-container .nav-folder-title::after, .novel-word-count--below .nav-files-container .nav-file-title::after { 23 | padding-left: 5px; 24 | margin-top: -3px; 25 | } 26 | 27 | /*# sourceMappingURL=styles.css.map */ 28 | -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-auto-link-title/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | THIS IS A GENERATED/BUNDLED FILE BY ROLLUP 3 | if you want to view the source visit the plugins github repository 4 | */ 5 | 6 | 'use strict'; 7 | 8 | var obsidian = require('obsidian'); 9 | 10 | /*! ***************************************************************************** 11 | Copyright (c) Microsoft Corporation. 12 | 13 | Permission to use, copy, modify, and/or distribute this software for any 14 | purpose with or without fee is hereby granted. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 17 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 18 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 19 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 20 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 21 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 22 | PERFORMANCE OF THIS SOFTWARE. 23 | ***************************************************************************** */ 24 | 25 | function __awaiter(thisArg, _arguments, P, generator) { 26 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 27 | return new (P || (P = Promise))(function (resolve, reject) { 28 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 29 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 30 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 31 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 32 | }); 33 | } 34 | 35 | const DEFAULT_SETTINGS = { 36 | regex: /^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})$/i, 37 | lineRegex: /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi, 38 | linkRegex: /^\[([^\[\]]*)\]\((https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})\)$/i, 39 | linkLineRegex: /\[([^\[\]]*)\]\((https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})\)/gi, 40 | imageRegex: /\.(gif|jpe?g|tiff?|png|webp|bmp|tga|psd|ai)$/i, 41 | shouldReplaceSelection: true, 42 | enhanceDefaultPaste: true, 43 | }; 44 | class AutoLinkTitleSettingTab extends obsidian.PluginSettingTab { 45 | constructor(app, plugin) { 46 | super(app, plugin); 47 | this.plugin = plugin; 48 | } 49 | display() { 50 | let { containerEl } = this; 51 | containerEl.empty(); 52 | new obsidian.Setting(containerEl) 53 | .setName("Enhance Default Paste") 54 | .setDesc("Fetch the link title when pasting a link in the editor with the default paste command") 55 | .addToggle((val) => val 56 | .setValue(this.plugin.settings.enhanceDefaultPaste) 57 | .onChange((value) => __awaiter(this, void 0, void 0, function* () { 58 | console.log(value); 59 | this.plugin.settings.enhanceDefaultPaste = value; 60 | yield this.plugin.saveSettings(); 61 | }))); 62 | new obsidian.Setting(containerEl) 63 | .setName("Replace Selection") 64 | .setDesc("Whether to replace a text selection with link and fetched title") 65 | .addToggle((val) => val 66 | .setValue(this.plugin.settings.shouldReplaceSelection) 67 | .onChange((value) => __awaiter(this, void 0, void 0, function* () { 68 | console.log(value); 69 | this.plugin.settings.shouldReplaceSelection = value; 70 | yield this.plugin.saveSettings(); 71 | }))); 72 | } 73 | } 74 | 75 | class EditorExtensions { 76 | static getSelectedText(editor) { 77 | if (!editor.somethingSelected()) { 78 | let wordBoundaries = this.getWordBoundaries(editor); 79 | editor.setSelection(wordBoundaries.start, wordBoundaries.end); 80 | } 81 | return editor.getSelection(); 82 | } 83 | static cursorWithinBoundaries(cursor, match) { 84 | let startIndex = match.index; 85 | let endIndex = match.index + match[0].length; 86 | return startIndex <= cursor.ch && cursor.ch <= endIndex; 87 | } 88 | static getWordBoundaries(editor) { 89 | let cursor = editor.getCursor(); 90 | // If its a normal URL token this is not a markdown link 91 | // In this case we can simply overwrite the link boundaries as-is 92 | let lineText = editor.getLine(cursor.line); 93 | // First check if we're in a link 94 | let linksInLine = lineText.matchAll(DEFAULT_SETTINGS.linkLineRegex); 95 | for (let match of linksInLine) { 96 | if (this.cursorWithinBoundaries(cursor, match)) { 97 | return { 98 | start: { line: cursor.line, ch: match.index }, 99 | end: { line: cursor.line, ch: match.index + match[0].length }, 100 | }; 101 | } 102 | } 103 | // If not, check if we're in just a standard ol' URL. 104 | let urlsInLine = lineText.matchAll(DEFAULT_SETTINGS.lineRegex); 105 | for (let match of urlsInLine) { 106 | if (this.cursorWithinBoundaries(cursor, match)) { 107 | return { 108 | start: { line: cursor.line, ch: match.index }, 109 | end: { line: cursor.line, ch: match.index + match[0].length }, 110 | }; 111 | } 112 | } 113 | return { 114 | start: cursor, 115 | end: cursor, 116 | }; 117 | } 118 | static getEditorPositionFromIndex(content, index) { 119 | let substr = content.substr(0, index); 120 | let l = 0; 121 | let offset = -1; 122 | let r = -1; 123 | for (; (r = substr.indexOf("\n", r + 1)) !== -1; l++, offset = r) 124 | ; 125 | offset += 1; 126 | let ch = content.substr(offset, index - offset).length; 127 | return { line: l, ch: ch }; 128 | } 129 | } 130 | 131 | class CheckIf { 132 | static isMarkdownLinkAlready(editor) { 133 | let cursor = editor.getCursor(); 134 | // Check if the characters before the url are ]( to indicate a markdown link 135 | var titleEnd = editor.getRange({ ch: cursor.ch - 2, line: cursor.line }, { ch: cursor.ch, line: cursor.line }); 136 | return titleEnd == "]("; 137 | } 138 | static isAfterQuote(editor) { 139 | let cursor = editor.getCursor(); 140 | // Check if the characters before the url are " or ' to indicate we want the url directly 141 | // This is common in elements like 142 | var beforeChar = editor.getRange({ ch: cursor.ch - 1, line: cursor.line }, { ch: cursor.ch, line: cursor.line }); 143 | return beforeChar == "\"" || beforeChar == "'"; 144 | } 145 | static isUrl(text) { 146 | let urlRegex = new RegExp(DEFAULT_SETTINGS.regex); 147 | return urlRegex.test(text); 148 | } 149 | static isImage(text) { 150 | let imageRegex = new RegExp(DEFAULT_SETTINGS.imageRegex); 151 | return imageRegex.test(text); 152 | } 153 | static isLinkedUrl(text) { 154 | let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex); 155 | return urlRegex.test(text); 156 | } 157 | } 158 | 159 | const electronPkg = require("electron"); 160 | function blank(text) { 161 | return text === undefined || text === null || text === ""; 162 | } 163 | function notBlank(text) { 164 | return !blank(text); 165 | } 166 | // async wrapper to load a url and settle on load finish or fail 167 | function load(window, url) { 168 | return __awaiter(this, void 0, void 0, function* () { 169 | return new Promise((resolve, reject) => { 170 | window.webContents.on("did-finish-load", (event) => resolve(event)); 171 | window.webContents.on("did-fail-load", (event) => reject(event)); 172 | window.loadURL(url); 173 | }); 174 | }); 175 | } 176 | function electronGetPageTitle(url) { 177 | return __awaiter(this, void 0, void 0, function* () { 178 | const { remote } = electronPkg; 179 | const { BrowserWindow } = remote; 180 | try { 181 | const window = new BrowserWindow({ 182 | width: 1000, 183 | height: 600, 184 | webPreferences: { 185 | webSecurity: false, 186 | nodeIntegration: true, 187 | images: false, 188 | }, 189 | show: false, 190 | }); 191 | yield load(window, url); 192 | try { 193 | const title = window.webContents.getTitle(); 194 | window.destroy(); 195 | if (notBlank(title)) { 196 | return title; 197 | } 198 | else { 199 | return url; 200 | } 201 | } 202 | catch (ex) { 203 | return url; 204 | } 205 | } 206 | catch (ex) { 207 | console.error(ex); 208 | return "Site Unreachable"; 209 | } 210 | }); 211 | } 212 | function nonElectronGetPageTitle(url) { 213 | return __awaiter(this, void 0, void 0, function* () { 214 | try { 215 | const html = yield obsidian.request({ url }); 216 | const doc = new DOMParser().parseFromString(html, "text/html"); 217 | const title = doc.querySelectorAll("title")[0]; 218 | if (title == null || blank(title === null || title === void 0 ? void 0 : title.innerText)) { 219 | // If site is javascript based and has a no-title attribute when unloaded, use it. 220 | var noTitle = title === null || title === void 0 ? void 0 : title.getAttr("no-title"); 221 | if (notBlank(noTitle)) { 222 | return noTitle; 223 | } 224 | // Otherwise if the site has no title/requires javascript simply return Title Unknown 225 | return url; 226 | } 227 | return title.innerText; 228 | } 229 | catch (ex) { 230 | console.error(ex); 231 | return "Site Unreachable"; 232 | } 233 | }); 234 | } 235 | function getPageTitle(url) { 236 | return __awaiter(this, void 0, void 0, function* () { 237 | // If we're on Desktop use the Electron scraper 238 | if (electronPkg != null) { 239 | return electronGetPageTitle(url); 240 | } 241 | else { 242 | return nonElectronGetPageTitle(url); 243 | } 244 | }); 245 | } 246 | 247 | class AutoLinkTitle extends obsidian.Plugin { 248 | onload() { 249 | return __awaiter(this, void 0, void 0, function* () { 250 | console.log("loading obsidian-auto-link-title"); 251 | yield this.loadSettings(); 252 | // Listen to paste event 253 | this.pasteFunction = this.pasteUrlWithTitle.bind(this); 254 | this.addCommand({ 255 | id: "auto-link-title-paste", 256 | name: "Paste URL and auto fetch title", 257 | callback: () => { 258 | this.manualPasteUrlWithTitle(); 259 | }, 260 | hotkeys: [], 261 | }); 262 | this.registerEvent(this.app.workspace.on("editor-paste", this.pasteFunction)); 263 | this.addCommand({ 264 | id: "enhance-url-with-title", 265 | name: "Enhance existing URL with link and title", 266 | callback: () => this.addTitleToLink(), 267 | hotkeys: [ 268 | { 269 | modifiers: ["Mod", "Shift"], 270 | key: "e", 271 | }, 272 | ], 273 | }); 274 | this.addSettingTab(new AutoLinkTitleSettingTab(this.app, this)); 275 | }); 276 | } 277 | addTitleToLink() { 278 | // Only attempt fetch if online 279 | if (!navigator.onLine) 280 | return; 281 | let editor = this.getEditor(); 282 | if (editor == null) 283 | return; 284 | let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim(); 285 | // If the cursor is on a raw html link, convert to a markdown link and fetch title 286 | if (CheckIf.isUrl(selectedText)) { 287 | this.convertUrlToTitledLink(editor, selectedText); 288 | } 289 | // If the cursor is on the URL part of a markdown link, fetch title and replace existing link title 290 | else if (CheckIf.isLinkedUrl(selectedText)) { 291 | var link = this.getUrlFromLink(selectedText); 292 | this.convertUrlToTitledLink(editor, link); 293 | } 294 | } 295 | // Simulate standard paste but using editor.replaceSelection with clipboard text since we can't seem to dispatch a paste event. 296 | manualPasteUrlWithTitle() { 297 | return __awaiter(this, void 0, void 0, function* () { 298 | let editor = this.getEditor(); 299 | // Only attempt fetch if online 300 | if (!navigator.onLine) { 301 | editor.replaceSelection(clipboardText); 302 | return; 303 | } 304 | var clipboardText = yield navigator.clipboard.readText(); 305 | if (clipboardText == null || clipboardText == "") 306 | return; 307 | // If its not a URL, we return false to allow the default paste handler to take care of it. 308 | // Similarly, image urls don't have a meaningful attribute so downloading it 309 | // to fetch the title is a waste of bandwidth. 310 | if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) { 311 | editor.replaceSelection(clipboardText); 312 | return; 313 | } 314 | let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim(); 315 | if (selectedText && !this.settings.shouldReplaceSelection) { 316 | // If there is selected text and shouldReplaceSelection is false, do not fetch title 317 | editor.replaceSelection(clipboardText); 318 | return; 319 | } 320 | // If it looks like we're pasting the url into a markdown link already, don't fetch title 321 | // as the user has already probably put a meaningful title, also it would lead to the title 322 | // being inside the link. 323 | if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) { 324 | editor.replaceSelection(clipboardText); 325 | return; 326 | } 327 | // At this point we're just pasting a link in a normal fashion, fetch its title. 328 | this.convertUrlToTitledLink(editor, clipboardText); 329 | return; 330 | }); 331 | } 332 | pasteUrlWithTitle(clipboard) { 333 | return __awaiter(this, void 0, void 0, function* () { 334 | if (!this.settings.enhanceDefaultPaste) { 335 | return; 336 | } 337 | // Only attempt fetch if online 338 | if (!navigator.onLine) 339 | return; 340 | let editor = this.getEditor(); 341 | let clipboardText = clipboard.clipboardData.getData("text/plain"); 342 | if (clipboardText == null || clipboardText == "") 343 | return; 344 | // If its not a URL, we return false to allow the default paste handler to take care of it. 345 | // Similarly, image urls don't have a meaningful <title> attribute so downloading it 346 | // to fetch the title is a waste of bandwidth. 347 | if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) { 348 | return; 349 | } 350 | let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim(); 351 | if (selectedText && !this.settings.shouldReplaceSelection) { 352 | // If there is selected text and shouldReplaceSelection is false, do not fetch title 353 | return; 354 | } 355 | // We've decided to handle the paste, stop propagation to the default handler. 356 | clipboard.stopPropagation(); 357 | clipboard.preventDefault(); 358 | // If it looks like we're pasting the url into a markdown link already, don't fetch title 359 | // as the user has already probably put a meaningful title, also it would lead to the title 360 | // being inside the link. 361 | if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) { 362 | editor.replaceSelection(clipboardText); 363 | return; 364 | } 365 | // At this point we're just pasting a link in a normal fashion, fetch its title. 366 | this.convertUrlToTitledLink(editor, clipboardText); 367 | return; 368 | }); 369 | } 370 | convertUrlToTitledLink(editor, url) { 371 | return __awaiter(this, void 0, void 0, function* () { 372 | // Generate a unique id for find/replace operations for the title. 373 | const pasteId = `Fetching Title#${this.createBlockHash()}`; 374 | // Instantly paste so you don't wonder if paste is broken 375 | editor.replaceSelection(`[${pasteId}](${url})`); 376 | // Fetch title from site, replace Fetching Title with actual title 377 | const title = yield this.fetchUrlTitle(url); 378 | const text = editor.getValue(); 379 | const start = text.indexOf(pasteId); 380 | if (start < 0) { 381 | console.log(`Unable to find text "${pasteId}" in current editor, bailing out; link ${url}`); 382 | } 383 | else { 384 | const end = start + pasteId.length; 385 | const startPos = EditorExtensions.getEditorPositionFromIndex(text, start); 386 | const endPos = EditorExtensions.getEditorPositionFromIndex(text, end); 387 | editor.replaceRange(title, startPos, endPos); 388 | } 389 | }); 390 | } 391 | fetchUrlTitle(url) { 392 | return __awaiter(this, void 0, void 0, function* () { 393 | try { 394 | const title = yield getPageTitle(url); 395 | return title.replace(/(\r\n|\n|\r)/gm, "").trim(); 396 | } 397 | catch (error) { 398 | // console.error(error) 399 | return "Site Unreachable"; 400 | } 401 | }); 402 | } 403 | getEditor() { 404 | let activeLeaf = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); 405 | if (activeLeaf == null) 406 | return; 407 | return activeLeaf.editor; 408 | } 409 | getUrlFromLink(link) { 410 | let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex); 411 | return urlRegex.exec(link)[2]; 412 | } 413 | // Custom hashid by @shabegom 414 | createBlockHash() { 415 | let result = ""; 416 | var characters = "abcdefghijklmnopqrstuvwxyz0123456789"; 417 | var charactersLength = characters.length; 418 | for (var i = 0; i < 4; i++) { 419 | result += characters.charAt(Math.floor(Math.random() * charactersLength)); 420 | } 421 | return result; 422 | } 423 | onunload() { 424 | console.log("unloading obsidian-auto-link-title"); 425 | this.app.workspace.containerEl.removeEventListener("paste", this.pasteFunction, true); 426 | } 427 | loadSettings() { 428 | return __awaiter(this, void 0, void 0, function* () { 429 | this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData()); 430 | }); 431 | } 432 | saveSettings() { 433 | return __awaiter(this, void 0, void 0, function* () { 434 | yield this.saveData(this.settings); 435 | }); 436 | } 437 | } 438 | 439 | module.exports = AutoLinkTitle; 440 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNldHRpbmdzLnRzIiwiZWRpdG9yLWVuaGFuY2VtZW50cy50cyIsImNoZWNraWYudHMiLCJzY3JhcGVyLnRzIiwibWFpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6bnVsbCwibmFtZXMiOlsiUGx1Z2luU2V0dGluZ1RhYiIsIlNldHRpbmciLCJyZXF1ZXN0IiwiUGx1Z2luIiwiTWFya2Rvd25WaWV3Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdURBO0FBQ08sU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFO0FBQzdELElBQUksU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxLQUFLLFlBQVksQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2hILElBQUksT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsVUFBVSxPQUFPLEVBQUUsTUFBTSxFQUFFO0FBQy9ELFFBQVEsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUNuRyxRQUFRLFNBQVMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FB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 441 | -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-auto-link-title/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "obsidian-auto-link-title", 3 | "name": "Auto Link Title", 4 | "version": "1.2.5", 5 | "minAppVersion": "0.12.17", 6 | "description": "This plugin automatically fetches the titles of links from the web", 7 | "author": "Matt Furden", 8 | "authorUrl": "https://github.com/zolrath", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-auto-link-title/styles.css: -------------------------------------------------------------------------------- 1 | /* no styles */ -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-languagetool-plugin/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "serverUrl": "https://api.languagetool.org", 3 | "urlMode": "standard", 4 | "glassBg": false, 5 | "shouldAutoCheck": true, 6 | "pickyMode": false 7 | } -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-languagetool-plugin/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "obsidian-languagetool-plugin", 3 | "name": "LanguageTool Integration", 4 | "version": "0.2.7", 5 | "minAppVersion": "0.13.24", 6 | "description": "Spelling and grammar checks with the LanguageTool API", 7 | "author": "Clemens Ertle", 8 | "authorUrl": "https://github.com/Clemens-E", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-languagetool-plugin/styles.css: -------------------------------------------------------------------------------- 1 | .lt-underline { 2 | cursor: pointer; 3 | transition: background-color 100ms ease-out; 4 | } 5 | 6 | .lt-underline.lt-minor { 7 | box-shadow: inset 0 -2px #e9b35f; 8 | } 9 | 10 | .lt-underline.lt-major { 11 | box-shadow: inset 0 -2px #da615c; 12 | } 13 | 14 | .lt-underline.lt-style { 15 | box-shadow: inset 0 -2px #8981f3; 16 | } 17 | 18 | .lt-underline.lt-minor:hover { 19 | background-color: #e9b35f21; 20 | } 21 | 22 | .lt-underline.lt-major:hover { 23 | background-color: #da615c21; 24 | } 25 | 26 | .lt-underline.lt-style:hover { 27 | background-color: #8981f321; 28 | } 29 | 30 | @keyframes lineInserted { 31 | from { 32 | opacity: 0; 33 | } 34 | 35 | to { 36 | opacity: 1; 37 | } 38 | } 39 | 40 | .lt-predictions-container-glass.cm-tooltip, 41 | .lt-predictions-container.cm-tooltip, 42 | .lt-predictions-container-glass, 43 | .lt-predictions-container { 44 | position: absolute; 45 | animation-duration: 150ms; 46 | animation-name: lineInserted; 47 | font-family: var(--default-font); 48 | font-size: 0.93rem; 49 | padding: 12px 0 0; 50 | background-color: var(--background-primary); 51 | border: 1px solid var(--background-modifier-border); 52 | box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); 53 | border-radius: 6px; 54 | width: 300px; 55 | line-height: 1.5; 56 | z-index: var(--layer-popover); 57 | overflow: hidden; 58 | } 59 | 60 | .lt-predictions-container-glass { 61 | background: hsla(0, 0%, 100%, 0.25); 62 | backdrop-filter: blur(12px); 63 | } 64 | 65 | .lt-predictions-container > button { 66 | transition-delay: 0.5s; 67 | } 68 | 69 | .lt-buttoncontainer:not(:empty) { 70 | padding: 10px 12px 0; 71 | } 72 | 73 | .lt-buttoncontainer > button { 74 | border: 1px solid var(--background-modifier-border); 75 | font-size: 1rem; 76 | margin-right: 4px; 77 | margin-bottom: 4px; 78 | padding: 4px 10px; 79 | } 80 | 81 | .lt-title { 82 | display: block; 83 | font-weight: 600; 84 | margin-bottom: 6px; 85 | padding: 0 12px; 86 | } 87 | 88 | .lt-message { 89 | padding: 0 12px; 90 | display: block; 91 | } 92 | 93 | .lt-ignorecontainer { 94 | padding-top: 10px; 95 | display: flex; 96 | } 97 | 98 | .lt-status-bar-btn { 99 | height: 100%; 100 | display: flex; 101 | cursor: pointer; 102 | line-height: 1; 103 | align-items: center; 104 | } 105 | 106 | .lt-status-bar-check-icon { 107 | display: block; 108 | text-decoration: underline; 109 | text-decoration-style: dotted; 110 | } 111 | 112 | .lt-ignore-btn { 113 | margin: 0; 114 | padding: 12px; 115 | display: flex; 116 | width: 100%; 117 | text-align: left; 118 | border-radius: 0; 119 | align-items: center; 120 | line-height: 1; 121 | border-top: 1px solid var(--background-modifier-border); 122 | } 123 | 124 | .lt-ignore-btn > span { 125 | display: flex; 126 | } 127 | 128 | .lt-ignore-btn > span:last-child { 129 | margin-left: 5px; 130 | } 131 | 132 | .lt-minor .lt-title > span { 133 | box-shadow: inset 0 -2px #e9b35f88; 134 | } 135 | 136 | .lt-major .lt-title > span { 137 | box-shadow: inset 0 -2px #da615c88; 138 | } 139 | 140 | .lt-style .lt-title > span { 141 | box-shadow: inset 0 -2px #8981f388; 142 | } 143 | 144 | .lt-loading > svg { 145 | animation-name: spin; 146 | animation-duration: 1s; 147 | animation-iteration-count: infinite; 148 | animation-timing-function: linear; 149 | } 150 | 151 | @keyframes spin { 152 | from { 153 | transform: rotate(0deg); 154 | } 155 | 156 | to { 157 | transform: rotate(360deg); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-reading-time/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | THIS IS A GENERATED/BUNDLED FILE BY ESBUILD 3 | if you want to view the source, please visit the github repository of this plugin 4 | */ 5 | 6 | var __create = Object.create; 7 | var __defProp = Object.defineProperty; 8 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor; 9 | var __getOwnPropNames = Object.getOwnPropertyNames; 10 | var __getProtoOf = Object.getPrototypeOf; 11 | var __hasOwnProp = Object.prototype.hasOwnProperty; 12 | var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); 13 | var __commonJS = (cb, mod) => function __require() { 14 | return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; 15 | }; 16 | var __export = (target, all) => { 17 | __markAsModule(target); 18 | for (var name in all) 19 | __defProp(target, name, { get: all[name], enumerable: true }); 20 | }; 21 | var __reExport = (target, module2, desc) => { 22 | if (module2 && typeof module2 === "object" || typeof module2 === "function") { 23 | for (let key of __getOwnPropNames(module2)) 24 | if (!__hasOwnProp.call(target, key) && key !== "default") 25 | __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); 26 | } 27 | return target; 28 | }; 29 | var __toModule = (module2) => { 30 | return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); 31 | }; 32 | var __async = (__this, __arguments, generator) => { 33 | return new Promise((resolve, reject) => { 34 | var fulfilled = (value) => { 35 | try { 36 | step(generator.next(value)); 37 | } catch (e) { 38 | reject(e); 39 | } 40 | }; 41 | var rejected = (value) => { 42 | try { 43 | step(generator.throw(value)); 44 | } catch (e) { 45 | reject(e); 46 | } 47 | }; 48 | var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); 49 | step((generator = generator.apply(__this, __arguments)).next()); 50 | }); 51 | }; 52 | 53 | // node_modules/parse-ms/index.js 54 | var require_parse_ms = __commonJS({ 55 | "node_modules/parse-ms/index.js"(exports, module2) { 56 | "use strict"; 57 | module2.exports = (milliseconds) => { 58 | if (typeof milliseconds !== "number") { 59 | throw new TypeError("Expected a number"); 60 | } 61 | const roundTowardsZero = milliseconds > 0 ? Math.floor : Math.ceil; 62 | return { 63 | days: roundTowardsZero(milliseconds / 864e5), 64 | hours: roundTowardsZero(milliseconds / 36e5) % 24, 65 | minutes: roundTowardsZero(milliseconds / 6e4) % 60, 66 | seconds: roundTowardsZero(milliseconds / 1e3) % 60, 67 | milliseconds: roundTowardsZero(milliseconds) % 1e3, 68 | microseconds: roundTowardsZero(milliseconds * 1e3) % 1e3, 69 | nanoseconds: roundTowardsZero(milliseconds * 1e6) % 1e3 70 | }; 71 | }; 72 | } 73 | }); 74 | 75 | // node_modules/pretty-ms/index.js 76 | var require_pretty_ms = __commonJS({ 77 | "node_modules/pretty-ms/index.js"(exports, module2) { 78 | "use strict"; 79 | var parseMilliseconds = require_parse_ms(); 80 | var pluralize = (word, count) => count === 1 ? word : `${word}s`; 81 | var SECOND_ROUNDING_EPSILON = 1e-7; 82 | module2.exports = (milliseconds, options = {}) => { 83 | if (!Number.isFinite(milliseconds)) { 84 | throw new TypeError("Expected a finite number"); 85 | } 86 | if (options.colonNotation) { 87 | options.compact = false; 88 | options.formatSubMilliseconds = false; 89 | options.separateMilliseconds = false; 90 | options.verbose = false; 91 | } 92 | if (options.compact) { 93 | options.secondsDecimalDigits = 0; 94 | options.millisecondsDecimalDigits = 0; 95 | } 96 | const result = []; 97 | const floorDecimals = (value, decimalDigits) => { 98 | const flooredInterimValue = Math.floor(value * 10 ** decimalDigits + SECOND_ROUNDING_EPSILON); 99 | const flooredValue = Math.round(flooredInterimValue) / 10 ** decimalDigits; 100 | return flooredValue.toFixed(decimalDigits); 101 | }; 102 | const add = (value, long, short, valueString) => { 103 | if ((result.length === 0 || !options.colonNotation) && value === 0 && !(options.colonNotation && short === "m")) { 104 | return; 105 | } 106 | valueString = (valueString || value || "0").toString(); 107 | let prefix; 108 | let suffix; 109 | if (options.colonNotation) { 110 | prefix = result.length > 0 ? ":" : ""; 111 | suffix = ""; 112 | const wholeDigits = valueString.includes(".") ? valueString.split(".")[0].length : valueString.length; 113 | const minLength = result.length > 0 ? 2 : 1; 114 | valueString = "0".repeat(Math.max(0, minLength - wholeDigits)) + valueString; 115 | } else { 116 | prefix = ""; 117 | suffix = options.verbose ? " " + pluralize(long, value) : short; 118 | } 119 | result.push(prefix + valueString + suffix); 120 | }; 121 | const parsed = parseMilliseconds(milliseconds); 122 | add(Math.trunc(parsed.days / 365), "year", "y"); 123 | add(parsed.days % 365, "day", "d"); 124 | add(parsed.hours, "hour", "h"); 125 | add(parsed.minutes, "minute", "m"); 126 | if (options.separateMilliseconds || options.formatSubMilliseconds || !options.colonNotation && milliseconds < 1e3) { 127 | add(parsed.seconds, "second", "s"); 128 | if (options.formatSubMilliseconds) { 129 | add(parsed.milliseconds, "millisecond", "ms"); 130 | add(parsed.microseconds, "microsecond", "\xB5s"); 131 | add(parsed.nanoseconds, "nanosecond", "ns"); 132 | } else { 133 | const millisecondsAndBelow = parsed.milliseconds + parsed.microseconds / 1e3 + parsed.nanoseconds / 1e6; 134 | const millisecondsDecimalDigits = typeof options.millisecondsDecimalDigits === "number" ? options.millisecondsDecimalDigits : 0; 135 | const roundedMiliseconds = millisecondsAndBelow >= 1 ? Math.round(millisecondsAndBelow) : Math.ceil(millisecondsAndBelow); 136 | const millisecondsString = millisecondsDecimalDigits ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) : roundedMiliseconds; 137 | add(Number.parseFloat(millisecondsString, 10), "millisecond", "ms", millisecondsString); 138 | } 139 | } else { 140 | const seconds = milliseconds / 1e3 % 60; 141 | const secondsDecimalDigits = typeof options.secondsDecimalDigits === "number" ? options.secondsDecimalDigits : 1; 142 | const secondsFixed = floorDecimals(seconds, secondsDecimalDigits); 143 | const secondsString = options.keepDecimalsOnWholeSeconds ? secondsFixed : secondsFixed.replace(/\.0+$/, ""); 144 | add(Number.parseFloat(secondsString, 10), "second", "s", secondsString); 145 | } 146 | if (result.length === 0) { 147 | return "0" + (options.verbose ? " milliseconds" : "ms"); 148 | } 149 | if (options.compact) { 150 | return result[0]; 151 | } 152 | if (typeof options.unitCount === "number") { 153 | const separator = options.colonNotation ? "" : " "; 154 | return result.slice(0, Math.max(options.unitCount, 1)).join(separator); 155 | } 156 | return options.colonNotation ? result.join("") : result.join(" "); 157 | }; 158 | } 159 | }); 160 | 161 | // node_modules/reading-time/lib/reading-time.js 162 | var require_reading_time = __commonJS({ 163 | "node_modules/reading-time/lib/reading-time.js"(exports, module2) { 164 | "use strict"; 165 | function codeIsInRanges(number, arrayOfRanges) { 166 | return arrayOfRanges.some(([lowerBound, upperBound]) => lowerBound <= number && number <= upperBound); 167 | } 168 | function isCJK(c) { 169 | if (typeof c !== "string") { 170 | return false; 171 | } 172 | const charCode = c.charCodeAt(0); 173 | return codeIsInRanges(charCode, [ 174 | [12352, 12447], 175 | [19968, 40959], 176 | [44032, 55203], 177 | [131072, 191456] 178 | ]); 179 | } 180 | function isAnsiWordBound(c) { 181 | return " \n\r ".includes(c); 182 | } 183 | function isPunctuation(c) { 184 | if (typeof c !== "string") { 185 | return false; 186 | } 187 | const charCode = c.charCodeAt(0); 188 | return codeIsInRanges(charCode, [ 189 | [33, 47], 190 | [58, 64], 191 | [91, 96], 192 | [123, 126], 193 | [12288, 12351], 194 | [65280, 65519] 195 | ]); 196 | } 197 | function readingTime2(text, options = {}) { 198 | let words = 0, start = 0, end = text.length - 1; 199 | const wordsPerMinute = options.wordsPerMinute || 200; 200 | const isWordBound = options.wordBound || isAnsiWordBound; 201 | while (isWordBound(text[start])) 202 | start++; 203 | while (isWordBound(text[end])) 204 | end--; 205 | const normalizedText = `${text} 206 | `; 207 | for (let i = start; i <= end; i++) { 208 | if (isCJK(normalizedText[i]) || !isWordBound(normalizedText[i]) && (isWordBound(normalizedText[i + 1]) || isCJK(normalizedText[i + 1]))) { 209 | words++; 210 | } 211 | if (isCJK(normalizedText[i])) { 212 | while (i <= end && (isPunctuation(normalizedText[i + 1]) || isWordBound(normalizedText[i + 1]))) { 213 | i++; 214 | } 215 | } 216 | } 217 | const minutes = words / wordsPerMinute; 218 | const time = Math.round(minutes * 60 * 1e3); 219 | const displayed = Math.ceil(minutes.toFixed(2)); 220 | return { 221 | text: displayed + " min read", 222 | minutes, 223 | time, 224 | words 225 | }; 226 | } 227 | module2.exports = readingTime2; 228 | } 229 | }); 230 | 231 | // src/main.ts 232 | __export(exports, { 233 | default: () => ReadingTime 234 | }); 235 | var import_obsidian2 = __toModule(require("obsidian")); 236 | 237 | // src/settings.ts 238 | var import_obsidian = __toModule(require("obsidian")); 239 | var RT_DEFAULT_SETTINGS = { 240 | readingSpeed: 200, 241 | format: "default", 242 | appendText: "read" 243 | }; 244 | var ReadingTimeSettingsTab = class extends import_obsidian.PluginSettingTab { 245 | constructor(app, plugin) { 246 | super(app, plugin); 247 | this.plugin = plugin; 248 | } 249 | display() { 250 | const { containerEl } = this; 251 | containerEl.empty(); 252 | new import_obsidian.Setting(containerEl).setName("Reading speed").setDesc("Words per minute used for reading speed (default: 200).").addText((text) => { 253 | text.setPlaceholder("Example: 200").setValue(this.plugin.settings.readingSpeed.toString()).onChange((value) => __async(this, null, function* () { 254 | this.plugin.settings.readingSpeed = parseInt(value.trim()); 255 | yield this.plugin.saveSettings().then(this.plugin.calculateReadingTime); 256 | })); 257 | }); 258 | new import_obsidian.Setting(this.containerEl).setName("Format").setDesc("Choose the output format").addDropdown((dropdown) => dropdown.addOption("default", "Default (10 min)").addOption("compact", "Compact (10m)").addOption("simple", "Simple (10m 4s)").addOption("verbose", "Verbose (10 minutes 4 seconds)").addOption("digital", "Colon Notation (10:04)").setValue(this.plugin.settings.format).onChange((value) => __async(this, null, function* () { 259 | this.plugin.settings.format = value; 260 | yield this.plugin.saveSettings().then(this.plugin.calculateReadingTime); 261 | }))); 262 | new import_obsidian.Setting(this.containerEl).setName("Append Text").setDesc("Append 'read' to formatted string.").addText((text) => text.setValue(this.plugin.settings.appendText).onChange((value) => __async(this, null, function* () { 263 | this.plugin.settings.appendText = value.trim(); 264 | yield this.plugin.saveSettings().then(this.plugin.calculateReadingTime); 265 | }))); 266 | } 267 | }; 268 | 269 | // src/helpers.ts 270 | var import_pretty_ms = __toModule(require_pretty_ms()); 271 | var ReadTime = require_reading_time(); 272 | function readingTimeText(text, plugin) { 273 | const result = ReadTime(text, { 274 | wordsPerMinute: plugin.settings.readingSpeed 275 | }); 276 | let options = { 277 | secondsDecimalDigits: 0 278 | }; 279 | switch (plugin.settings.format) { 280 | case "simple": 281 | break; 282 | case "compact": 283 | if (result.time > 36e5) { 284 | options.unitCount = 2; 285 | } else { 286 | options.compact = true; 287 | } 288 | break; 289 | case "verbose": 290 | options.verbose = true; 291 | break; 292 | case "digital": 293 | options.colonNotation = true; 294 | break; 295 | case "default": 296 | return plugin.settings.appendText ? result.text : result.text.replace(" read", ""); 297 | } 298 | let output = (0, import_pretty_ms.default)(result.time, options); 299 | return plugin.settings.appendText ? `${output} ${plugin.settings.appendText}` : output; 300 | } 301 | 302 | // src/main.ts 303 | var ReadingTime = class extends import_obsidian2.Plugin { 304 | constructor() { 305 | super(...arguments); 306 | this.calculateReadingTime = () => { 307 | const mdView = this.app.workspace.getActiveViewOfType(import_obsidian2.MarkdownView); 308 | if (mdView && mdView.getViewData()) { 309 | const result = readingTimeText(mdView.getViewData(), this); 310 | this.statusBar.setText(`${result}`); 311 | } else { 312 | this.statusBar.setText("0 min read"); 313 | } 314 | }; 315 | } 316 | onload() { 317 | return __async(this, null, function* () { 318 | yield this.loadSettings(); 319 | this.statusBar = this.addStatusBarItem(); 320 | this.statusBar.setText(""); 321 | this.addSettingTab(new ReadingTimeSettingsTab(this.app, this)); 322 | this.addCommand({ 323 | id: "reading-time-editor-command", 324 | name: "Selected Text", 325 | editorCallback: (editor, view) => { 326 | new ReadingTimeModal(this.app, editor, this).open(); 327 | } 328 | }); 329 | this.registerEvent(this.app.workspace.on("file-open", this.calculateReadingTime)); 330 | this.registerEvent(this.app.workspace.on("editor-change", (0, import_obsidian2.debounce)(this.calculateReadingTime, 1e3))); 331 | }); 332 | } 333 | loadSettings() { 334 | return __async(this, null, function* () { 335 | this.settings = Object.assign({}, RT_DEFAULT_SETTINGS, yield this.loadData()); 336 | }); 337 | } 338 | saveSettings() { 339 | return __async(this, null, function* () { 340 | yield this.saveData(this.settings); 341 | }); 342 | } 343 | }; 344 | var ReadingTimeModal = class extends import_obsidian2.Modal { 345 | constructor(app, editor, plugin) { 346 | super(app); 347 | this.editor = editor; 348 | this.plugin = plugin; 349 | } 350 | onOpen() { 351 | const { contentEl, titleEl } = this; 352 | titleEl.setText("Reading Time of Selected Text"); 353 | const stats = readingTime(this.editor.getSelection(), this.plugin); 354 | contentEl.setText(`${stats} (at ${this.plugin.settings.readingSpeed} wpm)`); 355 | } 356 | onClose() { 357 | const { contentEl } = this; 358 | contentEl.empty(); 359 | } 360 | }; 361 | /*! 362 | * reading-time 363 | * Copyright (c) Nicolas Gryman <ngryman@gmail.com> 364 | * MIT Licensed 365 | */ 366 | -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-reading-time/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "obsidian-reading-time", 3 | "name": "Reading Time", 4 | "description": "Add the current note's reading time to Obsidian's status bar.", 5 | "version": "1.1.1", 6 | "minAppVersion": "0.12.17", 7 | "isDesktopOnly": false, 8 | "author": "avr", 9 | "authorUrl": "https://github.com/avr" 10 | } -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-tasks-plugin/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "globalFilter": "#task", 3 | "removeGlobalFilter": false 4 | } -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-tasks-plugin/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "obsidian-tasks-plugin", 3 | "name": "Tasks", 4 | "version": "1.7.0", 5 | "minAppVersion": "0.13.21", 6 | "description": "Task management for Obsidian", 7 | "author": "Martin Schenck", 8 | "authorUrl": "https://github.com/obsidian-tasks-group", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/obsidian-tasks-plugin/styles.css: -------------------------------------------------------------------------------- 1 | .tasks-count { 2 | color: var(--text-faint); 3 | padding-left: 20px; 4 | } 5 | 6 | /* Pencil icon. */ 7 | .tasks-edit { 8 | background-color: var(--text-faint); 9 | mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20aria-hidden%3D%22true%22%20focusable%3D%22false%22%20width%3D%221em%22%20height%3D%221em%22%20style%3D%22-ms-transform%3A%20rotate(360deg)%3B%20-webkit-transform%3A%20rotate(360deg)%3B%20transform%3A%20rotate(360deg)%3B%22%20preserveAspectRatio%3D%22xMidYMid%20meet%22%20viewBox%3D%220%200%201536%201536%22%3E%3Cpath%20d%3D%22M363%201408l91-91l-235-235l-91%2091v107h128v128h107zm523-928q0-22-22-22q-10%200-17%207l-542%20542q-7%207-7%2017q0%2022%2022%2022q10%200%2017-7l542-542q7-7%207-17zm-54-192l416%20416l-832%20832H0v-416zm683%2096q0%2053-37%2090l-166%20166l-416-416l166-165q36-38%2090-38q53%200%2091%2038l235%20234q37%2039%2037%2091z%22%20fill%3D%22%23626262%22%2F%3E%3C%2Fsvg%3E"); 10 | -webkit-mask-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20aria-hidden%3D%22true%22%20focusable%3D%22false%22%20width%3D%221em%22%20height%3D%221em%22%20style%3D%22-ms-transform%3A%20rotate(360deg)%3B%20-webkit-transform%3A%20rotate(360deg)%3B%20transform%3A%20rotate(360deg)%3B%22%20preserveAspectRatio%3D%22xMidYMid%20meet%22%20viewBox%3D%220%200%201536%201536%22%3E%3Cpath%20d%3D%22M363%201408l91-91l-235-235l-91%2091v107h128v128h107zm523-928q0-22-22-22q-10%200-17%207l-542%20542q-7%207-7%2017q0%2022%2022%2022q10%200%2017-7l542-542q7-7%207-17zm-54-192l416%20416l-832%20832H0v-416zm683%2096q0%2053-37%2090l-166%20166l-416-416l166-165q36-38%2090-38q53%200%2091%2038l235%20234q37%2039%2037%2091z%22%20fill%3D%22%23626262%22%2F%3E%3C%2Fsvg%3E"); 11 | display: inline-block; 12 | width: 1em; 13 | height: 1em; 14 | vertical-align: middle; 15 | margin-left: 0.3em; 16 | cursor: pointer; 17 | } 18 | 19 | .internal-link.internal-link-short-mode { 20 | text-decoration: none; 21 | } 22 | 23 | .tasks-list-text { 24 | position: relative; 25 | } 26 | 27 | .tasks-list-text .tooltip { 28 | position: absolute; 29 | top: 0px; 30 | left: 0px; 31 | white-space: nowrap; 32 | } 33 | 34 | .tasks-setting-important { 35 | color: red; 36 | font-weight: bold; 37 | } 38 | 39 | .tasks-modal label { 40 | margin: 5px 0 5px 0; 41 | } 42 | 43 | .tasks-modal input[type=text] { 44 | width: 100%; 45 | } 46 | 47 | .tasks-modal hr { 48 | margin: 10px 0 10px 0; 49 | } 50 | 51 | .tasks-modal-date { 52 | margin-bottom: 10px; 53 | } 54 | -------------------------------------------------------------------------------- /.obsidian/plugins/periodic-notes/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "showGettingStartedBanner": false, 3 | "hasMigratedDailyNoteSettings": false, 4 | "hasMigratedWeeklyNoteSettings": false, 5 | "daily": { 6 | "format": "", 7 | "template": "", 8 | "folder": "300 Alignment", 9 | "enabled": true 10 | }, 11 | "weekly": { 12 | "format": "", 13 | "template": "", 14 | "folder": "300 Alignment", 15 | "enabled": true 16 | }, 17 | "monthly": { 18 | "format": "", 19 | "template": "", 20 | "folder": "300 Alignment", 21 | "enabled": true 22 | }, 23 | "quarterly": { 24 | "format": "", 25 | "template": "", 26 | "folder": "300 Alignment", 27 | "enabled": true 28 | }, 29 | "yearly": { 30 | "format": "", 31 | "template": "", 32 | "folder": "300 Alignment", 33 | "enabled": true 34 | } 35 | } -------------------------------------------------------------------------------- /.obsidian/plugins/periodic-notes/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "periodic-notes", 3 | "name": "Periodic Notes", 4 | "description": "Create/manage your daily, weekly, and monthly notes", 5 | "version": "0.0.17", 6 | "author": "Liam Cain", 7 | "authorUrl": "https://github.com/liamcain/", 8 | "isDesktopOnly": false, 9 | "minAppVersion": "0.10.11" 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/periodic-notes/styles.css: -------------------------------------------------------------------------------- 1 | .periodic-modal { 2 | min-width: 40vw; 3 | } 4 | 5 | .settings-banner { 6 | background-color: var(--background-primary-alt); 7 | border-radius: 8px; 8 | border: 1px solid var(--background-modifier-border); 9 | margin-bottom: 1em; 10 | margin-top: 1em; 11 | padding: 1.5em; 12 | text-align: left; 13 | } 14 | 15 | .settings-banner h3 { 16 | margin-top: 0; 17 | } 18 | 19 | .settings-banner h4 { 20 | margin-bottom: 0.25em; 21 | } 22 | 23 | .has-error { 24 | color: var(--text-error); 25 | } 26 | 27 | input.has-error { 28 | color: var(--text-error); 29 | border-color: var(--text-error); 30 | } 31 | -------------------------------------------------------------------------------- /.obsidian/plugins/table-editor-obsidian/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "formatType": "normal", 3 | "showRibbonIcon": true, 4 | "bindEnter": true, 5 | "bindTab": true 6 | } -------------------------------------------------------------------------------- /.obsidian/plugins/table-editor-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "table-editor-obsidian", 3 | "name": "Advanced Tables", 4 | "author": "Tony Grosinger", 5 | "authorUrl": "https://grosinger.net", 6 | "description": "Improved table navigation, formatting, manipulation, and formulas", 7 | "isDesktopOnly": false, 8 | "minAppVersion": "0.13.8", 9 | "version": "0.17.3", 10 | "js": "main.js" 11 | } 12 | -------------------------------------------------------------------------------- /.obsidian/plugins/table-editor-obsidian/styles.css: -------------------------------------------------------------------------------- 1 | .HyperMD-table-row span.cm-inline-code { 2 | font-size: 100%; 3 | } 4 | 5 | .widget-icon { 6 | width: 20px; 7 | height: 20px; 8 | fill: var(--text-muted); 9 | } 10 | 11 | .widget-icon:hover { 12 | fill: var(--text-normal); 13 | } 14 | 15 | .advanced-tables-csv-export textarea { 16 | height: 200px; 17 | width: 100%; 18 | } 19 | 20 | .advanced-tables-donation { 21 | width: 70%; 22 | margin: 0 auto; 23 | text-align: center; 24 | } 25 | 26 | .advanced-tables-donate-button { 27 | margin: 10px; 28 | } 29 | -------------------------------------------------------------------------------- /.obsidian/plugins/templater-obsidian/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "command_timeout": 5, 3 | "templates_folder": "800 Templates", 4 | "templates_pairs": [ 5 | [ 6 | "", 7 | "" 8 | ] 9 | ], 10 | "trigger_on_file_creation": false, 11 | "auto_jump_to_cursor": true, 12 | "enable_system_commands": false, 13 | "shell_path": "", 14 | "user_scripts_folder": "", 15 | "enable_folder_templates": true, 16 | "folder_templates": [ 17 | { 18 | "folder": "", 19 | "template": "" 20 | } 21 | ], 22 | "syntax_highlighting": true, 23 | "enabled_templates_hotkeys": [ 24 | "" 25 | ], 26 | "startup_templates": [ 27 | "" 28 | ] 29 | } -------------------------------------------------------------------------------- /.obsidian/plugins/templater-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "templater-obsidian", 3 | "name": "Templater", 4 | "version": "1.12.0", 5 | "description": "Create and use templates", 6 | "minAppVersion": "0.11.13", 7 | "author": "SilentVoid", 8 | "authorUrl": "https://github.com/SilentVoid13", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/templater-obsidian/styles.css: -------------------------------------------------------------------------------- 1 | .templater_search { 2 | width: calc(100% - 20px); 3 | } 4 | 5 | .templater_div { 6 | border-top: 1px solid var(--background-modifier-border); 7 | } 8 | 9 | .templater_div > .setting-item { 10 | border-top: none !important; 11 | align-self: center; 12 | } 13 | 14 | .templater_div > .setting-item > .setting-item-control { 15 | justify-content: space-around; 16 | padding: 0; 17 | width: 100%; 18 | } 19 | 20 | .templater_div 21 | > .setting-item 22 | > .setting-item-control 23 | > .setting-editor-extra-setting-button { 24 | align-self: center; 25 | } 26 | 27 | .templater_title { 28 | margin: 0; 29 | padding: 0; 30 | margin-top: 5px; 31 | text-align: center; 32 | } 33 | 34 | .templater_template { 35 | align-self: center; 36 | margin-left: 5px; 37 | margin-right: 5px; 38 | width: 70%; 39 | } 40 | 41 | .templater_cmd { 42 | margin-left: 5px; 43 | margin-right: 5px; 44 | font-size: 14px; 45 | width: 100%; 46 | } 47 | 48 | .templater_div2 > .setting-item { 49 | align-content: center; 50 | justify-content: center; 51 | } 52 | 53 | .templater-prompt-div { 54 | display: flex; 55 | } 56 | 57 | .templater-prompt-form { 58 | display: flex; 59 | flex-grow: 1; 60 | } 61 | 62 | .templater-prompt-input { 63 | flex-grow: 1; 64 | } 65 | 66 | .cm-s-obsidian .templater-command-bg { 67 | left: 0px; 68 | right: 0px; 69 | background-color: var(--background-primary-alt); 70 | } 71 | 72 | .cm-s-obsidian .cm-templater-command { 73 | font-size: 0.85em; 74 | font-family: var(--font-monospace); 75 | line-height: 1.3; 76 | } 77 | 78 | .cm-s-obsidian .templater-inline .cm-templater-command { 79 | background-color: var(--background-primary-alt); 80 | } 81 | 82 | .cm-s-obsidian .cm-templater-command.cm-templater-opening-tag { 83 | font-weight: bold; 84 | } 85 | 86 | .cm-s-obsidian .cm-templater-command.cm-templater-closing-tag { 87 | font-weight: bold; 88 | } 89 | 90 | .cm-s-obsidian .cm-templater-command.cm-templater-interpolation-tag { 91 | color: #008bff; 92 | } 93 | 94 | .cm-s-obsidian .cm-templater-command.cm-templater-execution-tag { 95 | color: #c0d700; 96 | } 97 | 98 | .cm-s-obsidian .cm-templater-command.cm-templater-raw-tag { 99 | color: green; 100 | } 101 | 102 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-keyword { 103 | color: #00a7aa; 104 | font-weight: normal; 105 | } 106 | 107 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-atom { 108 | color: #f39b35; 109 | } 110 | 111 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-number { 112 | color: #a06fca; 113 | } 114 | 115 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-type { 116 | color: #a06fca; 117 | } 118 | 119 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-def { 120 | color: #98e342; 121 | } 122 | 123 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-property { 124 | color: #d4d4d4; 125 | } 126 | 127 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-variable { 128 | color: #d4d4d4; 129 | } 130 | 131 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-variable-2 { 132 | color: #da7dae; 133 | } 134 | 135 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-variable-3 { 136 | color: #a06fca; 137 | } 138 | 139 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-type.cm-def { 140 | color: #fc4384; 141 | } 142 | 143 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-property.cm-def { 144 | color: #fc4384; 145 | } 146 | 147 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-callee { 148 | color: #fc4384; 149 | } 150 | 151 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-operator { 152 | color: #fc4384; 153 | } 154 | 155 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-qualifier { 156 | color: #fc4384; 157 | } 158 | 159 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-tag { 160 | color: #fc4384; 161 | } 162 | 163 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-tag.cm-bracket { 164 | color: #d4d4d4; 165 | } 166 | 167 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-attribute { 168 | color: #a06fca; 169 | } 170 | 171 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-comment { 172 | color: #696d70; 173 | } 174 | 175 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-comment.cm-tag { 176 | color: #fc4384; 177 | } 178 | 179 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-comment.cm-attribute { 180 | color: #d4d4d4; 181 | } 182 | 183 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-string { 184 | color: #e6db74; 185 | } 186 | 187 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-string-2 { 188 | color: #f39b35; 189 | } 190 | 191 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-meta { 192 | color: #d4d4d4; 193 | background: inherit; 194 | } 195 | 196 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-builtin { 197 | color: #fc4384; 198 | } 199 | 200 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-header { 201 | color: #da7dae; 202 | } 203 | 204 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-hr { 205 | color: #98e342; 206 | } 207 | 208 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-link { 209 | color: #696d70; 210 | } 211 | 212 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-error { 213 | border-bottom: 1px solid #c42412; 214 | } 215 | 216 | .theme-dark .cm-s-obsidian pre.HyperMD-codeblock .cm-keyword { 217 | font-weight: normal; 218 | } 219 | 220 | .theme-dark 221 | .cm-s-obsidian 222 | .cm-templater-command.CodeMirror-activeline-background { 223 | background: #272727; 224 | } 225 | 226 | .theme-dark .cm-s-obsidian .cm-templater-command.CodeMirror-matchingbracket { 227 | outline: 1px solid grey; 228 | color: #d4d4d4 !important; 229 | } 230 | 231 | .CodeMirror-hints { 232 | position: absolute; 233 | z-index: 10; 234 | overflow: hidden; 235 | list-style: none; 236 | 237 | margin: 0; 238 | padding: 2px; 239 | 240 | -webkit-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2); 241 | -moz-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2); 242 | box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2); 243 | border-radius: 3px; 244 | border: 1px solid silver; 245 | 246 | background: white; 247 | font-size: 90%; 248 | font-family: monospace; 249 | 250 | max-height: 20em; 251 | overflow-y: auto; 252 | } 253 | 254 | .CodeMirror-hint { 255 | margin: 0; 256 | padding: 0 4px; 257 | border-radius: 2px; 258 | white-space: pre; 259 | color: black; 260 | cursor: pointer; 261 | } 262 | 263 | li.CodeMirror-hint-active { 264 | background: #08f; 265 | color: white; 266 | } 267 | -------------------------------------------------------------------------------- /.obsidian/starred.json: -------------------------------------------------------------------------------- 1 | { 2 | "items": [ 3 | { 4 | "type": "file", 5 | "title": "00 ❗ Readme", 6 | "path": "000 Inbox/00 ❗ Readme.md" 7 | }, 8 | { 9 | "type": "file", 10 | "title": "00 🧰 Setup", 11 | "path": "100 Projects/Setup/00 🧰 Setup.md" 12 | }, 13 | { 14 | "type": "file", 15 | "title": "110 🎀 Example Discipline", 16 | "path": "200 Disciplines/210 🎀 Well-being (EXAMPLE)/210 🎀 Well-being (EXAMPLE).md" 17 | }, 18 | { 19 | "type": "file", 20 | "title": "00 🔀 Divergence to Disciplines", 21 | "path": "999 Setup/00 🔀 Divergence to Disciplines.md" 22 | }, 23 | { 24 | "type": "file", 25 | "title": "01 🔂 Convergence to Ikigai", 26 | "path": "999 Setup/01 🔂 Convergence to Ikigai.md" 27 | }, 28 | { 29 | "type": "file", 30 | "title": "02 🎎 Ikigai Expansion", 31 | "path": "999 Setup/02 🎎 Ikigai Expansion.md" 32 | }, 33 | { 34 | "type": "file", 35 | "title": "00 🎁 Example Project", 36 | "path": "100 Disciplines/110 🎀 Example Discipline/Example Project/00 🎁 Example Project.md" 37 | }, 38 | { 39 | "type": "file", 40 | "title": "00 ✨ Example Habit", 41 | "path": "100 Disciplines/110 🎀 Example Discipline/00 Habit - Example Habit/00 ✨ Example Habit.md" 42 | }, 43 | { 44 | "type": "file", 45 | "title": "90 🗃️ Master Backlog", 46 | "path": "01 🗃️ Master Backlog.md" 47 | }, 48 | { 49 | "type": "file", 50 | "title": "90 👀 Readme", 51 | "path": "00 ♻ Memory Flow Interface.md" 52 | }, 53 | { 54 | "type": "file", 55 | "title": "91 📝 Directory", 56 | "path": "00 📝 Directory.md" 57 | }, 58 | { 59 | "type": "file", 60 | "title": "00 🏠 Main Dashboard", 61 | "path": "01 🏠 Main Dashboard.md" 62 | }, 63 | { 64 | "type": "file", 65 | "title": "Workbench", 66 | "path": "Workbench.md" 67 | }, 68 | { 69 | "type": "file", 70 | "title": "Preface", 71 | "path": "Preface.md" 72 | } 73 | ] 74 | } -------------------------------------------------------------------------------- /.obsidian/workspace: -------------------------------------------------------------------------------- 1 | { 2 | "main": { 3 | "id": "c419ae07d5d81988", 4 | "type": "split", 5 | "children": [ 6 | { 7 | "id": "7ea162fe62ee3290", 8 | "type": "leaf", 9 | "state": { 10 | "type": "markdown", 11 | "state": { 12 | "file": "00 ♻ Memory Flow Interface.md", 13 | "mode": "preview", 14 | "source": false 15 | } 16 | } 17 | } 18 | ], 19 | "direction": "vertical" 20 | }, 21 | "left": { 22 | "id": "617303f2f182a3bf", 23 | "type": "split", 24 | "children": [ 25 | { 26 | "id": "86da0a92365affaf", 27 | "type": "tabs", 28 | "dimension": 26.02996254681648, 29 | "children": [ 30 | { 31 | "id": "47852916ae5bebee", 32 | "type": "leaf", 33 | "state": { 34 | "type": "starred", 35 | "state": {} 36 | } 37 | } 38 | ] 39 | }, 40 | { 41 | "id": "a670690c1135b2bb", 42 | "type": "tabs", 43 | "dimension": 73.97003745318352, 44 | "children": [ 45 | { 46 | "id": "fa11ae403f88cd9d", 47 | "type": "leaf", 48 | "state": { 49 | "type": "file-explorer", 50 | "state": {} 51 | } 52 | }, 53 | { 54 | "id": "e54b1d98790c0e3f", 55 | "type": "leaf", 56 | "state": { 57 | "type": "search", 58 | "state": { 59 | "query": "", 60 | "matchingCase": false, 61 | "explainSearch": false, 62 | "collapseAll": false, 63 | "extraContext": false, 64 | "sortOrder": "alphabetical" 65 | } 66 | } 67 | }, 68 | { 69 | "id": "e28cb742ca38d24c", 70 | "type": "leaf", 71 | "state": { 72 | "type": "tag", 73 | "state": { 74 | "sortOrder": "frequency", 75 | "useHierarchy": true 76 | } 77 | } 78 | } 79 | ] 80 | } 81 | ], 82 | "direction": "horizontal", 83 | "width": 388 84 | }, 85 | "right": { 86 | "id": "36aa89e907fd6bc1", 87 | "type": "split", 88 | "children": [ 89 | { 90 | "id": "b43dcb35aa923479", 91 | "type": "tabs", 92 | "dimension": 47.90575916230367, 93 | "children": [ 94 | { 95 | "id": "3e7ef70c26947fa0", 96 | "type": "leaf", 97 | "state": { 98 | "type": "localgraph", 99 | "state": { 100 | "file": "00 ♻ Memory Flow Interface.md", 101 | "options": { 102 | "collapse-filter": false, 103 | "search": "", 104 | "localJumps": 1, 105 | "localBacklinks": false, 106 | "localForelinks": true, 107 | "localInterlinks": false, 108 | "showTags": false, 109 | "showAttachments": false, 110 | "hideUnresolved": false, 111 | "collapse-color-groups": true, 112 | "colorGroups": [], 113 | "collapse-display": true, 114 | "showArrow": false, 115 | "textFadeMultiplier": 0, 116 | "nodeSizeMultiplier": 1, 117 | "lineSizeMultiplier": 1, 118 | "collapse-forces": true, 119 | "centerStrength": 0.808547008547009, 120 | "repelStrength": 4, 121 | "linkStrength": 0.370940170940171, 122 | "linkDistance": 30, 123 | "scale": 1.0000000000000002, 124 | "close": true 125 | } 126 | } 127 | } 128 | }, 129 | { 130 | "id": "97d8d1242d8bfc61", 131 | "type": "leaf", 132 | "state": { 133 | "type": "calendar", 134 | "state": {} 135 | } 136 | } 137 | ] 138 | }, 139 | { 140 | "id": "5116d57311ec98b6", 141 | "type": "tabs", 142 | "dimension": 52.09424083769634, 143 | "children": [ 144 | { 145 | "id": "a853884b70beb523", 146 | "type": "leaf", 147 | "state": { 148 | "type": "outline", 149 | "state": { 150 | "file": "00 ♻ Memory Flow Interface.md" 151 | } 152 | } 153 | }, 154 | { 155 | "id": "16a2297c4248b84a", 156 | "type": "leaf", 157 | "state": { 158 | "type": "backlink", 159 | "state": { 160 | "file": "00 ♻ Memory Flow Interface.md", 161 | "collapseAll": false, 162 | "extraContext": false, 163 | "sortOrder": "alphabetical", 164 | "showSearch": false, 165 | "searchQuery": "", 166 | "backlinkCollapsed": false, 167 | "unlinkedCollapsed": true 168 | } 169 | } 170 | } 171 | ] 172 | } 173 | ], 174 | "direction": "horizontal", 175 | "width": 282 176 | }, 177 | "active": "7ea162fe62ee3290", 178 | "lastOpenFiles": [ 179 | "00 ♻ Memory Flow Interface.md", 180 | "README.md", 181 | "200 Resources/Personal Knowledge Database.md", 182 | "200 Resources/Getting Things Done.md", 183 | "200 Resources/Agile Project Management.md", 184 | "200 Resources/Alignment.md", 185 | "200 Resources/Answering Big Questions with Alignment.md", 186 | "100 Staging/Harumachi Clover Is THE Song.md", 187 | "200 Resources/Dashboard.md", 188 | "02 🎨 Arts Dashboard.md" 189 | ] 190 | } -------------------------------------------------------------------------------- /00 ♻ Memory Flow Interface.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: ♻ Memory Flow Interface 3 | tags: dashboard 4 | --- 5 | # Everything About Memory Flow Interface 6 | Memory Flow Interface (MFI) is a working environment that promotes the externalization of working memory for mental processing. 7 | 8 | MFI is a form of [[Personal Knowledge Management|Personal Knowledge Management (PKM)]], and can be thought of as creating a second brain optimized for processing ideas, with secondary goals being long-term storage, information retrieval, and mental health. 9 | 10 | This vault is an integration of MFI with Obsidian, and has been catered towards personal life-management rather than managing teams or corporate, but concepts discussed here can be applied there too. 11 | 12 | ## Audience 13 | MFI is a PKM, a workflow, a task/project management framework, a journal, a form of meditation, and a creative outlet. 14 | 15 | But most importantly, MFI is for people who want a better understanding of how their mind works. It encourages a lot of rambling as a means of self-actuation, to discover patterns of thought and raise self-awareness. And it's through these ramblings where revelations occur, such as the inability to start work due to fear of incompetence and decision paralysis. 16 | 17 | MFI is designed to be powerfully basic. The core elements allow for immense personal development and information management. If so desired, users can bring in other [[#Further Reading|tools and other concepts]] to create a more nuanced environment that suits their needs. 18 | 19 | ## Context 20 | Our working memory and ability to internally process information is rather limited. [It's been observed that seven (plus or minus two) chunks of information is what most people can work with](https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two). Anymore and information is either lost, workflow is hindered, or both. 21 | 22 | One of the best ways to help us get around that limit and enhance processing is having a means to externalize our working memory. The internal memory gets off-loaded and now existing as a memory of the environment. This externalized memory can now flow to and out of our internal working memory and store any manipulations apply onto it. 23 | 24 | Language is one of the most common forms of externalizing working memory, and for MFI in Obsidian, it's mostly about writing. From writing, we get notes. And from notes, we get databases and PKM. MFI serves to help create that practical space for externalizing working memory. 25 | 26 | ## Fundamental Concepts 27 | - You need a container (or workspace) to represent and hold your ideas. 28 | - The container for your ideas should have a focus, and always has a working state of *being worked on* or *done*. 29 | - The generalized [[Practical Workflow of MFI|Workflow]] is as follows: Input, Process, Conclude, Act. 30 | - [[Rambling|Rambling]] is used to drive mental processing and link relevant ideas. 31 | - Frequent check-ins as a form of self-reflection are done through life-rambling. 32 | - This promotes fair mental state and well-being, and is important for processing information well. 33 | - Reminders, checklists, and inline *notes about your notes* are used to quickly load external working memory back into internal working memory. 34 | - This is important, since mental fatigue is unfortunately (or fortunately) a thing, and you will walk away from the MFI for a break. 35 | - This also allows you to internally process the information during cycles of sleep. 36 | 37 | ## Applied to Obsidian 38 | - The container for ideas is a note, but [[Projects|the container can also be a Project]], which is a container (folders) for containers (notes). 39 | - [[Organizing by Folders vs Tags|Folders are used to denote the working state of a note]]. This is because a note must be in one, and only one, folder (ignoring root). Whatever folder the note is in denotes that note's working state. 40 | - Projects have their own internal working state folders. 41 | - [[Tasks|Checklists as Tasks]] with the [Tasks Plugin](obsidian://show-plugin?id=obsidian-tasks-plugin) serve the purpose of reminders. 42 | - Check-ins are done daily or as needed as [[Alignment|Alignments]]. [[Periodic Notes for Alignment|They utilize a few plugins for ease of use]]. 43 | 44 | ## Useful Concepts and Tools 45 | - Notes can be organized by [[Tags|Tags]], which denote its characteristics or relation to [[Tags are Disciplines|Disciplines]]. This is used for organizing and retrieving notes. 46 | - Tasks, metadata, and other information can be aggregated and put onto [[Dashboard|Dashboard]] to efficiently load information back onto working memory. 47 | - [Evergreen notes](https://notes.andymatuschak.org/Evergreen_notes) can also be used to represent projects. 48 | 49 | ## Shortcomings 50 | MFI requires the externalization of thoughts. That which cannot be externalized cannot be consumed and processed. This means that extremely early ideas or abstract concepts may not be able to utilize MFI, since describing them may not even be possible. Since Obsidian is mostly text-based, any pictures, videos, etc. are questionable. 51 | 52 | Messy notes will break MFI. Since MFI relies on your ability to externalize information, that then needs to re-consume into your working memory to process. You can't consume messy notes. You can get around this by providing context (or just writing better notes). 53 | 54 | MFI is not a substitute for experience. You can't externalize a skill, neither can you consume a skill. You can externalize the theory and consume the theory, but all that's learned is how it's supposed to be done. Practical experience is something MFI will never be able to achieve unless we start directly wiring our brains. *Though, you do experience and learn the act of externalizing and processing your thoughts.* 55 | 56 | MFI also requires that you have access to said environment. Since this is integrated within Obsidian, if you don't have access to your vault, either through a computer or mobile device, you can't use it. As a workaround, so long as you understand the fundamental concepts, you should be able to use pen and paper. 57 | 58 | ## Further Reading 59 | Not required, but can be useful in understanding how LDP was derived. You could also implement these ideas into your own workflow. 60 | - [[Getting Things Done]] is a task management framework, having a 5-step process of information capturing, processing, organizing, review, and engagement. 61 | - [[Pillars, Pipelines, Vaults (PPV)]] leverages systems thinking to develop focus, alignment, and knowledge. 62 | - [[Agile Project Management|Agile]] is a set of project management principles for speedy turnover, focusing on people, products, and tools. 63 | - [[Scrum (Agile)|Scrum]] is a derivative of Agile, and looks to describe the day's work and how it relates to the bigger picture. 64 | - [[Kanban (Agile)|Kanban]] is another derivative of Agile, and is a task management workflow that leverages some visual board to bucket the working status of a task. 65 | - [Evergreen notes](https://notes.andymatuschak.org/Evergreen_notes) are accumulated insights of a particular concept; these notes grow across projects and serve as definitions -------------------------------------------------------------------------------- /00 📝 Directory.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 📝 Directory 3 | tags: dashboard 4 | --- 5 | # 📝 Directory 6 | ## Fundamentals 7 | ```query 8 | tag:#fundamental -line:#fundamental 9 | ``` 10 | 11 | ## Suggestions 12 | ```query 13 | tag:#suggestion -line:#suggestion 14 | ``` 15 | 16 | ## Tools 17 | ```query 18 | tag:#tool -line:#tool 19 | ``` -------------------------------------------------------------------------------- /000 Inbox/Important Project/bad apple.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: art 4 | --- 5 | # bad apple 6 | ![](https://blogs.worldbank.org/sites/default/files/education/apple.jpg) 7 | 8 | [Bad Apple!! played on Google Maps - YouTube](https://www.youtube.com/watch?v=r-axdVfM0c0&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=1) 9 | [Bad Apple!! but it's a VS Code Auto-Formatter - YouTube](https://www.youtube.com/watch?v=cmpg-qiPYa8&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=2) 10 | [Bad Apple!! played on Desmos Graphing Calculator - YouTube](https://www.youtube.com/watch?v=siPzJD2tMDw&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=3) 11 | [Bad Apple!! played on WeBWork Homework System (Flash Warning) - YouTube](https://www.youtube.com/watch?v=pctF1w4utug&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=4) 12 | [Bad Apple!! played on Windows 10 File Explorer - YouTube](https://www.youtube.com/watch?v=7WHA_Gi4nPA&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=5) 13 | [I have run out of things to play Bad Apple!! on - YouTube](https://www.youtube.com/watch?v=zlLQg7p_BTs&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=6) 14 | [Bad Apple!! played on Microsoft Paint (Flash Warning) - YouTube](https://www.youtube.com/watch?v=itbBubDqm70&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=7) 15 | [Bad Apple!! played on Desmos but it's high quality with Bezier Curves - YouTube](https://www.youtube.com/watch?v=MVrNn5TuMkY&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=8) 16 | [Bad Apple!! but rendered with Minecraft Creeper Explosions - YouTube](https://www.youtube.com/watch?v=jC7Y-H60_V0&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=9) 17 | [Bad Apple!! played with pure CSS in high quality - YouTube](https://www.youtube.com/watch?v=MQbjW2VfaHs&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=10) 18 | [Bad Apple Channel Reveals Analytics - YouTube](https://www.youtube.com/watch?v=WOQil8pL0oU&list=PLsTVaNk5lQHmRy51gyAsVN16DHpv0gcfE&index=11) 19 | 20 | [my beloved Junferno](https://www.youtube.com/c/Junferno) -------------------------------------------------------------------------------- /000 Inbox/Important Project/it.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: art 4 | --- 5 | # it 6 | ![](https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Bliss_location%2C_Sonoma_Valley_in_2006.jpg/1280px-Bliss_location%2C_Sonoma_Valley_in_2006.jpg) 7 | exists. -------------------------------------------------------------------------------- /000 Inbox/Important Project/pls rember.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: art 4 | --- 5 | # pls rember 6 | 7 | ![](https://i.kym-cdn.com/photos/images/original/001/206/633/cfb.png) 8 | 9 | > pls rember that wen u feel scare or frigten 10 | > never forget ttimes wen u feeled happy 11 | > 12 | > wen day is dark alway rember happy day -------------------------------------------------------------------------------- /000 Inbox/What a save!.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: art 4 | --- 5 | # What a save! 6 | 7 | What a save! 8 | What a save! 9 | What a save! 10 | Wow! 11 | Chat disabled for 4 seconds. 12 | 13 | #resume finish Rocket League notes when chat is enabled again -------------------------------------------------------------------------------- /01 🏠 Main Dashboard.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 🏠 Main Dashboard 3 | tags: dashboard 4 | --- 5 | # 🏠 Main Dashboard 6 | ## Resume Work 7 | ```query 8 | tag:#resume 9 | ``` 10 | 11 | ## Planned 12 | ```tasks 13 | not done 14 | ``` 15 | 16 | ## Done 17 | ```tasks 18 | done 19 | ``` -------------------------------------------------------------------------------- /02 🎨 Arts Dashboard.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 🎨 Arts Dashboard 3 | tags: dashboard 4 | --- 5 | # 🎨 Arts Dashboard 6 | ## Planned 7 | ```tasks 8 | not done 9 | description includes #art 10 | ``` 11 | 12 | ## Done 13 | ```tasks 14 | done 15 | description includes #art 16 | ``` 17 | 18 | ## Related Notes 19 | ```query 20 | tag:#art -line:#art 21 | ``` -------------------------------------------------------------------------------- /100 Staging/Harumachi Clover Is THE Song.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: lord forgive me for what im about to do 3 | tags: art, music, composition, sin 4 | --- 5 | # Harumachi Clover Is THE Song 6 | [Ichimichi Mao - Harumachi Clover (FULL) - YouTube](https://www.youtube.com/watch?v=7Oxy8FWONh8&t=57s) 7 | 8 | Harumachi Clover is THE song. This note serves as a deconstruction of it. 9 | 10 | The majority of the song is composed in a 2-4 swing arrangement, following a sequence of repeated verse-chorus. 11 | 12 | The song starts off without any a measure of 4-8 percussion with an accompanying synth playing the progression of `VI` -> `I` -> `V` -> `III`, all of which are augmented and diminished over a natural flat B major. 13 | 14 | As the lyrics begin, a counter melody is played with the progression of B flat on the fifth harmonic natural over note H. This cases the percussion to resonates with the vocals, bringing in some much needed distortion and compression to the smooth piano, which has been modulated by the bass. 15 | 16 | An intermission is added to lower the kinetic energy and osculate towards the bass drop, leading into the chorus, which is what his song is most famous for. And if you listen very carefully, you can hear them say Harumachi Clover. 17 | 18 | After the first chorus, on the eleventeenth measure of said chorus, the key signature changes, and it's played in C, for clover. The harps start to play a diminished third, accompanied by an augmented fifth from the synths. Together, they create harmony that gives listeners relief, as they can only take so much of this shitpost before moving onto better things. 19 | 20 | It then follows your typical song structure, doing another verse before coming back to the chorus. But unlike other songs, there isn't a shift in key signature on the chorus, meaning listeners can enjoy the chorus for what it is, in that diminished 7th arpeggio glory. 21 | 22 | The final few measureswraps up the song, with some final words whispered into the ears: "I'm glad you read up to this point. I have committed a sin in music theory. Please forgive me." 23 | 24 | - [ ] #task review and finalize Harumachi Clover deconstruction #art 25 | -------------------------------------------------------------------------------- /200 Resources/Agile Project Management.md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: Agile 3 | tags: definition 4 | --- 5 | # Agile Project Management 6 | **Agile** is a set of project management principles that focuses on people, products, and tools to encourage an iterative approach for speedy turnover on product delivery. Unlike other workflows (e.g. Waterfall)—allowing, encouraging, and enacting change within a project is welcome. 7 | 8 | ## Manifesto for Agile Software Development 9 | > We are uncovering better ways of developing software by doing it and helping others do it. 10 | > 11 | > Through this work we have come to value: 12 | > **Individuals and interactions** over *processes and tools* 13 | > **Working software** over *comprehensive documentation* 14 | > **Customer collaboration** over *contract negotiation* 15 | > **Responding to change** over *following a plan* 16 | > 17 | > That is, while there is value in the items on the right, we value the items on the left more. 18 | > 19 | > Kent Beck | James Grenning | Robert C. Martin 20 | > Mike Beedle | Jim Highsmith | Steve Mellor 21 | > Arie van Bennekum | Andrew Hunt | Ken Schwaber 22 | > Alistair Cockburn | Ron Jeffries | Jeff Sutherland 23 | > Ward Cunningham | on Kern | Dave Thomas 24 | > Martin Fowler | Brian Marick 25 | 26 | The Manifesto is meant to be taken as is. Learn the fundamentals and leverage the to create your best iterative work. 27 | 28 | Customer satisfaction is of top priority, even early during development. This is typically the result of continuous delivery of products, with each iteration being potentially changed. 29 | 30 | *Working Software* is the the primary measure of progress; the results are the deliverable versions. 31 | 32 | Agile emphasizes simplicity for maximizing effective work, with steady, sustainable development for maintaining a constant, indefinite pace to avoid fatigue. 33 | 34 | At regular intervals, teams are to reflect on how to be more effective and adjust behavior accordingly. 35 | 36 | ## Methodologies 37 | There are various methologies that have adapted the principles of Agile. 38 | - [[Scrum (Agile)]] 39 | - [[Kanban (Agile)]] 40 | 41 | **Sources** 42 | [What is Agile? | Atlassian](https://www.atlassian.com/agile) 43 | [Principles behind the Agile Manifesto](https://agilemanifesto.org/principles.html) -------------------------------------------------------------------------------- /200 Resources/Alignment.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Alignment 3 | tags: definition, tool, fundamental 4 | --- 5 | # Alignment 6 | **Alignment** is the verification of recent thoughts and actions to see if they resonate with current ideologies. This can be thought of a routine check-in, self-therapy, self-mentorship, etc. 7 | 8 | Alignment is also the time to freely [[Rambling|Ramble]] on things that's on your mind, though it may be better to do a guided check-in. 9 | 10 | These should be done on a daily basis. Perhaps first thing in the morning, last thing in the day, or both. They can also be done as-needed. 11 | 12 | For actual usage inside of Obsidian, see [[Periodic Notes for Alignment]]. 13 | 14 | ## General Process 15 | You can think of alignment as a personal diary or journal; write down anything and everything. No one is going to see what you write. No one but you can parse your own mind. Face yourself and appreciate your ability to think. 16 | 17 | Some things to consider asking yourself during alignment are the following. 18 | - How do you feel about today? 19 | - Is there anything troubling you right now? 20 | - What are you grateful today? 21 | - What's the next best step forward? 22 | 23 | Don't be too forceful when doing alignments. It's more feel than process. If you don't feel like going through your set of questions for the day, then don't. 24 | 25 | For a bigger-picture approach, see [[Answering Big Questions with Alignment]]. 26 | 27 | ## Random Daily Alignment Example 28 | In this example, italicized questions are questions raised internally based on what they just wrote. Everyone processes their thoughts differently, but it's a valuable tool to be self-aware and question ones own thoughts. 29 | > **How do you feel about today?** 30 | > Good. 31 | > 32 | > *Why do you feel good?* 33 | > I got free ice cream at the ice cream shop. 34 | > 35 | > *What about that feels good?* 36 | > It felt like they appreciated the day's efforts. 37 | > 38 | > *What about being appreciated makes you feel good?* 39 | > It's something about the joy of being acknowledged. Something about being heard... 40 | > 41 | > *What do you mean by being heard?* 42 | > I don't know I liked being heard... There's something about having someone listen to me and be considerate of my doings. It's comforting. 43 | > 44 | > *Do you think this is something you would like to explore some more?* 45 | >This is important for me to understand what makes me happy, because I was felt happy. I want to understand what about this makes me happy. -------------------------------------------------------------------------------- /200 Resources/Answering Big Questions with Alignment.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: suggestion, tool 4 | --- 5 | # Answering Big Questions with Alignment 6 | [[Alignment|Allignment]] can be done on a daily basis, but you may want to consider special alignments for weekly, monthly, quarterly, and yearly alignments. 7 | 8 | During these special alignments, you may want to ask bigger questions of life and reflect on a wider time frame. Something everyone should consider doing at least once a year, if not once, is to do alignment on their current life situation, discussing and reviewing why they exist, etc. 9 | 10 | Some important questions to consider answering are the following. 11 | - What are one's core values when it comes to a subjective *good* life? 12 | - Does their current circumstances allow for that life to happen? 13 | - What steps can be taken to progress towards that kind of life? 14 | - What kind of person do you want to be, and who are you right now? 15 | - How have you changed since the last time you did something like this? Is it a good change? 16 | - Are you happy with how things are? -------------------------------------------------------------------------------- /200 Resources/Dashboard.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Dashboards 3 | tags: tool, suggestion, definition 4 | --- 5 | # Dashboard 6 | **Dashboards** gather information and display it in a highly digestible manner. This is especially useful when the raw information is vast and complex (e.g. having a lot of notes). 7 | 8 | In the context of [[Personal Knowledge Management|Personal Knowledge Management (PKM)]] within Obsidian, dashboards are just like any regular note. They can be used to hold definitions (of [[Tags|Tags]]), act as entry links to the rest of your notes, or gather [[Tasks|Tasks]], among many other things. 9 | 10 | Dashboards are case-specific and can be very personal. So long as it delivers information, and is can be comprehended in a timely manner, and is actionable—it's good enough. 11 | 12 | ## Some Applications of Dashboards 13 | A common dashboard is a *Home* dashboard, with a popular component being a way to see today's work. 14 | 15 | If you use checklists, you can turn them into tasks and aggregate them with queries through the [Tasks](obsidian://show-plugin?id=obsidian-tasks-plugin) plugin, which is already installed and enabled on this vault. 16 | 17 | You can also query for files under `📁 000 Inbox` or `📁 100 Staging`, though this is redundant with [[Folders as Working States]]. 18 | 19 | A quick trick to resume and jump to an unfinished point of a note is to have a tag specifically for this purpose, say `#resume`. Now, if you query for a `#resume` tag, Obsidian will immediately jump to the note, and scroll down to where the tag is. 20 | 21 | See [[01 🏠 Main Dashboard|🏠 Main Dashboard]] or [[02 🎨 Arts Dashboard|🎨 Arts Dashboard]] for an example. -------------------------------------------------------------------------------- /200 Resources/Done (Working State).md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Resources, Storage, Done 3 | tags: definition 4 | --- 5 | # Done (Working State) 6 | The final step of [[Folders as Working States|Working State]] is **Done**. Notes that are no longer being [[Working (Working State)|Worked]] on or are done with review/revisions at [[Staging (Working State)|Staged]] go here. 7 | 8 | An alternative for notes that aren't up to par, or have been abandoned, might be considered [[Stale (Working State)|Stale]]. 9 | 10 | For this vault, the `📁 200 Resources` represents done. -------------------------------------------------------------------------------- /200 Resources/Folders as Working States.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Working State 3 | tags: definition, fundamental 4 | --- 5 | # Folders as Working States 6 | **Problem**: I'm not too sure how I should organize my vault. 7 | **Preface**: [[Organizing by Folders vs Tags]] 8 | 9 | Folders be used to denote the working state of a note. Working state just defines the step in production a note is in. 10 | 11 | In a [[Personal Knowledge Management|Personal Knowledge Management (PKM)]], usually the workflow has notes that are either in a state of `Working` or `Done`. We can use folders to represent these states. This also serves as a means to quickly assess your current workload; on file navigation, the unfinished work is immediately visible. 12 | 13 | So as you work, a note would progress working states as follows. 14 | > [[Working (Working State)|Working]] -> [[Staging (Working State)|Done]] 15 | 16 | Though some people prefer a more nuanced approach. This has the following workflow. 17 | > [[Working (Working State)|Working]] -> [[Staging (Working State)|Staging]] -> [[Done (Working State)|Done]]/[[Stale (Working State)|Stale]] 18 | 19 | This vault uses the following to represent above. 20 | > `📁 000 Inbox` -> `📁 100 Staging` -> `📁 200 Resources`/`📁 900 Archive` 21 | > >Note how these folders are prefixed so that they are pushed to the top when sorted. 22 | 23 | Workflow for MFI is further elaborated on [[Practical Workflow of MFI]]. 24 | 25 | Having folders as working state does NOT deny the ability of using folders to organize other content. If you need a folder to hold globally useful content (e.g. `Templates`), you can still have them. 26 | 27 | > You can prefix these globally useful folders with a high number so they get shoved at the bottom (e.g. 999), or not prefix them at all. For the latter, they'll still be shoved to the bottom since letters come after numbers. 28 | 29 | If categories for sorting are absolutely necessary, having folders within the `Done` folder would work. -------------------------------------------------------------------------------- /200 Resources/Getting Things Done.md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: GTD 3 | tags: definition 4 | --- 5 | # Getting Things Done 6 | **Getting Things Done** is a framework designed to help you keep track of tasks, ideas, and projects around your life and work. 7 | 8 | Your brain is for creating ideas, not holding onto them. Only when your mind lets go of mundane remembrance will you achieve effective work. 9 | 10 | ## Main Steps 11 | GTD has 5 main steps to its workflow. 12 | 13 | ### 1. Capture 14 | All interesting ideas needs a way to be externalized so you don't have the burden of remembering. You can't even make meaningful use of that information at the moment most of the time, but so long as you have an easy reference, you can make use of it when the time comes. 15 | 16 | ### 2. Process/Clarify 17 | For all Captured items, is it Actionable? An **Actionable** item is something that asks you do to something given this new information. This can be externally driven or internally driven. 18 | 19 | If it is Actionable and it can be dealt with right now and quickly (<5 minutes), do it and move on. If you cannot, it should to go onto some **Action List**, a backlog of To-Do's for later. 20 | 21 | If it isn't Actionable, trash, archive it, or set it in a "Think about later" place so you can review it to see if it's still relevant (e.g. maybe you want to learn Piano and found some good learning material). 22 | 23 | ### 3. Organize 24 | Items tracked on the Action List needs to be organized and prioritized such that you can get these Actionable items done with as little initial effort as possible. Actions should be organized by Project, Time, and Context. 25 | 26 | Items that related to a particular Project should be grouped together. 27 | 28 | Items that can only be done on specific dates or have deadlines should be clearly labeled. 29 | 30 | Items that depend on time and place should also be clearly labeled as to take care of them when you happen to be there. 31 | 32 | **This is a system that you will have to flesh out yourself.** As a general rule of thumb, always ask yourself "What is the next possible action?" 33 | 34 | ### 4. Review/Reflect 35 | As time progresses, chaos will ensue. The Action List can grow out of control and you can easily get overwhelmed. 36 | 37 | At regular intervals (e.g. every week), it's suggested to review a set of items in this system to ensure things are aligned and on track. 38 | 39 | Are you moving towards your goals? Or are you just reacting to what comes towards you? 40 | 41 | ### 5. Engage 42 | When properly organized, you can engage with your Action List and immediately start working on what you had planned to work on, knowing that this item is relevant to you. 43 | 44 | If you happen to receive new input that interests you, Capture it as follows and follow the process. 45 | 46 | ## Projects 47 | If you're trying to complete something but you find that it requires >2 steps before being complete, this item could be considered a **Project**. You may need some additional overhead or planning and organizing the tasks for this project to make sure it gets completed smoothly. 48 | 49 | ## Related 50 | [[Agile Project Management|Agile]], specifically [[Scrum (Agile)]] and [[Kanban (Agile)]], can be useful methodologies that follow similar ideas of getting things done. 51 | 52 | [[Pillars, Pipelines, Vaults (PPV)]] is a more advance and structured take on GTD. It isn't as general as GTD as it has already made some deliberate choices, namely in how tasks are organized and reviewed. 53 | 54 | **Sources** 55 | [Getting Things Done (GTD) by David Allen - Animated Book Summary And Review - YouTube](https://www.youtube.com/watch?v=gCswMsONkwY) 56 | [Getting Things Done (GTD) for Beginners: How to Get Started for 2021 - YouTube](https://www.youtube.com/watch?v=zP8gQp3nDPA) -------------------------------------------------------------------------------- /200 Resources/Kanban (Agile).md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: Kanban 3 | tags: definition 4 | --- 5 | # Kanban (Agile) 6 | **Kanban** is an adaptation of [[Agile Project Management]] and is a workflow that uses a visual aid of columns to help organize work and increase its efficiency. It can also bring to light "invisible work" that has not been accounted for. 7 | 8 | It should be applied directly to how you currently work, not the other way around. 9 | 10 | Kanban is a pull system. If you have free hands, you can pull a task to work on it. 11 | 12 | ## Example 13 | | Backlog | Working | Done | 14 | | --------------- | -------- | ------------ | 15 | | Shop for dinner | Exercise | Brush Teeth | 16 | | | | Water Garden | 17 | | | | Do Homework | 18 | 19 | The very left **Backlog** can be thought of a backlog for [[Scrum (Agile)|Scrum]]. Cards move from left to right as working states progresses. These cards should require a small amount of work that one can finish it within a reasonable time-frame (e.g. less than 2 hours). 20 | 21 | Another popular adaptation of Agile is [[Scrum (Agile)|Scrum]]. 22 | 23 | **Sources** 24 | [Kanban - A brief introduction | Atlassian](https://www.atlassian.com/agile/kanban) -------------------------------------------------------------------------------- /200 Resources/Open-Ended Problem-Solving.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Open-Ended Problems 3 | tags: definition 4 | --- 5 | # Open-Ended Problem-Solving 6 | **Open-Ended Problem-Solving** is the act of resolving goals within an environment of a vague sense of direction or unclear tool-set. One can think of this as trying to figure out how to have fun in a sandbox. 7 | 8 | This kind of problem-solving is usually seen as difficult, since people have to reach into a void of mostly nothingness, and pull out some seemingly random solution that may or may not work. This can lead to decision paralysis as it can be perceived as infinite solutions, or possibly no solutions at all. 9 | 10 | [[Rambling|Rambling]] can be a systematic process of resolving open-ended problems. 11 | 12 | ## Practical Example of Open-Ended Problem-Solving 13 | > Let's say you have a goal of getting fit, but you can't just *get fit*. This is an open-ended problem. There are no trains to jump on that give you the solution. 14 | > 15 | > You could run a mile every day, but, what does being fit even mean to you? 16 | > 17 | > Perhaps let's do a baseline reference. What do other people (google) consider being fit? 18 | > 19 | > Do you think that's reasonable for you? What's your own sense of being fit? 20 | > 21 | > And now that you have that idea, what will you actually do to get there? Exercises? Okay, now what exercise? How many reps? How many sets? Do you go until failure? What is failure? 22 | > 23 | > I just want to feel fit. Well, what does that feel like? Let's try things out and see how I feel. Then we can work from there. 24 | > 25 | > ... 26 | > .. 27 | > . 28 | > 29 | > And then you come to your own conclusions on how to be fit. -------------------------------------------------------------------------------- /200 Resources/Organizing Tasks With Tags.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: tool, suggestion 4 | --- 5 | # Organizing Tasks With Tags 6 | Tags can be leveraged to organize [[Tasks]]. 7 | 8 | For example, if a task relates to art, you can add the `#art` tag to it, and then you can filter specifically for tasks for art. 9 | 10 | **Task** 11 | - [ ] #task Draw something cool today #art 12 | 13 | **Raw Query** 14 | > \`\`\`tasks 15 | > not done 16 | > description includes #art 17 | > \`\`\` 18 | 19 | **Running Query** 20 | ```tasks 21 | not done 22 | description includes #art 23 | ``` 24 | 25 | You can also have this query on some [[Dashboard|Dashboard]] ([[02 🎨 Arts Dashboard]]) if it's important. -------------------------------------------------------------------------------- /200 Resources/Organizing by Folders vs Tags.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: fundamental, suggestion 4 | --- 5 | # Organizing by Folders vs Tags 6 | **Problem**: I don't know whether I should organize my notes through folders or [[Tags|tags]]. 7 | 8 | [[Personal Knowledge Management|PKM]] interfaces with a [[Personal Knowledge Database|database of notes]]. We can leverage some ideas from [Entity-Relationship Diagrams](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model#Relationships,_roles_and_cardinalities), which abstract the ideas of databases. From that, we're going to use the idea of [Cardinality](https://en.wikipedia.org/wiki/Cardinality). 9 | 10 | In short, any object A can relate to a certain amount of objects B. How many objects A can relate to object B *is the cardinality*. Direction matters. 11 | 12 | > **A note can belong to zero or an infinite amount of tags.** 13 | > Tags can belong to one or an infinite amount of notes. 14 | > ... 15 | > **However, a note must only belong to one folder.** 16 | > Folders can belong to zero or an infinite amount of notes. 17 | 18 | Tags can represent a note of multiple attributes from a common set (e.g. multiple [[Tags are Disciplines|Disciplines]]). 19 | 20 | Folders should be leveraged when a note **must** have one attribute from a set. 21 | 22 | ## Suggestion Course of Action 23 | It's best to think of notes as having attributes. Tags and folders are a means to give attributes to notes, but with different constraints. 24 | 25 | Since folders will be one of the primary methods of navigating your vault, it would be wise to consider some commonly used attribute set—an attribute set that all notes must have only one of, and only one. 26 | 27 | For this vault, we are using [[Folders as Working States]]. 28 | 29 | Tags have no real constraints, but can get messy without consistency. For example, do you use the plural or singular form of a tag? If one isn't vigilant, tagging can cause redundancy. But sometimes this redundancy is needed. 30 | 31 | Tags should be treated with careful consideration. -------------------------------------------------------------------------------- /200 Resources/Periodic Notes for Alignment.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | info: tool, suggestion 4 | --- 5 | # Periodic Notes for Alignment 6 | Obsidian has a plugin called [Periodic Notes](obsidian://show-plugin?id=periodic-notes) and [Calendar](obsidian://show-plugin?id=calendar). They allow for quick access and the creation of notes for the daily, weekly, monthly, quarterly, and yearly occasions. 7 | 8 | These plugins are already installed and enabled on this vault. On the right sidebar, top panel, second tab, is the calendar. If you click on a date, you can bring up a note that corresponds to that date. This is where you can visually see your daily and weekly alignment. 9 | 10 | For monthly, quarterly, and yearly notes, you'll have to use the command palette `Ctrl + P`. 11 | 12 | You can also bring up today's daily alignment note by pressing `Ctrl + T`. -------------------------------------------------------------------------------- /200 Resources/Personal Knowledge Database.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: PKD, Personal Knowledge Database (PKD) 3 | tags: fundamental, definition, tool 4 | --- 5 | # Personal Knowledge Database 6 | A **Personal Knowledge Database (PKD)** is a collection of elements that hold information. They are usually organized/structured in a way that allows for quick retrieval of specific queries. 7 | 8 | [[Personal Knowledge Management|Personal Knowledge Management (PKM)]] seeks to iterate on the database through certain workflows and principles. -------------------------------------------------------------------------------- /200 Resources/Personal Knowledge Management.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: PKM, Personal Knowledge Management (PKM) 3 | tags: definition, fundamental 4 | --- 5 | # Personal Knowledge Management 6 | **Personal Knowledge Management (PKM)** is the aggregation and iteration of one's knowledge to draw conclusions, develop new concepts, or achieve a goal. 7 | 8 | The simple act of taking notes and organizing during a classroom lecture can be thought as a form of PKM. 9 | 10 | A PKM is most commonly referred to as a second brain, and modeling a PKM system after the brain intuitively works the best. These systems typically work as follows. 11 | 1. Input is given into the system. 12 | 2. The input is processed, revised, re-organized, etc. 13 | 3. Conclusions are drawn and a call to action is performed; input is stored for long-term use. 14 | 15 | Applying this workflow ideology to Obsidian and MFI, consider seeing [[Practical Workflow of MFI]]. 16 | 17 | PKM usually works off of some [[Personal Knowledge Database|Personal Knowledge Database (PKD)]]. -------------------------------------------------------------------------------- /200 Resources/Pillars, Pipelines, Vaults (PPV).md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: PPV 3 | tags: definition 4 | --- 5 | # Pillars, Pipelines, Vaults (PPV) 6 | **Pillars, Pipelines, Vaults (PPV)** is an extended and personalized take on [[Getting Things Done]] by [August Bradley](https://www.youtube.com/channel/UCfqj2oq6LVmR3ybC2nfjqKg). He suggests a systems thinking approach to organizing your life, and coins it as a life operating system. By viewing your entire life as integrated and overlapping systems, new insights can be discovered. 7 | 8 | ## Objectives 9 | PPV has 3 primary objectives. 10 | - **Focus**: to encourage flow at times when you need it the most 11 | - You should be able to sit down, see what you need to do, and immediately start working 12 | - **Alignment**: to ensure that work is directed and focused towards the right goals 13 | - You should know for sure that what you're doing will make progress towards something your goals 14 | - You should have a review system for each Pipeline step to ensure you haven't drifted 15 | - **Knowledge**: the quick stash of personal knowledge for you to leverage 16 | - You should be able to quickly pull and push notes as needed 17 | 18 | ## The Basics 19 | Pipelines can be thought of as your workflow. This workflow communicates with your Vault, your personal knowledge. Pillars are stripped across Pipelines and Vaults. 20 | 21 | **Cycles** is a separate process of Pipeline that optimizes the system for error recovery and redundancy. It's essentially a series of reviews. 22 | 23 | ## Pipelines 24 | Pipelines describe the what and how for actions in our life. There are four tiers parts. 25 | - **Value Goals**: A guiding principle for this particular pillar 26 | - **Goal Outcomes**: Resolutions that we want to aspire to meet that value 27 | - **Projects**: The what that needs to be done to meet Goal Outcomes 28 | - **Action Items (Tasks)**: The specific what and how that needs to be done to complete the Project 29 | 30 | For example, under a Pillar of Health, a Value Goal would be to stay healthy. A Goal Outcome would be to prevent bloating. A Project would be to overhaul your environment to only allow foods that lower bloat. Action Items would be to clear out the fridge and pantry of junk foods. 31 | 32 | > You should also have some system of habit tracking to denote progress and to encourage consistency. 33 | 34 | Your pipelines can be thought of as your [[Getting Things Done]]. 35 | 36 | ## Pillars 37 | Pillars are a categorization of the aspects of your life. They are not aspirations, lifetime goals, or responsibilities. The amount of pillars can vary depending on your needs, from 5 to 20. 38 | 39 | For Obsidian, you can use Tags as a means to categorize notes and link it back to a Pillar. This will allow aggregation of notes, tasks, etc. 40 | 41 | ## Vaults 42 | This is your personal knowledge database that should be able to be aggregated according to a Pillar or it's relation to a Value Goal. 43 | - **Media Vault**: where all interesting standalone media notes go in. This includes books, videos, podcasts, and any one else's ideas to be later recalled 44 | - **Courses & Training Vault**: specific towards courses and training 45 | - **Notes & Ideas Vault**: your own originals 46 | - **Tools & Skills Vault**: notes on software or on individuals 47 | 48 | This is your Zettelkasten, Link Your Thinking, etc. 49 | 50 | ## Cycles 51 | Cycles are review sessions that ensure work remains consistent with Pipelines and Pillars. 52 | 53 | ## Dashboards 54 | Dashboards are a means to centralize, condense, and hide as much irrelevant information for Pillars. They should be minimal and only show the required information for that Dashboard's purpose. 55 | 56 | You should at least have... 57 | - one dedicated to taking Action per day, week, month, etc 58 | - one dedicated to realignment (Cycles) 59 | 60 | These can be thought of as Map of Contents. 61 | 62 | **Sources** 63 | [Intro & Overview of Pillars, Pipelines & Vaults – Notion Life Operating System - YouTube](https://www.youtube.com/watch?v=d93SGaf82OM) -------------------------------------------------------------------------------- /200 Resources/Practical Workflow of MFI.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Workflow 3 | tag: fundamental 4 | --- 5 | # Practical Workflow of MFI 6 | You are your own producer and manager of your thoughts. When externalizing thoughts on MFI, the key is to reduce complexity so you can focus on the real work, rather than management. Get the best results with minimal effort. 7 | 8 | To understand workflow, one should be familiar with [[Folders as Working States|Working States]]. In short, ideas start out as "being worked on", and eventually progress towards "done" (or at least *good enough*). 9 | 10 | ## Generalized Process 11 | You have ideas you wish to expand within MFI. 12 | 1. In your information container, fully capture the idea. This idea is now being considered being in the state of [[Working (Working State)|Working]]. 13 | - It's suggested to take a break afterwards to let your own brain process and refresh your mindset. 14 | 2. Idea is further processed and iterated on, linking other relevant ideas. 15 | - Usually this would be done in the form of [[Rambling|Rambling]]. 16 | 3. Conclusions are drawn. The idea is moved to long-term storage and is now considered [[Done (Working State)|Done]]. 17 | 4. Educated actions are taken as a result of new knowledge. 18 | 19 | This process is a positive feedback loop—from the conclusion, more ideas are formed and are open for exploration. 20 | 21 | ## Working with Obsidian (Example) 22 | Working states are represented with [[Folders as Working States|Folders]]. Working states progress as follows. 23 | > [[Working (Working State)|Working]] ⇾ [[Staging (Working State)|Staging]] ⇾ [[Done (Working State)|Done]]/[[Stale (Working State)|Stale]] 24 | 25 | You want to take notes on [Non-linear Gameplay](https://en.wikipedia.org/wiki/Nonlinear_gameplay). 26 | 1. You create a new note named `Non-linear Gameplay` under `📁 000 Inbox`. The note is now considered [[Working (Working State)|Working]] 27 | 2. You fully write down your interpretations of the article. 28 | 3. Once done, the note is moved to `📁 100 Staging` and is considered [[Staging (Working State)|Staging]]. 29 | 4. You review said note and simplify concepts, linking some other related notes. 30 | 5. You evaluate the note looks good enough and draw conclusions. The note is moved to `📁 200 Resources` and is now considered [[Done (Working State)|Done]]. 31 | - Alternatively, it's moved to `📁 900 Archive` if the note is [[Stale (Working State)|Stale]] and has been abandoned. 32 | 6. You apply that new-found knowledge to developing non-linear experiences. 33 | 34 | This now raises more questions, asking what linear gameplay is and how it compares to non-linear. You start to do research on linear gameplay to compare the two, and the process keeps iterating on itself. 35 | 36 | > If you want to take a break during the workflow, you come back and see whatever unfinished work you have under `📁 100 Staging` or `📁 000 Inbox`. Optionally, you could leverage [[Tasks|Tasks]]. -------------------------------------------------------------------------------- /200 Resources/Projects.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Projects 3 | tags: tool, suggestion, fundamental 4 | --- 5 | # Projects 6 | **Problem:** I need a way to organize some bigger ideas that require multiple notes, and I don't really want it to overlap already existing work. 7 | 8 | Projects are containers containing containers of information. 9 | 10 | You should consider using projects when dealing with complex, big goals that require [[Open-Ended Problem-Solving]]. You can also use it as a means of gathering information from a long course or a book. 11 | 12 | ## Specific to Obsidian 13 | In Obsidian, projects can be thought of as folders containing notes, or a note that links various other notes. However, the former has an issue of not being able to separate the project files from regular notes when using [[Folders as Working States]], which this vault uses. 14 | 15 | Projects also have their own working states. This means that upon creation, they would exist within the folder of [[Working (Working State)]], and eventually be moved to appropriate folders for [[Done (Working State)]]. 16 | 17 | When projects are done, before moving them to your root `Done` folder (or `Stale`) it's suggested to move its internal *`Done`* notes to the vault's root `Done`. Not necessary, but keeps things consistent! 18 | 19 | > It's suggested to have a **Home Note** for the project to hold project details. If using folders, It should be placed within the project, named exactly the same as the project folder, but prepended with *00* to push it to the top. In there, you can centralize all of your [[Tasks]] and [[Rambling|Ramblings]]. You can think of this as an [Evergreen note](https://notes.andymatuschak.org/Evergreen_notes) is so desired. 20 | 21 | Projects should have their own internal Working and Done folders, among others depending on your workflow. This is to preserve the note's own working status within the project, and maintains the working status of the project itself. 22 | 23 | -------------------------------------------------------------------------------- /200 Resources/Rambling.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Ramble, Rambling 3 | tags: fundamental 4 | --- 5 | # Rambling 6 | Given some topic of interest, **Rambling** is the inconsequential dialogue and mind-wandering that may result in meaningful results. 7 | 8 | Mentally processing content is the work that is invisible to everyone and everything. Rambling acts as an interface to guide this mental processing, and how realizations are made. 9 | 10 | In the context of [[Personal Knowledge Management|Personal Knowledge Management (PKM)]], the environment is very [[Open-Ended Problem-Solving|open-ended]]. You start out with abstract ideas in need of resolution. Rambling is a tool to resolve those ideas, and if anything, tells you what works and what doesn't. 11 | 12 | [[Projects|Projects]] can benefit from rambling, as it can help flesh out its true purpose and intentions. It will also help with understanding if work actually benefits the project. Rambling does wonders for processing personal thoughts and improving mental health; see [[Alignment]]. 13 | 14 | ## General Process 15 | What's important isn't the materialistic yields, but the internal neural connections built by going through the process—a good note is just the kicker. There is no right or wrong way to ramble, though you should have some focused direction. 16 | 17 | Given a topic of interest, write your thoughts. Keep asking why and answer those whys, creating a curious positive-feedback look. 18 | 19 | If your ramble ever comes to fruition, you can factor out the rambling into its own note with an appropriate title if needed. 20 | 21 | ## Random Example of Rambling 22 | Topic of Interest: What makes water so important? 23 | > Well, we need water to survive, right? But that's just us humans. It's not just humans that need water, literally every living thing requires water. I don't think there's any living thing that does not require any amount of water to survive, and if so, that's crazy. 24 | > 25 | > But it isn't just living things, the environment also needs, well, may not need, but they function with water. Beaches are made because of water, and other environments are created by the erosion of water. 26 | > 27 | > Water also serves the purpose of cooling down the Earth too, right? Well, doesn't it also warm up the earth too? I would probably have to verify that, but it does serve double duty in maintaining temperatures. 28 | > 29 | > ... 30 | > 31 | > yada yada yada cool stuff about water, no need to be super formal amout your grammar or spelling. etc. water is cool because it tastes wonderful. -------------------------------------------------------------------------------- /200 Resources/Scrum (Agile).md: -------------------------------------------------------------------------------- 1 | --- 2 | aliases: Scrum 3 | tags: definition 4 | --- 5 | # Scrum (Agile) 6 | **Scrum** is one of many methodologies derived from [[Agile Project Management|Agile]]. Teams are encouraged to self-organize and work in increments, eventually learning through experiences. They are to routinely reflect on work and improve workflow. 7 | 8 | Work that is generated and organized for Scrum can be described as daily work, the bigger picture, and the vision. 9 | 10 | Another popular iteration of Scrum is [[Kanban (Agile)]]. 11 | 12 | **Source** 13 | [[Agile Project Management]] 14 | [Scrum - what it is, how it works, and why it's awesome](https://www.atlassian.com/agile/scrum) -------------------------------------------------------------------------------- /200 Resources/Staging (Working State).md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Review, Revision, Staging 3 | tags: definition 4 | --- 5 | # Staging (Working State) 6 | **Staging** is [[Folders as Working States|Working State]], and is the intermediate step between [[Working (Working State)|Working]] and [[Done (Working State)|Done]]/[[Stale (Working State)|Stale]], which is review/revision. It's a step for those who wish to differentiate between the initial brainstorm and review/revision. 7 | 8 | For this vault, the `📁 100 Staging` represents staging. -------------------------------------------------------------------------------- /200 Resources/Stale (Working State).md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Stale, Archive 3 | tags: definition 4 | --- 5 | # Stale (Working State) 6 | **Stale** is a [[Folders as Working States|Working State]] for information containers (notes) that aren't being touched anymore. These notes aren't useful enough to be directly linked or reference, but still hold historical information that could potentially be useful in the future, given some more work and relevancy. 7 | 8 | Notes that are useful for reference could instead be considered [[Done (Working State)|Done]]. 9 | 10 | For this vault, the `📁 900 Archive` represents stale. -------------------------------------------------------------------------------- /200 Resources/Tags are Disciplines.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Disciplines 3 | tags: suggestion 4 | --- 5 | # Tags are Disciplines 6 | **Problem**: In [Life Disciplines Projects (LDP)](https://github.com/uwidev/life-disciplines-projects), Disciplines had a dedicated folder, which was separate from the [[Folders as Working States|Inbox folder]]. This meant that when creating a new note, it could either go into Inbox or under a related Discipline(s). Where this note was to go wasn't clear, created redundancy, and made things messy. 7 | 8 | Disciplines now exist within the realm of [[Tags|Tags]]. If you think about it, any tag can be a discipline with enough effort. 9 | 10 | The Disciplines folder no longer exist, and all incoming [[Working (Working State)|Working]] notes now go to `📁 000 Inbox`. 11 | 12 | The Disciplines folder was originally meant as a place to categorize a note to said discipline, but we could easily do that through tags. Having it as tags would also allow a note to be a part of multiple disciplines, rather than locked to a single discipline, [[Organizing by Folders vs Tags|further elaborated here]]. 13 | 14 | If you need a discipline elaborated on, you can always create a note that specifically defines that discipline, or have a note that functions as a glossary of tags. Though with the former, it may also function as a **Mapping of Content**, or as a [[Dashboard|Dashboard]] to hold or query [[Tasks|Tasks]], or as locations for [[Rambling|Ramblings]], or as an [evergreen note](https://notes.andymatuschak.org/Evergreen_notes). -------------------------------------------------------------------------------- /200 Resources/Tags.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Tag, Tagging 3 | tags: fundamental, definition, suggestion 4 | --- 5 | # Tags 6 | Notes can be thought of as having certain attributes. **Tags** explicitly give attributes to notes, which can then be used to reference and organize said notes. 7 | 8 | #fundamental ⇽ This is a tag. This note now tagged as "fundamental". 9 | 10 | Some Obsidian plugins leverage tags for more than just categorizing notes, like [[Tasks]], which uses tags to mark checklist items as a Task for later reference. 11 | 12 | ## Naming Tags 13 | One may consider naming tags based on [[Tags are Disciplines|Disciplines]]. As for what disciplines, you can derive it based on what notes you have (or plan to have). For example, a note about ceramics may give birth to `#cermaics`, but can also birth `#art`. 14 | 15 | Tags may also come to existence based on structure or intent of notes. For example, `#definition` might be used to denote a note that describes a concept. Then `#connection` can be used to flesh out connections between two ideas. 16 | 17 | ## Referencing 18 | Using tags, we can run search queries to reference and organize notes with tags. This is how one can *organize* their notes. 19 | 20 | Let's find all the notes that are considered *fundamental*, but are more so suggestions. 21 | 22 | **Raw Query** 23 | > \`\`\`query 24 | > tag:#fundamental tag:#suggestion 25 | > \`\`\` 26 | 27 | **Running Query** 28 | ```query 29 | tag:#fundamental tag:#suggestion 30 | ``` 31 | 32 | You can also just use the search function on the left sidebar. 33 | 34 | -------------------------------------------------------------------------------- /200 Resources/Tasks.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Tasks 3 | tags: tool, suggestion 4 | --- 5 | # Tasks 6 | **Problem**: I have things I need to do inside this vault, but can't quite get to. I can't figure out how to organize it well. 7 | 8 | **Tasks** are checklist, but with extended functionality through the Obsidian [Tasks](obsidian://show-plugin?id=obsidian-tasks-plugin) plugin. Example below. 9 | 10 | - [ ] #task Come back home with milk for the kids 11 | 12 | They utilize [[Tags|Tagging]] to mark the checklist as a task. Tagging is also used to [[Organizing Tasks With Tags|Organize Tasks]]. 13 | 14 | Tasks are useful when you have need to plan or defer work to the future. They're also handy for [[Projects|Projects]] and ensuring errands are visible during [[Alignment|Alignment]]. 15 | 16 | ## How to Task 17 | Tasks are created by adding the #task tag to any checklist item. 18 | 19 | Where you create them is up to you. You may find it practical adding tasks in-line during a [[Rambling|Ramble]], or you might find it better to have a centralized place to hold all tasks. For the latter, you can aggregate tasks through queries (see below). 20 | 21 | ## Queries 22 | You can then query for tags using code blocks. 23 | 24 | **Raw Query** 25 | > \`\`\`tasks 26 | > not done 27 | > \`\`\` 28 | 29 | **Running Query** 30 | ```tasks 31 | not done 32 | ``` 33 | 34 | You should have the query on some [[Dashboard|Dashboard]] note, like [[01 🏠 Main Dashboard|🏠 Main Dashboard]]. 35 | 36 | Be sure to check out the [Tasks plugin](obsidian://show-plugin?id=obsidian-tasks-plugin) for full details. -------------------------------------------------------------------------------- /200 Resources/Working (Working State).md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: Inbox, Working 3 | tags: definition 4 | --- 5 | # Working (Working State) 6 | **Working** is a [[Folders as Working States|Working State]] and is the initial state of information containers (notes). This is when information is being inputted into the system. Some may also consider when information is being modified to also be working. 7 | 8 | Some people like to differentiate the initial input and review/revisions. An intermediate step [[Staging (Working State)|Staging]] would resolve this. More working states may be needed depending on your process. 9 | 10 | When a note is *done*, it's usually considered in [[Done (Working State)|Done]] or [[Stale (Working State)|Stale]]. 11 | 12 | For this vault, the `📁 000 Inbox` represents working. -------------------------------------------------------------------------------- /300 Alignment/2022-06-11.md: -------------------------------------------------------------------------------- 1 | This is some daily note for [[Rambling|ramblings]] for an [[Alignment|alignment]]. 2 | 3 | This note was created for 2022-06-11, as you can see by the title. 4 | 5 | Actually, you don't know if it was actually created on that date. You know that this note represents that date, but this note could have actually been created on any other day. 6 | 7 | It's possible it could have been created in the future... *oOoooooOooOOOO*. 8 | 9 | Now, with that statement, there are two interpretations from it. 10 | 1. The future from the perspective of your now. 11 | 2. The future from the perspective of my now. 12 | 13 | And logically, the future of my now is the only thing that makes sense, since it would be impossible for a future me to have written this for you in the present. 14 | 15 | But did you know that you are never experiencing the present? The thoughts you have observe the past, though it isn't the distant past. It's present "enough" that we perceive it as the present. The experience can only be perceived because it happened. For it to be happening, it is only happening because it will become happened, and that is what we experience. 16 | 17 | Should we be chasing the present moment? I'd say don't worry about it too much. 18 | 19 | But if anything, appreciate the immediate past. -------------------------------------------------------------------------------- /800 Templates/em dash.md: -------------------------------------------------------------------------------- 1 | — -------------------------------------------------------------------------------- /800 Templates/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | alias: 3 | tags: 4 | --- 5 | # <% tp.file.title %> 6 | -------------------------------------------------------------------------------- /800 Templates/task.md: -------------------------------------------------------------------------------- 1 | #task -------------------------------------------------------------------------------- /900 Archive/abandoned note.md: -------------------------------------------------------------------------------- 1 | this note had been abandoned because it done a bad. 2 | 3 | bad note. 4 | 5 | it may be useful in the future, but currently serves no real use. 6 | 7 | better to save it than deleting it, since it's still work that you poured your energy into. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Memory Flow Interface (MFI) 2 | **Memory Flow Interface (MFI)** is a working environment that promotes the externalization of working memory for mental processing. This repository serves to describe MFI, as well as serve as an implementation and demonstration within [Obsidian](https://obsidian.md/). 3 | 4 | ![](https://storage.ko-fi.com/cdn/useruploads/display/beaf0b1f-5264-4d01-b278-a9075114c7b6_obsidian_ikkorp5p48.png) 5 | 6 | ## Who is this for? 7 | MFI is designed to be powerfully basic. The core elements allow for immense personal development and information management. If so desired, users can bring in other tools and concepts to create a more nuanced environment that suits their needs. 8 | 9 | Conceptually, MFI is for people who want a better understanding of how their mind works. It encourages a lot of rambling as a means of self-actuation, to discover patterns of thought and raise self-awareness. And it's through these ramblings where revelations occur, such as the inability to start work due to fear of incompetence and decision paralysis. 10 | 11 | ## Conceptual Overview 12 | Obsidian uses notes (markdown files) to hold information. Notes are the workspace to externalize ideas, which are then iterated on until resolved. Conclusions are drawn and further actions can be taken. Notes are moved into a database for long-term storage. 13 | 14 | The database is primarily organized by Obsidian's tagging functionality, and uses them to give attributes to notes for queries. Folders are used to denote the working state of a note. 15 | 16 | Rambling is a means of outlet and decompression, and is utilized to gather insights on ideas. This is combined with alignments, which are routine check-ins for mental health and performance evaluation. 17 | 18 | Processing of information after a break requires a means to quickly load information back into loading memory. This usually requires contextual information, and is done through checklist items, whose functionality are extended by plugins. 19 | 20 | ## How to get started 21 | 1. Navigate to [Obsidian's Website](https://obsidian.md/) and download Obsidian. Install. 22 | 2. Download the latest release of this project on the right sidebar, under **Releases**. Extract to a safe location. 23 | 3. Open Obsidian then `Open folder as Vault`, and navigate to the folder that you extracted the source code to. Turn off safe-mode so plugins work. 24 | 4. Read `00 ♻ Memory Flow Interface` for further understanding, or immediately start working within this vault. 25 | 26 | ## Suggestions and Concerns 27 | Join the my community Discord server [here](https://discord.gg/xSaj5Cc5GZ). Also consider joining the official Obsidian Discord [here](https://discord.com/invite/veuWUTm) for Obsidian-specific details. Also feel free to [open a new issue](https://github.com/uwidev/life-disciplines-projects/issues/new). 28 | 29 | ## More about uwi 30 | I am a solo indie game developer focused on experience design. I have a mission of making people cry, but not through of saddness, but through sheer beauty. As of June 2022, I'm wrapping up an initial proof of concept, whose ideas have yet to be publicized. 31 | 32 | If you're interested in following me for game development, personal development, and anything else I find interesting, follow me on [twitter](https://twitter.com/uwidev). Also please consider donating at [ko-fi](https://ko-fi.com/uwidev) as appreciation for my efforts. 33 | 34 | If you're also a fan of Cirno from the Touhou Project, you can join my other community Discord [Club Cirno](https://discord.com/invite/clubcirno). 35 | --------------------------------------------------------------------------------