Initial commit: Vault setup with .gitignore

This commit is contained in:
Voidex 2025-05-21 02:51:04 -05:00
commit f68821a4f3
142 changed files with 77519 additions and 0 deletions

29
.gitignore vendored Normal file
View file

@ -0,0 +1,29 @@
# Device-specific layout (safe to ignore across machines)
.obsidian/workspace.json
.obsidian/workspace-mobile.json
# Obsidian plugin cache or temp files
.obsidian/plugins/**/data.json
.obsidian/plugins/**/cache.json
.obsidian/plugins/**/.cache/
.obsidian/plugins/**/__pycache__/
# OS and editor temp files
.DS_Store
Thumbs.db
desktop.ini
*.log
*.swp
*.swo
*.bak
*.tmp
~$*
# VS Code folders (optional)
.vscode/
.vscode-insiders/
# Node modules (if you build plugins)
node_modules/
dist/

13
.obsidian/app.json vendored Normal file
View file

@ -0,0 +1,13 @@
{
"promptDelete": false,
"readableLineLength": false,
"trashOption": "none",
"alwaysUpdateLinks": true,
"newFileLocation": "folder",
"newFileFolderPath": "00 Inbox",
"showUnsupportedFiles": true,
"showInlineTitle": false,
"livePreview": false,
"showIndentGuide": false,
"showLineNumber": true
}

9
.obsidian/appearance.json vendored Normal file
View file

@ -0,0 +1,9 @@
{
"translucency": false,
"cssTheme": "AnuPpuccin",
"enabledCssSnippets": [
"extended-colorschemes",
"custom-background",
"S - Checkboxes"
]
}

3
.obsidian/backlink.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"backlinkInDocument": true
}

5
.obsidian/canvas.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"snapToObjects": true,
"snapToGrid": true,
"newFileLocation": "current"
}

17
.obsidian/community-plugins.json vendored Normal file
View file

@ -0,0 +1,17 @@
[
"obsidian-style-settings",
"obsidian-markdown-formatting-assistant-plugin",
"obsidian-icon-folder",
"editing-toolbar",
"url-into-selection",
"obsidian-auto-link-title",
"obsidian-footnotes",
"obsidian-link-embed",
"link-favicon",
"obsidian-admonition",
"dataview",
"templater-obsidian",
"periodic-notes",
"calendar",
"obsidian-amazingmarvin-plugin"
]

31
.obsidian/core-plugins.json vendored Normal file
View file

@ -0,0 +1,31 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": false,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"properties": false,
"page-preview": true,
"daily-notes": false,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": true,
"editor-status": true,
"bookmarks": false,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": false,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": true,
"file-recovery": true,
"publish": false,
"sync": false,
"webviewer": true
}

5
.obsidian/daily-notes.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"format": "",
"folder": "",
"template": ""
}

22
.obsidian/graph.json vendored Normal file
View file

@ -0,0 +1,22 @@
{
"collapse-filter": true,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": true,
"collapse-color-groups": true,
"colorGroups": [],
"collapse-display": true,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": true,
"centerStrength": 0.518713248970312,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 1,
"close": true
}

18
.obsidian/hotkeys.json vendored Normal file
View file

@ -0,0 +1,18 @@
{
"obsidian-footnotes:insert-named-footnote": [
{
"modifiers": [
"Alt"
],
"key": "-"
}
],
"obsidian-footnotes:insert-autonumbered-footnote": [
{
"modifiers": [
"Alt"
],
"key": "0"
}
]
}

BIN
.obsidian/icons/boxicons.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="currentColor"><path d="M14 5H6c-1.103 0-2 .897-2 2v16l6-3.601L16 23V7c0-1.103-.897-2-2-2zm0 14.467-4-2.399-4 2.399V7h8v12.467z"></path><path d="M18 1h-8c-1.103 0-2 .897-2 2h8c1.103 0 2 .897 2 2v10.443l2 2.489V3c0-1.103-.897-2-2-2z"></path></svg>

After

Width:  |  Height:  |  Size: 338 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="currentColor"><path d="M9.585 11.692h4.328s2.432.039 2.432-2.35V5.391S16.714 3 11.936 3C7.362 3 7.647 4.983 7.647 4.983l.006 2.055h4.363v.617H5.92s-2.927-.332-2.927 4.282 2.555 4.45 2.555 4.45h1.524v-2.141s-.083-2.554 2.513-2.554zm-.056-5.74a.784.784 0 1 1 0-1.57.784.784 0 1 1 0 1.57z"></path><path d="M18.452 7.532h-1.524v2.141s.083 2.554-2.513 2.554h-4.328s-2.432-.04-2.432 2.35v3.951s-.369 2.391 4.409 2.391c4.573 0 4.288-1.983 4.288-1.983l-.006-2.054h-4.363v-.617h6.097s2.927.332 2.927-4.282-2.555-4.451-2.555-4.451zm-3.981 10.436a.784.784 0 1 1 0 1.57.784.784 0 1 1 0-1.57z"></path></svg>

After

Width:  |  Height:  |  Size: 687 B

BIN
.obsidian/icons/coolicons.zip vendored Normal file

Binary file not shown.

1
.obsidian/icons/coolicons/Archive.svg vendored Normal file
View file

@ -0,0 +1 @@
<svg width="16px" height="16px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="File / Archive"><path id="Vector" d="M6.60035 9H17.4003M6.60035 9C6.04029 9 5.75957 9 5.54566 9.10899C5.3575 9.20487 5.20463 9.35774 5.10875 9.5459C4.99976 9.75981 4.99976 10.04 4.99976 10.6001V15.8001C4.99976 16.9202 4.99976 17.4804 5.21775 17.9082C5.40949 18.2845 5.71523 18.5905 6.09156 18.7822C6.51896 19 7.07875 19 8.19667 19H15.8025C16.9204 19 17.4794 19 17.9068 18.7822C18.2831 18.5905 18.5902 18.2844 18.782 17.9081C18.9998 17.4807 18.9998 16.9216 18.9998 15.8037V10.591C18.9998 10.037 18.9998 9.75865 18.8914 9.5459C18.7955 9.35774 18.6419 9.20487 18.4538 9.10899C18.2398 9 17.9604 9 17.4003 9M6.60035 9H4.97507C4.12597 9 3.70168 9 3.4607 8.85156C3.13911 8.65347 2.95678 8.29079 2.98902 7.91447C3.0132 7.63223 3.26593 7.29089 3.77222 6.60739C3.91866 6.40971 3.99189 6.31084 4.08152 6.23535C4.20104 6.1347 4.34286 6.06322 4.49488 6.02709C4.60889 6 4.73126 6 4.9773 6H19.0217C19.2677 6 19.3904 6 19.5044 6.02709C19.6564 6.06322 19.7982 6.1347 19.9177 6.23535C20.0074 6.31084 20.0809 6.40924 20.2273 6.60693C20.7336 7.29042 20.9867 7.63218 21.0109 7.91442C21.0432 8.29074 20.8602 8.65347 20.5386 8.85156C20.2976 9 19.8723 9 19.0232 9H17.4003M9.99976 14H13.9998" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1 @@
<svg width="16px" height="16px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="System / Desktop_Tower"><path id="Vector" d="M10 20H7M18 17H16M13.0002 9H6.2002C5.08009 9 4.51962 9 4.0918 9.21799C3.71547 9.40973 3.40973 9.71547 3.21799 10.0918C3 10.5196 3 11.0801 3 12.2002V13.8002C3 14.9203 3 15.4796 3.21799 15.9074C3.40973 16.2837 3.71547 16.5905 4.0918 16.7822C4.5192 17 5.07899 17 6.19691 17H13.0001M13.0002 9L13 16.8002C13 16.8689 13 16.9354 13.0001 17M13.0002 9L13 7.2002C13 6.08009 13 5.51962 13.218 5.0918C13.4097 4.71547 13.7155 4.40973 14.0918 4.21799C14.5196 4 15.0801 4 16.2002 4H17.8002C18.9203 4 19.4796 4 19.9074 4.21799C20.2837 4.40973 20.5905 4.71547 20.7822 5.0918C21 5.5192 21 6.07899 21 7.19691V16.8031C21 17.921 21 18.48 20.7822 18.9074C20.5905 19.2837 20.2837 19.5905 19.9074 19.7822C19.48 20 18.921 20 17.8031 20H16.1969C15.079 20 14.5192 20 14.0918 19.7822C13.7155 19.5905 13.4097 19.2837 13.218 18.9074C13.0134 18.5058 13.0008 17.9884 13.0001 17M17.002 7V7.002L17 7.00195V7H17.002Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
.obsidian/icons/feather-icons.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>

After

Width:  |  Height:  |  Size: 320 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path></svg>

After

Width:  |  Height:  |  Size: 379 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"></polygon><rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect></svg>

After

Width:  |  Height:  |  Size: 303 B

BIN
.obsidian/icons/font-awesome-brands.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" fill="currentColor" width="16px" height="16px"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z"></path></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
.obsidian/icons/font-awesome-regular.zip vendored Normal file

Binary file not shown.

BIN
.obsidian/icons/font-awesome-solid.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" fill="currentColor" width="16px" height="16px"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M308.5 135.3c7.1-6.3 9.9-16.2 6.2-25c-2.3-5.3-4.8-10.5-7.6-15.5L304 89.4c-3-5-6.3-9.9-9.8-14.6c-5.7-7.6-15.7-10.1-24.7-7.1l-28.2 9.3c-10.7-8.8-23-16-36.2-20.9L199 27.1c-1.9-9.3-9.1-16.7-18.5-17.8C173.9 8.4 167.2 8 160.4 8h-.7c-6.8 0-13.5 .4-20.1 1.2c-9.4 1.1-16.6 8.6-18.5 17.8L115 56.1c-13.3 5-25.5 12.1-36.2 20.9L50.5 67.8c-9-3-19-.5-24.7 7.1c-3.5 4.7-6.8 9.6-9.9 14.6l-3 5.3c-2.8 5-5.3 10.2-7.6 15.6c-3.7 8.7-.9 18.6 6.2 25l22.2 19.8C32.6 161.9 32 168.9 32 176s.6 14.1 1.7 20.9L11.5 216.7c-7.1 6.3-9.9 16.2-6.2 25c2.3 5.3 4.8 10.5 7.6 15.6l3 5.2c3 5.1 6.3 9.9 9.9 14.6c5.7 7.6 15.7 10.1 24.7 7.1l28.2-9.3c10.7 8.8 23 16 36.2 20.9l6.1 29.1c1.9 9.3 9.1 16.7 18.5 17.8c6.7 .8 13.5 1.2 20.4 1.2s13.7-.4 20.4-1.2c9.4-1.1 16.6-8.6 18.5-17.8l6.1-29.1c13.3-5 25.5-12.1 36.2-20.9l28.2 9.3c9 3 19 .5 24.7-7.1c3.5-4.7 6.8-9.5 9.8-14.6l3.1-5.4c2.8-5 5.3-10.2 7.6-15.5c3.7-8.7 .9-18.6-6.2-25l-22.2-19.8c1.1-6.8 1.7-13.8 1.7-20.9s-.6-14.1-1.7-20.9l22.2-19.8zM112 176a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM504.7 500.5c6.3 7.1 16.2 9.9 25 6.2c5.3-2.3 10.5-4.8 15.5-7.6l5.4-3.1c5-3 9.9-6.3 14.6-9.8c7.6-5.7 10.1-15.7 7.1-24.7l-9.3-28.2c8.8-10.7 16-23 20.9-36.2l29.1-6.1c9.3-1.9 16.7-9.1 17.8-18.5c.8-6.7 1.2-13.5 1.2-20.4s-.4-13.7-1.2-20.4c-1.1-9.4-8.6-16.6-17.8-18.5L583.9 307c-5-13.3-12.1-25.5-20.9-36.2l9.3-28.2c3-9 .5-19-7.1-24.7c-4.7-3.5-9.6-6.8-14.6-9.9l-5.3-3c-5-2.8-10.2-5.3-15.6-7.6c-8.7-3.7-18.6-.9-25 6.2l-19.8 22.2c-6.8-1.1-13.8-1.7-20.9-1.7s-14.1 .6-20.9 1.7l-19.8-22.2c-6.3-7.1-16.2-9.9-25-6.2c-5.3 2.3-10.5 4.8-15.6 7.6l-5.2 3c-5.1 3-9.9 6.3-14.6 9.9c-7.6 5.7-10.1 15.7-7.1 24.7l9.3 28.2c-8.8 10.7-16 23-20.9 36.2L315.1 313c-9.3 1.9-16.7 9.1-17.8 18.5c-.8 6.7-1.2 13.5-1.2 20.4s.4 13.7 1.2 20.4c1.1 9.4 8.6 16.6 17.8 18.5l29.1 6.1c5 13.3 12.1 25.5 20.9 36.2l-9.3 28.2c-3 9-.5 19 7.1 24.7c4.7 3.5 9.5 6.8 14.6 9.8l5.4 3.1c5 2.8 10.2 5.3 15.5 7.6c8.7 3.7 18.6 .9 25-6.2l19.8-22.2c6.8 1.1 13.8 1.7 20.9 1.7s14.1-.6 20.9-1.7l19.8 22.2zM464 304a48 48 0 1 1 0 96 48 48 0 1 1 0-96z"></path></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" width="16px" height="16px"><!--! Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M121 32C91.6 32 66 52 58.9 80.5L1.9 308.4C.6 313.5 0 318.7 0 323.9V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V323.9c0-5.2-.6-10.4-1.9-15.5l-57-227.9C446 52 420.4 32 391 32H121zm0 64H391l48 192H387.8c-12.1 0-23.2 6.8-28.6 17.7l-14.3 28.6c-5.4 10.8-16.5 17.7-28.6 17.7H195.8c-12.1 0-23.2-6.8-28.6-17.7l-14.3-28.6c-5.4-10.8-16.5-17.7-28.6-17.7H73L121 96z"></path></svg>

After

Width:  |  Height:  |  Size: 702 B

BIN
.obsidian/icons/icon-brew.zip vendored Normal file

Binary file not shown.

BIN
.obsidian/icons/lucide-icons.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 16V4a2 2 0 0 1 2-2h11"></path><path d="M5 14H4a2 2 0 1 0 0 4h1"></path><path d="M22 18H11a2 2 0 1 0 0 4h11V6H11a2 2 0 0 0-2 2v12"></path></svg>

After

Width:  |  Height:  |  Size: 340 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z"></path><path d="M9 13a4.5 4.5 0 0 0 3-4"></path><path d="M6.003 5.125A3 3 0 0 0 6.401 6.5"></path><path d="M3.477 10.896a4 4 0 0 1 .585-.396"></path><path d="M6 18a4 4 0 0 1-1.967-.516"></path><path d="M12 13h4"></path><path d="M12 18h6a2 2 0 0 1 2 2v1"></path><path d="M12 8h8"></path><path d="M16 8V5a2 2 0 0 1 2-2"></path><circle cx="16" cy="13" r=".5"></circle><circle cx="18" cy="3" r=".5"></circle><circle cx="20" cy="21" r=".5"></circle><circle cx="20" cy="8" r=".5"></circle></svg>

After

Width:  |  Height:  |  Size: 769 B

1
.obsidian/icons/lucide-icons/Code.svg vendored Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>

After

Width:  |  Height:  |  Size: 282 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"></path><path d="M14 2v4a2 2 0 0 0 2 2h4"></path><path d="M8 13h2"></path><path d="M14 13h2"></path><path d="M8 17h2"></path><path d="M14 17h2"></path></svg>

After

Width:  |  Height:  |  Size: 410 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="8" height="18" x="3" y="3" rx="1"></rect><path d="M7 3v18"></path><path d="M20.4 18.9c.2.5-.1 1.1-.6 1.3l-1.9.7c-.5.2-1.1-.1-1.3-.6L11.1 5.1c-.2-.5.1-1.1.6-1.3l1.9-.7c.5-.2 1.1.1 1.3.6Z"></path></svg>

After

Width:  |  Height:  |  Size: 398 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"></path><path d="m9 12 2 2 4-4"></path></svg>

After

Width:  |  Height:  |  Size: 402 B

1
.obsidian/icons/lucide-icons/Tags.svg vendored Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 5 6.3 6.3a2.4 2.4 0 0 1 0 3.4L17 19"></path><path d="M9.586 5.586A2 2 0 0 0 8.172 5H3a1 1 0 0 0-1 1v5.172a2 2 0 0 0 .586 1.414L8.29 18.29a2.426 2.426 0 0 0 3.42 0l3.58-3.58a2.426 2.426 0 0 0 0-3.42z"></path><circle cx="6.5" cy="9.5" r=".5" fill="currentColor"></circle></svg>

After

Width:  |  Height:  |  Size: 473 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="7" cy="12" r="3"></circle><path d="M10 9v6"></path><circle cx="17" cy="12" r="3"></circle><path d="M14 7v8"></path><path d="M22 17v1c0 .5-.5 1-1 1H3c-.5 0-1-.5-1-1v-1"></path></svg>

After

Width:  |  Height:  |  Size: 378 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg>

After

Width:  |  Height:  |  Size: 361 B

BIN
.obsidian/icons/octicons.zip vendored Normal file

Binary file not shown.

1
.obsidian/icons/octicons/Gear16.svg vendored Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 16 16" fill="currentColor"><path d="M8 0a8.2 8.2 0 0 1 .701.031C9.444.095 9.99.645 10.16 1.29l.288 1.107c.018.066.079.158.212.224.231.114.454.243.668.386.123.082.233.09.299.071l1.103-.303c.644-.176 1.392.021 1.82.63.27.385.506.792.704 1.218.315.675.111 1.422-.364 1.891l-.814.806c-.049.048-.098.147-.088.294.016.257.016.515 0 .772-.01.147.038.246.088.294l.814.806c.475.469.679 1.216.364 1.891a7.977 7.977 0 0 1-.704 1.217c-.428.61-1.176.807-1.82.63l-1.102-.302c-.067-.019-.177-.011-.3.071a5.909 5.909 0 0 1-.668.386c-.133.066-.194.158-.211.224l-.29 1.106c-.168.646-.715 1.196-1.458 1.26a8.006 8.006 0 0 1-1.402 0c-.743-.064-1.289-.614-1.458-1.26l-.289-1.106c-.018-.066-.079-.158-.212-.224a5.738 5.738 0 0 1-.668-.386c-.123-.082-.233-.09-.299-.071l-1.103.303c-.644.176-1.392-.021-1.82-.63a8.12 8.12 0 0 1-.704-1.218c-.315-.675-.111-1.422.363-1.891l.815-.806c.05-.048.098-.147.088-.294a6.214 6.214 0 0 1 0-.772c.01-.147-.038-.246-.088-.294l-.815-.806C.635 6.045.431 5.298.746 4.623a7.92 7.92 0 0 1 .704-1.217c.428-.61 1.176-.807 1.82-.63l1.102.302c.067.019.177.011.3-.071.214-.143.437-.272.668-.386.133-.066.194-.158.211-.224l.29-1.106C6.009.645 6.556.095 7.299.03 7.53.01 7.764 0 8 0Zm-.571 1.525c-.036.003-.108.036-.137.146l-.289 1.105c-.147.561-.549.967-.998 1.189-.173.086-.34.183-.5.29-.417.278-.97.423-1.529.27l-1.103-.303c-.109-.03-.175.016-.195.045-.22.312-.412.644-.573.99-.014.031-.021.11.059.19l.815.806c.411.406.562.957.53 1.456a4.709 4.709 0 0 0 0 .582c.032.499-.119 1.05-.53 1.456l-.815.806c-.081.08-.073.159-.059.19.162.346.353.677.573.989.02.03.085.076.195.046l1.102-.303c.56-.153 1.113-.008 1.53.27.161.107.328.204.501.29.447.222.85.629.997 1.189l.289 1.105c.029.109.101.143.137.146a6.6 6.6 0 0 0 1.142 0c.036-.003.108-.036.137-.146l.289-1.105c.147-.561.549-.967.998-1.189.173-.086.34-.183.5-.29.417-.278.97-.423 1.529-.27l1.103.303c.109.029.175-.016.195-.045.22-.313.411-.644.573-.99.014-.031.021-.11-.059-.19l-.815-.806c-.411-.406-.562-.957-.53-1.456a4.709 4.709 0 0 0 0-.582c-.032-.499.119-1.05.53-1.456l.815-.806c.081-.08.073-.159.059-.19a6.464 6.464 0 0 0-.573-.989c-.02-.03-.085-.076-.195-.046l-1.102.303c-.56.153-1.113.008-1.53-.27a4.44 4.44 0 0 0-.501-.29c-.447-.222-.85-.629-.997-1.189l-.289-1.105c-.029-.11-.101-.143-.137-.146a6.6 6.6 0 0 0-1.142 0ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0ZM9.5 8a1.5 1.5 0 1 0-3.001.001A1.5 1.5 0 0 0 9.5 8Z"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 16 16" fill="currentColor"><path d="M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0 1 14.25 15H1.75A1.75 1.75 0 0 1 0 13.25Zm1.75-.25a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V2.75a.25.25 0 0 0-.25-.25ZM7.25 8a.749.749 0 0 1-.22.53l-2.25 2.25a.749.749 0 0 1-1.275-.326.749.749 0 0 1 .215-.734L5.44 8 3.72 6.28a.749.749 0 0 1 .326-1.275.749.749 0 0 1 .734.215l2.25 2.25c.141.14.22.331.22.53Zm1.5 1.5h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5Z"></path></svg>

After

Width:  |  Height:  |  Size: 597 B

BIN
.obsidian/icons/remix-icons.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><path d="M12 14V22H4C4 17.5817 7.58172 14 12 14ZM12 13C8.685 13 6 10.315 6 7C6 3.685 8.685 1 12 1C15.315 1 18 3.685 18 7C18 10.315 15.315 13 12 13ZM21 17H22V22H14V17H15V16C15 14.3431 16.3431 13 18 13C19.6569 13 21 14.3431 21 16V17ZM19 17V16C19 15.4477 18.5523 15 18 15C17.4477 15 17 15.4477 17 16V17H19Z"></path></svg>

After

Width:  |  Height:  |  Size: 425 B

View file

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><path d="M12 14V16C8.68629 16 6 18.6863 6 22H4C4 17.5817 7.58172 14 12 14ZM12 13C8.685 13 6 10.315 6 7C6 3.685 8.685 1 12 1C15.315 1 18 3.685 18 7C18 10.315 15.315 13 12 13ZM12 11C14.21 11 16 9.21 16 7C16 4.79 14.21 3 12 3C9.79 3 8 4.79 8 7C8 9.21 9.79 11 12 11ZM21 17H22V22H14V17H15V16C15 14.3431 16.3431 13 18 13C19.6569 13 21 14.3431 21 16V17ZM19 17V16C19 15.4477 18.5523 15 18 15C17.4477 15 17 15.4477 17 16V17H19Z"></path></svg>

After

Width:  |  Height:  |  Size: 540 B

View file

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><path d="M20 22H4C3.44772 22 3 21.5523 3 21V3C3 2.44772 3.44772 2 4 2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22ZM19 20V4H5V20H19ZM7 6H11V10H7V6ZM7 12H17V14H7V12ZM7 16H17V18H7V16ZM13 7H17V9H13V7Z"></path></svg>

After

Width:  |  Height:  |  Size: 334 B

View file

@ -0,0 +1 @@
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="16px" height="16px"><path d="M20 3L22 7V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V7.00353L4 3H20ZM20 9H4V19H20V9ZM12 10L16 14H13V18H11V14H8L12 10ZM18.764 5H5.236L4.237 7H19.764L18.764 5Z"></path></svg>

After

Width:  |  Height:  |  Size: 305 B

BIN
.obsidian/icons/rpg-awesome.zip vendored Normal file

Binary file not shown.

1
.obsidian/icons/rpg-awesome/Gears.svg vendored Normal file
View file

@ -0,0 +1 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 613 613" enable-background="new 0 0 613 613" xml:space="preserve" fill="currentColor"><path d="M576.368,231.834l-32.985,57.427c-20.128-8.609-41.599-14.639-64.05-17.609v-66.345h-64.222v66.301 c-21.864,2.842-42.826,8.555-62.514,16.731l-32.425-56.506l-43.044,24.212l-17.76-24.862c5.859-8.141,10.483-17.303,13.554-27.254 l64.799-7.091l-6.381-64.857l-62.004,6.13c-4.842-11.121-11.779-21.221-20.393-29.727l24.768-55.321l-59.008-26.408h-0.004 L190.172,81.44c-12.573-1.042-24.854,0.457-36.3,4.089l-34.6-48.439L66.645,75.536l35.612,49.859 c-5.99,9.506-10.364,20.226-12.689,31.839l-62.562,6.847l6.38,64.854l66.115-7.235c4.678,8.461,10.631,16.176,17.642,22.857 L89.172,307.03l59.01,26.408l28.199-62.988c9.712,0.632,19.236-0.243,28.318-2.444l40.754,55.825l37.916-27.701l13.955,24.095 c-17.581,13.427-33.316,29.153-46.766,46.727l-58.833-33.895l-30.715,55.847l57.507,33.407 c-8.446,20.236-14.304,41.816-17.144,64.325H134.48v64.224h67.177c1.986,14.402,5.24,28.376,9.612,41.885h202.403c0,0,0,0,0,0h0 c-28.598-12.855-48.524-41.57-48.524-74.959c0-45.381,36.787-82.166,82.166-82.166s82.166,36.785,82.166,82.166 c0,33.387-19.926,62.104-48.525,74.959h0c0,0,0,0,0,0H590.33v0v-30.018v-11.867v-64.224v-14.66v-73.997v-61.431v-20.943v-76.091 L576.368,231.834z M185.724,232.535c-29.018,1.771-53.98-20.313-55.751-49.33c-1.771-29.017,20.321-53.976,49.339-55.747 s53.981,20.317,55.751,49.334C236.835,205.809,214.743,230.764,185.724,232.535z"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 612 612" enable-background="new 0 0 612 612" xml:space="preserve" fill="currentColor"><g transform="matrix(15 0 0 15 -5924 -6649.4327)"></g><g transform="matrix(-3.75 0 0 3.75 2295.9997 -3330.35765)"><path stroke="#000000" stroke-miterlimit="10" d="M492.417,955.35h38.25v-62.156l38.25,90.844h-38.25v62.156L492.417,955.35z"></path></g></svg>

After

Width:  |  Height:  |  Size: 506 B

BIN
.obsidian/icons/simple-icons.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16px" height="16px"><path d="M.3013 17.6146c-.1299-.3387-.5228-1.5119-.1337-2.4314l9.8273 5.6738a.329.329 0 0 0 .3299 0L24 12.9616v2.3542l-13.8401 7.9906-9.8586-5.6918zM.1911 8.9628c-.2882.8769.0149 2.0581.1236 2.4261l9.8452 5.6841L24 9.0823V6.7275L10.3248 14.623a.329.329 0 0 1-.3299 0L.1911 8.9628zm13.1698-1.9361c-.1819.1113-.4394.0015-.4852-.2064l-.2805-1.1336-2.1254-.1752a.33.33 0 0 1-.1378-.6145l5.5782-3.2207-1.7021-.9826L.6979 8.4935l9.462 5.463 13.5104-7.8004-4.401-2.5407-5.9084 3.4113zm-.1821-1.7286.2321.938 5.1984-3.0014-2.0395-1.1775-4.994 2.8834 1.3099.108a.3302.3302 0 0 1 .2931.2495zM24 9.845l-13.6752 7.8954a.329.329 0 0 1-.3299 0L.1678 12.0667c-.3891.919.003 2.0914.1332 2.4311l9.8589 5.692L24 12.1993V9.845z"></path></svg>

After

Width:  |  Height:  |  Size: 841 B

View file

@ -0,0 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16px" height="16px"><path d="M1.6367 1.6367C.7322 1.6367 0 2.369 0 3.2734v17.4532c0 .9045.7322 1.6367 1.6367 1.6367h20.7266c.9045 0 1.6367-.7322 1.6367-1.6367V3.2734c0-.9045-.7322-1.6367-1.6367-1.6367H1.6367zm.545 2.1817h19.6367v16.3632h-2.7266v-1.0898h-4.9102v1.0898h-12V3.8184zM12 8.1816c-.9046 0-1.6367.7322-1.6367 1.6368 0 .9045.7321 1.6367 1.6367 1.6367.9046 0 1.6367-.7322 1.6367-1.6367 0-.9046-.7321-1.6368-1.6367-1.6368zm-4.3633 1.9102c-.6773 0-1.2285.5493-1.2285 1.2266 0 .6772.5512 1.2265 1.2285 1.2265.6773 0 1.2266-.5493 1.2266-1.2265 0-.6773-.5493-1.2266-1.2266-1.2266zm8.7266 0c-.6773 0-1.2266.5493-1.2266 1.2266 0 .6772.5493 1.2265 1.2266 1.2265.6773 0 1.2285-.5493 1.2285-1.2265 0-.6773-.5512-1.2266-1.2285-1.2266zM12 12.5449c-1.179 0-2.4128.4012-3.1484 1.0059-.384-.1198-.8043-.1875-1.2149-.1875-1.3136 0-2.7285.695-2.7285 1.5586v.8965h14.1836v-.8965c0-.8637-1.4149-1.5586-2.7285-1.5586-.4106 0-.831.0677-1.2149.1875-.7356-.6047-1.9694-1.0059-3.1484-1.0059Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16px" height="16px"><path d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1 @@
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="currentColor" width="16px" height="16px"><path d="M21.469 6.825c.84 1.537 1.318 3.3 1.318 5.175 0 3.979-2.156 7.456-5.363 9.325l3.295-9.527c.615-1.54.82-2.771.82-3.864 0-.405-.026-.78-.07-1.11m-7.981.105c.647-.03 1.232-.105 1.232-.105.582-.075.514-.93-.067-.899 0 0-1.755.135-2.88.135-1.064 0-2.85-.15-2.85-.15-.585-.03-.661.855-.075.885 0 0 .54.061 1.125.09l1.68 4.605-2.37 7.08L5.354 6.9c.649-.03 1.234-.1 1.234-.1.585-.075.516-.93-.065-.896 0 0-1.746.138-2.874.138-.2 0-.438-.008-.69-.015C4.911 3.15 8.235 1.215 12 1.215c2.809 0 5.365 1.072 7.286 2.833-.046-.003-.091-.009-.141-.009-1.06 0-1.812.923-1.812 1.914 0 .89.513 1.643 1.06 2.531.411.72.89 1.643.89 2.977 0 .915-.354 1.994-.821 3.479l-1.075 3.585-3.9-11.61.001.014zM12 22.784c-1.059 0-2.081-.153-3.048-.437l3.237-9.406 3.315 9.087c.024.053.05.101.078.149-1.12.393-2.325.609-3.582.609M1.211 12c0-1.564.336-3.05.935-4.39L7.29 21.709C3.694 19.96 1.212 16.271 1.211 12M12 0C5.385 0 0 5.385 0 12s5.385 12 12 12 12-5.385 12-12S18.615 0 12 0"></path></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
.obsidian/icons/tabler-icons.zip vendored Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-books"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 4m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path><path d="M9 4m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path><path d="M5 8h4"></path><path d="M9 16h4"></path><path d="M13.803 4.56l2.184 -.53c.562 -.135 1.133 .19 1.282 .732l3.695 13.418a1.02 1.02 0 0 1 -.634 1.219l-.133 .041l-2.184 .53c-.562 .135 -1.133 -.19 -1.282 -.732l-3.695 -13.418a1.02 1.02 0 0 1 .634 -1.219l.133 -.041z"></path><path d="M14 9l4 -1"></path><path d="M16 16l3.923 -.98"></path></svg>

After

Width:  |  Height:  |  Size: 841 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-checks"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M7 12l5 5l10 -10"></path><path d="M2 12l5 5m5 -5l5 -5"></path></svg>

After

Width:  |  Height:  |  Size: 384 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-cloud-plus"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M12 18.004h-5.343c-2.572 -.004 -4.657 -2.011 -4.657 -4.487c0 -2.475 2.085 -4.482 4.657 -4.482c.393 -1.762 1.794 -3.2 3.675 -3.773c1.88 -.572 3.956 -.193 5.444 1c1.488 1.19 2.162 3.007 1.77 4.769h.99a3.46 3.46 0 0 1 3.085 1.9"></path><path d="M16 19h6"></path><path d="M19 16v6"></path></svg>

After

Width:  |  Height:  |  Size: 611 B

1
.obsidian/icons/tabler-icons/Code.svg vendored Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-code"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M7 8l-4 4l4 4"></path><path d="M17 8l4 4l-4 4"></path><path d="M14 4l-4 16"></path></svg>

After

Width:  |  Height:  |  Size: 403 B

1
.obsidian/icons/tabler-icons/Logs.svg vendored Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-logs"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 12h.01"></path><path d="M4 6h.01"></path><path d="M4 18h.01"></path><path d="M8 18h2"></path><path d="M8 12h2"></path><path d="M8 6h2"></path><path d="M14 6h6"></path><path d="M14 12h6"></path><path d="M14 18h6"></path></svg>

After

Width:  |  Height:  |  Size: 542 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-network"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M6 9a6 6 0 1 0 12 0a6 6 0 0 0 -12 0"></path><path d="M12 3c1.333 .333 2 2.333 2 6s-.667 5.667 -2 6"></path><path d="M12 3c-1.333 .333 -2 2.333 -2 6s.667 5.667 2 6"></path><path d="M6 9h12"></path><path d="M3 20h7"></path><path d="M14 20h7"></path><path d="M10 20a2 2 0 1 0 4 0a2 2 0 0 0 -4 0"></path><path d="M12 15v3"></path></svg>

After

Width:  |  Height:  |  Size: 649 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-notes"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z"></path><path d="M9 7l6 0"></path><path d="M9 11l6 0"></path><path d="M9 15l4 0"></path></svg>

After

Width:  |  Height:  |  Size: 489 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-protocol"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M15 6l-7 12"></path><path d="M20 6l-7 12"></path><path d="M5 14v.015"></path><path d="M5 10.015v.015"></path></svg>

After

Width:  |  Height:  |  Size: 433 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-template"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M4 4m0 1a1 1 0 0 1 1 -1h14a1 1 0 0 1 1 1v2a1 1 0 0 1 -1 1h-14a1 1 0 0 1 -1 -1z"></path><path d="M4 12m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v6a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z"></path><path d="M14 12l6 0"></path><path d="M14 16l6 0"></path><path d="M14 20l6 0"></path></svg>

After

Width:  |  Height:  |  Size: 590 B

4459
.obsidian/plugins/calendar/main.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
{
"id": "calendar",
"name": "Calendar",
"description": "Calendar view of your daily notes",
"version": "1.5.10",
"author": "Liam Cain",
"authorUrl": "https://github.com/liamcain/",
"isDesktopOnly": false,
"minAppVersion": "0.9.11"
}

20876
.obsidian/plugins/dataview/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,11 @@
{
"id": "dataview",
"name": "Dataview",
"version": "0.5.68",
"minAppVersion": "0.13.11",
"description": "Complex data views for the data-obsessed.",
"author": "Michael Brenan <blacksmithgu@gmail.com>",
"authorUrl": "https://github.com/blacksmithgu",
"helpUrl": "https://blacksmithgu.github.io/obsidian-dataview/",
"isDesktopOnly": false
}

141
.obsidian/plugins/dataview/styles.css vendored Normal file
View file

@ -0,0 +1,141 @@
.block-language-dataview {
overflow-y: auto;
}
/*****************/
/** Table Views **/
/*****************/
/* List View Default Styling; rendered internally as a table. */
.table-view-table {
width: 100%;
}
.table-view-table > thead > tr, .table-view-table > tbody > tr {
margin-top: 1em;
margin-bottom: 1em;
text-align: left;
}
.table-view-table > tbody > tr:hover {
background-color: var(--table-row-background-hover);
}
.table-view-table > thead > tr > th {
font-weight: 700;
font-size: larger;
border-top: none;
border-left: none;
border-right: none;
border-bottom: solid;
max-width: 100%;
}
.table-view-table > tbody > tr > td {
text-align: left;
border: none;
font-weight: 400;
max-width: 100%;
}
.table-view-table ul, .table-view-table ol {
margin-block-start: 0.2em !important;
margin-block-end: 0.2em !important;
}
/** Rendered value styling for any view. */
.dataview-result-list-root-ul {
padding: 0em !important;
margin: 0em !important;
}
.dataview-result-list-ul {
margin-block-start: 0.2em !important;
margin-block-end: 0.2em !important;
}
/** Generic grouping styling. */
.dataview.result-group {
padding-left: 8px;
}
/*******************/
/** Inline Fields **/
/*******************/
.dataview.inline-field-key {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-primary-alt);
color: var(--nav-item-color-selected);
}
.dataview.inline-field-value {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-secondary-alt);
color: var(--nav-item-color-selected);
}
.dataview.inline-field-standalone-value {
padding-left: 8px;
padding-right: 8px;
font-family: var(--font-monospace);
background-color: var(--background-secondary-alt);
color: var(--nav-item-color-selected);
}
/***************/
/** Task View **/
/***************/
.dataview.task-list-item, .dataview.task-list-basic-item {
margin-top: 3px;
margin-bottom: 3px;
transition: 0.4s;
}
.dataview.task-list-item:hover, .dataview.task-list-basic-item:hover {
background-color: var(--text-selection);
box-shadow: -40px 0 0 var(--text-selection);
cursor: pointer;
}
/*****************/
/** Error Views **/
/*****************/
div.dataview-error-box {
width: 100%;
min-height: 150px;
display: flex;
align-items: center;
justify-content: center;
border: 4px dashed var(--background-secondary);
}
.dataview-error-message {
color: var(--text-muted);
text-align: center;
}
/*************************/
/** Additional Metadata **/
/*************************/
.dataview.small-text {
font-size: smaller;
color: var(--text-muted);
margin-left: 3px;
}
.dataview.small-text::before {
content: "(";
}
.dataview.small-text::after {
content: ")";
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "editing-toolbar",
"name": "Editing Toolbar",
"version": "3.1.16",
"minAppVersion": "0.14.0",
"description": "The Obsidian Editing Toolbar is modified from cmenu, which provides more powerful customization settings and has many built-in editing commands to be a MS Word-like toolbar editing experience.",
"author": "Cuman",
"authorUrl": "https://github.com/cumany/obsidian-editing-toolbar",
"isDesktopOnly": false
}

File diff suppressed because it is too large Load diff

12
.obsidian/plugins/link-favicon/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "link-favicon",
"name": "Link Favicons",
"version": "1.8.4",
"minAppVersion": "1.3.0",
"description": "See the favicon for a linked website. ",
"author": "Johannes Theiner",
"authorUrl": "https://github.com/joethei",
"isDesktopOnly": false
}

View file

@ -0,0 +1,7 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
https://github.com/joethei/obisidian-link-favicon
*/
.link-favicon{cursor:pointer!important;image-rendering:-webkit-optimize-contrast;margin-bottom:.3em;margin-left:.1em;margin-right:.1em;max-height:1em;vertical-align:bottom}.link-favicon-preview{font-size:50px;text-align:center}.link-favicon-preview img{height:50px}.link-favicon[data-color-inversion=true][data-is-readable-a-a=false]{filter:hue-rotate(180deg) invert(1)}.link-favicon-scrollable-content{height:60vh;overflow:auto}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-admonition",
"name": "Admonition",
"version": "10.3.2",
"minAppVersion": "1.1.0",
"description": "Enhanced callouts for Obsidian.md",
"author": "Jeremy Valentine",
"authorUrl": "",
"isDesktopOnly": false
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-amazingmarvin-plugin",
"name": "Amazing Marvin",
"version": "0.3.1",
"minAppVersion": "0.9.12",
"description": "This is a plugin for Obsidian (https://obsidian.md) for Amazing Marvin (https://app.amazingmarvin.com/)",
"author": "Shirayuki Nekomata",
"authorUrl": "https://github.com/ikuyarihS",
"isDesktopOnly": false
}

View file

@ -0,0 +1,59 @@
.amazing-marvin-container {
padding-left: 3%;
}
.modal-button-container .button,
.amazing-marvin-container .button-group .button {
display: inline-flex;
border: 1px solid;
padding: 1%;
}
.modal-button-container .icon,
.amazing-marvin-container .button-group .icon {
fill: var(--text-normal);
margin-right: 5px;
}
.amazing-marvin-container .button-group .span {
font-style: italic;
font-size: small;
margin-left: 2%;
}
.workspace-leaf-content .amazing-marvin-container {
user-select: text !important;
overflow: auto !important;
}
.amazing-marvin-title-container {
display: flex;
align-items: center;
}
.amazing-marvin-title-container .amazing-marvin-label {
user-select: none !important;
font-size: 75%;
display: flex;
align-items: center;
margin-left: 7px;
white-space: nowrap;
}
.amazing-marvin-list::before,
.amazing-marvin-list-item::before {
content: None !important;
}
.amazing-marvin-error-display {
color: red;
}
.amazing-marvin-title-icon {
margin-right: 5px;
}
.amazing-marvin-setting-header {
padding-bottom: 3%;
}
.amazing-marvin-setting-footer {
text-align: center;
border-top: 1px solid var(--background-modifier-border);
}

View file

@ -0,0 +1,771 @@
/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
'use strict';
var obsidian = require('obsidian');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
const DEFAULT_SETTINGS = {
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,
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,
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,
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,
imageRegex: /\.(gif|jpe?g|tiff?|png|webp|bmp|tga|psd|ai)$/i,
enhanceDefaultPaste: true,
shouldPreserveSelectionAsTitle: false,
enhanceDropEvents: true,
websiteBlacklist: "",
maximumTitleLength: 0,
useNewScraper: false,
linkPreviewApiKey: "",
useBetterPasteId: false,
};
class AutoLinkTitleSettingTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
let { containerEl } = this;
containerEl.empty();
new obsidian.Setting(containerEl)
.setName("Enhance Default Paste")
.setDesc("Fetch the link title when pasting a link in the editor with the default paste command")
.addToggle((val) => val
.setValue(this.plugin.settings.enhanceDefaultPaste)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
console.log(value);
this.plugin.settings.enhanceDefaultPaste = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("Enhance Drop Events")
.setDesc("Fetch the link title when drag and dropping a link from another program")
.addToggle((val) => val
.setValue(this.plugin.settings.enhanceDropEvents)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
console.log(value);
this.plugin.settings.enhanceDropEvents = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("Maximum title length")
.setDesc("Set the maximum length of the title. Set to 0 to disable.")
.addText((val) => val
.setValue(this.plugin.settings.maximumTitleLength.toString(10))
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
const titleLength = Number(value);
this.plugin.settings.maximumTitleLength =
isNaN(titleLength) || titleLength < 0 ? 0 : titleLength;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("Preserve selection as title")
.setDesc("Whether to prefer selected text as title over fetched title when pasting")
.addToggle((val) => val
.setValue(this.plugin.settings.shouldPreserveSelectionAsTitle)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
console.log(value);
this.plugin.settings.shouldPreserveSelectionAsTitle = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("Website Blacklist")
.setDesc("List of strings (comma separated) that disable autocompleting website titles. Can be URLs or arbitrary text.")
.addTextArea((val) => val
.setValue(this.plugin.settings.websiteBlacklist)
.setPlaceholder("localhost, tiktok.com")
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.websiteBlacklist = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("Use New Scraper")
.setDesc("Use experimental new scraper, seems to work well on desktop but not mobile.")
.addToggle((val) => val
.setValue(this.plugin.settings.useNewScraper)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
console.log(value);
this.plugin.settings.useNewScraper = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("Use Better Fetching Placeholder")
.setDesc("Use a more readable placeholder when fetching the title of a link.")
.addToggle((val) => val
.setValue(this.plugin.settings.useBetterPasteId)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
console.log(value);
this.plugin.settings.useBetterPasteId = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("LinkPreview API Key")
.setDesc("API key for the LinkPreview.net service. Get one at https://my.linkpreview.net/access_keys")
.addText((text) => text
.setValue(this.plugin.settings.linkPreviewApiKey || "")
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
const trimmedValue = value.trim();
if (trimmedValue.length > 0 && trimmedValue.length !== 32) {
new obsidian.Notice("LinkPreview API key must be 32 characters long");
this.plugin.settings.linkPreviewApiKey = "";
}
else {
this.plugin.settings.linkPreviewApiKey = trimmedValue;
}
yield this.plugin.saveSettings();
})));
}
}
class CheckIf {
static isMarkdownLinkAlready(editor) {
let cursor = editor.getCursor();
// Check if the characters before the url are ]( to indicate a markdown link
var titleEnd = editor.getRange({ ch: cursor.ch - 2, line: cursor.line }, { ch: cursor.ch, line: cursor.line });
return titleEnd == "](";
}
static isAfterQuote(editor) {
let cursor = editor.getCursor();
// Check if the characters before the url are " or ' to indicate we want the url directly
// This is common in elements like <a href="linkhere"></a>
var beforeChar = editor.getRange({ ch: cursor.ch - 1, line: cursor.line }, { ch: cursor.ch, line: cursor.line });
return beforeChar == "\"" || beforeChar == "'";
}
static isUrl(text) {
let urlRegex = new RegExp(DEFAULT_SETTINGS.regex);
return urlRegex.test(text);
}
static isImage(text) {
let imageRegex = new RegExp(DEFAULT_SETTINGS.imageRegex);
return imageRegex.test(text);
}
static isLinkedUrl(text) {
let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex);
return urlRegex.test(text);
}
}
class EditorExtensions {
static getSelectedText(editor) {
if (!editor.somethingSelected()) {
let wordBoundaries = this.getWordBoundaries(editor);
editor.setSelection(wordBoundaries.start, wordBoundaries.end);
}
return editor.getSelection();
}
static cursorWithinBoundaries(cursor, match) {
let startIndex = match.index;
let endIndex = match.index + match[0].length;
return startIndex <= cursor.ch && cursor.ch <= endIndex;
}
static getWordBoundaries(editor) {
let cursor = editor.getCursor();
// If its a normal URL token this is not a markdown link
// In this case we can simply overwrite the link boundaries as-is
let lineText = editor.getLine(cursor.line);
// First check if we're in a link
let linksInLine = lineText.matchAll(DEFAULT_SETTINGS.linkLineRegex);
for (let match of linksInLine) {
if (this.cursorWithinBoundaries(cursor, match)) {
return {
start: { line: cursor.line, ch: match.index },
end: { line: cursor.line, ch: match.index + match[0].length },
};
}
}
// If not, check if we're in just a standard ol' URL.
let urlsInLine = lineText.matchAll(DEFAULT_SETTINGS.lineRegex);
for (let match of urlsInLine) {
if (this.cursorWithinBoundaries(cursor, match)) {
return {
start: { line: cursor.line, ch: match.index },
end: { line: cursor.line, ch: match.index + match[0].length },
};
}
}
return {
start: cursor,
end: cursor,
};
}
static getEditorPositionFromIndex(content, index) {
let substr = content.substr(0, index);
let l = 0;
let offset = -1;
let r = -1;
for (; (r = substr.indexOf("\n", r + 1)) !== -1; l++, offset = r)
;
offset += 1;
let ch = content.substr(offset, index - offset).length;
return { line: l, ch: ch };
}
}
function blank$1(text) {
return text === undefined || text === null || text === '';
}
function notBlank$1(text) {
return !blank$1(text);
}
function scrape(url) {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield obsidian.requestUrl(url);
if (!response.headers['content-type'].includes('text/html'))
return getUrlFinalSegment$1(url);
const html = response.text;
const doc = new DOMParser().parseFromString(html, 'text/html');
const title = doc.querySelector('title');
if (blank$1(title === null || title === void 0 ? void 0 : title.innerText)) {
// If site is javascript based and has a no-title attribute when unloaded, use it.
var noTitle = title === null || title === void 0 ? void 0 : title.getAttr('no-title');
if (notBlank$1(noTitle)) {
return noTitle;
}
// Otherwise if the site has no title/requires javascript simply return Title Unknown
return url;
}
return title.innerText;
}
catch (ex) {
console.error(ex);
return '';
}
});
}
function getUrlFinalSegment$1(url) {
try {
const segments = new URL(url).pathname.split('/');
const last = segments.pop() || segments.pop(); // Handle potential trailing slash
return last;
}
catch (_) {
return 'File';
}
}
function getPageTitle$1(url) {
return __awaiter(this, void 0, void 0, function* () {
if (!(url.startsWith('http') || url.startsWith('https'))) {
url = 'https://' + url;
}
return scrape(url);
});
}
const electronPkg = require("electron");
function blank(text) {
return text === undefined || text === null || text === "";
}
function notBlank(text) {
return !blank(text);
}
// async wrapper to load a url and settle on load finish or fail
function load(window, url) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
window.webContents.on("did-finish-load", (event) => resolve(event));
window.webContents.on("did-fail-load", (event) => reject(event));
window.loadURL(url);
});
});
}
function electronGetPageTitle(url) {
return __awaiter(this, void 0, void 0, function* () {
const { remote } = electronPkg;
const { BrowserWindow } = remote;
try {
const window = new BrowserWindow({
width: 1000,
height: 600,
webPreferences: {
webSecurity: false,
nodeIntegration: true,
images: false,
},
show: false,
});
window.webContents.setAudioMuted(true);
window.webContents.on("will-navigate", (event, newUrl) => {
event.preventDefault();
window.loadURL(newUrl);
});
yield load(window, url);
try {
const title = window.webContents.getTitle();
window.destroy();
if (notBlank(title)) {
return title;
}
else {
return url;
}
}
catch (ex) {
window.destroy();
return url;
}
}
catch (ex) {
console.error(ex);
return "";
}
});
}
function nonElectronGetPageTitle(url) {
return __awaiter(this, void 0, void 0, function* () {
try {
const html = yield obsidian.request({ url });
const doc = new DOMParser().parseFromString(html, "text/html");
const title = doc.querySelectorAll("title")[0];
if (title == null || blank(title === null || title === void 0 ? void 0 : title.innerText)) {
// If site is javascript based and has a no-title attribute when unloaded, use it.
var noTitle = title === null || title === void 0 ? void 0 : title.getAttr("no-title");
if (notBlank(noTitle)) {
return noTitle;
}
// Otherwise if the site has no title/requires javascript simply return Title Unknown
return url;
}
return title.innerText;
}
catch (ex) {
console.error(ex);
return "";
}
});
}
function getUrlFinalSegment(url) {
try {
const segments = new URL(url).pathname.split('/');
const last = segments.pop() || segments.pop(); // Handle potential trailing slash
return last;
}
catch (_) {
return "File";
}
}
function tryGetFileType(url) {
return __awaiter(this, void 0, void 0, function* () {
try {
const response = yield fetch(url, { method: "HEAD" });
// Ensure site returns an ok status code before scraping
if (!response.ok) {
return "Site Unreachable";
}
// Ensure site is an actual HTML page and not a pdf or 3 gigabyte video file.
let contentType = response.headers.get("content-type");
if (!contentType.includes("text/html")) {
return getUrlFinalSegment(url);
}
return null;
}
catch (err) {
return null;
}
});
}
function getPageTitle(url) {
return __awaiter(this, void 0, void 0, function* () {
// If we're on Desktop use the Electron scraper
if (!(url.startsWith("http") || url.startsWith("https"))) {
url = "https://" + url;
}
// Try to do a HEAD request to see if the site is reachable and if it's an HTML page
// If we error out due to CORS, we'll just try to scrape the page anyway.
let fileType = yield tryGetFileType(url);
if (fileType) {
return fileType;
}
if (electronPkg != null) {
return electronGetPageTitle(url);
}
else {
return nonElectronGetPageTitle(url);
}
});
}
class AutoLinkTitle extends obsidian.Plugin {
constructor() {
super(...arguments);
this.shortTitle = (title) => {
if (this.settings.maximumTitleLength === 0) {
return title;
}
if (title.length < this.settings.maximumTitleLength + 3) {
return title;
}
const shortenedTitle = `${title.slice(0, this.settings.maximumTitleLength)}...`;
return shortenedTitle;
};
}
onload() {
return __awaiter(this, void 0, void 0, function* () {
console.log("loading obsidian-auto-link-title");
yield this.loadSettings();
this.blacklist = this.settings.websiteBlacklist
.split(",")
.map((s) => s.trim())
.filter((s) => s.length > 0);
// Listen to paste event
this.pasteFunction = this.pasteUrlWithTitle.bind(this);
// Listen to drop event
this.dropFunction = this.dropUrlWithTitle.bind(this);
this.addCommand({
id: "auto-link-title-paste",
name: "Paste URL and auto fetch title",
editorCallback: (editor) => this.manualPasteUrlWithTitle(editor),
hotkeys: [],
});
this.addCommand({
id: "auto-link-title-normal-paste",
name: "Normal paste (no fetching behavior)",
editorCallback: (editor) => this.normalPaste(editor),
hotkeys: [
{
modifiers: ["Mod", "Shift"],
key: "v",
},
],
});
this.registerEvent(this.app.workspace.on("editor-paste", this.pasteFunction));
this.registerEvent(this.app.workspace.on("editor-drop", this.dropFunction));
this.addCommand({
id: "enhance-url-with-title",
name: "Enhance existing URL with link and title",
editorCallback: (editor) => this.addTitleToLink(editor),
hotkeys: [
{
modifiers: ["Mod", "Shift"],
key: "e",
},
],
});
this.addSettingTab(new AutoLinkTitleSettingTab(this.app, this));
});
}
addTitleToLink(editor) {
// Only attempt fetch if online
if (!navigator.onLine)
return;
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
// If the cursor is on a raw html link, convert to a markdown link and fetch title
if (CheckIf.isUrl(selectedText)) {
this.convertUrlToTitledLink(editor, selectedText);
}
// If the cursor is on the URL part of a markdown link, fetch title and replace existing link title
else if (CheckIf.isLinkedUrl(selectedText)) {
const link = this.getUrlFromLink(selectedText);
this.convertUrlToTitledLink(editor, link);
}
}
normalPaste(editor) {
return __awaiter(this, void 0, void 0, function* () {
let clipboardText = yield navigator.clipboard.readText();
if (clipboardText === null || clipboardText === "")
return;
editor.replaceSelection(clipboardText);
});
}
// Simulate standard paste but using editor.replaceSelection with clipboard text since we can't seem to dispatch a paste event.
manualPasteUrlWithTitle(editor) {
return __awaiter(this, void 0, void 0, function* () {
const clipboardText = yield navigator.clipboard.readText();
// Only attempt fetch if online
if (!navigator.onLine) {
editor.replaceSelection(clipboardText);
return;
}
if (clipboardText == null || clipboardText == "")
return;
// If its not a URL, we return false to allow the default paste handler to take care of it.
// Similarly, image urls don't have a meaningful <title> attribute so downloading it
// to fetch the title is a waste of bandwidth.
if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) {
editor.replaceSelection(clipboardText);
return;
}
// If it looks like we're pasting the url into a markdown link already, don't fetch title
// as the user has already probably put a meaningful title, also it would lead to the title
// being inside the link.
if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) {
editor.replaceSelection(clipboardText);
return;
}
// If url is pasted over selected text and setting is enabled, no need to fetch title,
// just insert a link
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
if (selectedText && this.settings.shouldPreserveSelectionAsTitle) {
editor.replaceSelection(`[${selectedText}](${clipboardText})`);
return;
}
// At this point we're just pasting a link in a normal fashion, fetch its title.
this.convertUrlToTitledLink(editor, clipboardText);
return;
});
}
pasteUrlWithTitle(clipboard, editor) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.settings.enhanceDefaultPaste) {
return;
}
if (clipboard.defaultPrevented)
return;
// Only attempt fetch if online
if (!navigator.onLine)
return;
let clipboardText = clipboard.clipboardData.getData("text/plain");
if (clipboardText === null || clipboardText === "")
return;
// If its not a URL, we return false to allow the default paste handler to take care of it.
// Similarly, image urls don't have a meaningful <title> attribute so downloading it
// to fetch the title is a waste of bandwidth.
if (!CheckIf.isUrl(clipboardText) || CheckIf.isImage(clipboardText)) {
return;
}
// We've decided to handle the paste, stop propagation to the default handler.
clipboard.stopPropagation();
clipboard.preventDefault();
// If it looks like we're pasting the url into a markdown link already, don't fetch title
// as the user has already probably put a meaningful title, also it would lead to the title
// being inside the link.
if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) {
editor.replaceSelection(clipboardText);
return;
}
// If url is pasted over selected text and setting is enabled, no need to fetch title,
// just insert a link
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
if (selectedText && this.settings.shouldPreserveSelectionAsTitle) {
editor.replaceSelection(`[${selectedText}](${clipboardText})`);
return;
}
// At this point we're just pasting a link in a normal fashion, fetch its title.
this.convertUrlToTitledLink(editor, clipboardText);
return;
});
}
dropUrlWithTitle(dropEvent, editor) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.settings.enhanceDropEvents) {
return;
}
if (dropEvent.defaultPrevented)
return;
// Only attempt fetch if online
if (!navigator.onLine)
return;
let dropText = dropEvent.dataTransfer.getData("text/plain");
if (dropText === null || dropText === "")
return;
// If its not a URL, we return false to allow the default paste handler to take care of it.
// Similarly, image urls don't have a meaningful <title> attribute so downloading it
// to fetch the title is a waste of bandwidth.
if (!CheckIf.isUrl(dropText) || CheckIf.isImage(dropText)) {
return;
}
// We've decided to handle the paste, stop propagation to the default handler.
dropEvent.stopPropagation();
dropEvent.preventDefault();
// If it looks like we're pasting the url into a markdown link already, don't fetch title
// as the user has already probably put a meaningful title, also it would lead to the title
// being inside the link.
if (CheckIf.isMarkdownLinkAlready(editor) || CheckIf.isAfterQuote(editor)) {
editor.replaceSelection(dropText);
return;
}
// If url is pasted over selected text and setting is enabled, no need to fetch title,
// just insert a link
let selectedText = (EditorExtensions.getSelectedText(editor) || "").trim();
if (selectedText && this.settings.shouldPreserveSelectionAsTitle) {
editor.replaceSelection(`[${selectedText}](${dropText})`);
return;
}
// At this point we're just pasting a link in a normal fashion, fetch its title.
this.convertUrlToTitledLink(editor, dropText);
return;
});
}
isBlacklisted(url) {
return __awaiter(this, void 0, void 0, function* () {
yield this.loadSettings();
this.blacklist = this.settings.websiteBlacklist
.split(/,|\n/)
.map((s) => s.trim())
.filter((s) => s.length > 0);
return this.blacklist.some((site) => url.includes(site));
});
}
convertUrlToTitledLink(editor, url) {
return __awaiter(this, void 0, void 0, function* () {
if (yield this.isBlacklisted(url)) {
let domain = new URL(url).hostname;
editor.replaceSelection(`[${domain}](${url})`);
return;
}
// Generate a unique id for find/replace operations for the title.
const pasteId = this.getPasteId();
// Instantly paste so you don't wonder if paste is broken
editor.replaceSelection(`[${pasteId}](${url})`);
// Fetch title from site, replace Fetching Title with actual title
const title = yield this.fetchUrlTitle(url);
const escapedTitle = this.escapeMarkdown(title);
const shortenedTitle = this.shortTitle(escapedTitle);
const text = editor.getValue();
const start = text.indexOf(pasteId);
if (start < 0) {
console.log(`Unable to find text "${pasteId}" in current editor, bailing out; link ${url}`);
}
else {
const end = start + pasteId.length;
const startPos = EditorExtensions.getEditorPositionFromIndex(text, start);
const endPos = EditorExtensions.getEditorPositionFromIndex(text, end);
editor.replaceRange(shortenedTitle, startPos, endPos);
}
});
}
escapeMarkdown(text) {
var unescaped = text.replace(/\\(\*|_|`|~|\\|\[|\])/g, "$1"); // unescape any "backslashed" character
var escaped = unescaped.replace(/(\*|_|`|<|>|~|\\|\[|\])/g, "\\$1"); // escape *, _, `, ~, \, [, ], <, and >
var escaped = unescaped.replace(/(\*|_|`|\||<|>|~|\\|\[|\])/g, "\\$1"); // escape *, _, `, ~, \, |, [, ], <, and >
return escaped;
}
fetchUrlTitleViaLinkPreview(url) {
return __awaiter(this, void 0, void 0, function* () {
if (this.settings.linkPreviewApiKey.length !== 32) {
console.error("LinkPreview API key is not 32 characters long, please check your settings");
return "";
}
try {
const apiEndpoint = `https://api.linkpreview.net/?q=${encodeURIComponent(url)}`;
const response = yield fetch(apiEndpoint, {
headers: {
"X-Linkpreview-Api-Key": this.settings.linkPreviewApiKey,
},
});
const data = yield response.json();
return data.title;
}
catch (error) {
console.error(error);
return "";
}
});
}
fetchUrlTitle(url) {
return __awaiter(this, void 0, void 0, function* () {
try {
let title = "";
title = yield this.fetchUrlTitleViaLinkPreview(url);
console.log(`Title via Link Preview: ${title}`);
if (title === "") {
console.log("Title via Link Preview failed, falling back to scraper");
if (this.settings.useNewScraper) {
console.log("Using new scraper");
title = yield getPageTitle$1(url);
}
else {
console.log("Using old scraper");
title = yield getPageTitle(url);
}
}
console.log(`Title: ${title}`);
title =
title.replace(/(\r\n|\n|\r)/gm, "").trim() ||
"Title Unavailable | Site Unreachable";
return title;
}
catch (error) {
console.error(error);
return "Error fetching title";
}
});
}
getUrlFromLink(link) {
let urlRegex = new RegExp(DEFAULT_SETTINGS.linkRegex);
return urlRegex.exec(link)[2];
}
getPasteId() {
var base = "Fetching Title";
if (this.settings.useBetterPasteId) {
return this.getBetterPasteId(base);
}
else {
return `${base}#${this.createBlockHash()}`;
}
}
getBetterPasteId(base) {
// After every character, add 0, 1 or 2 invisible characters
// so that to the user it looks just like the base string.
// The number of combinations is 3^14 = 4782969
let result = "";
var invisibleCharacter = "\u200B";
var maxInvisibleCharacters = 2;
for (var i = 0; i < base.length; i++) {
var count = Math.floor(Math.random() * (maxInvisibleCharacters + 1));
result += base.charAt(i) + invisibleCharacter.repeat(count);
}
return result;
}
// Custom hashid by @shabegom
createBlockHash() {
let result = "";
var characters = "abcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < 4; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
onunload() {
console.log("unloading obsidian-auto-link-title");
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.settings);
});
}
}
module.exports = AutoLinkTitle;
/* nosourcemap */

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-auto-link-title",
"name": "Auto Link Title",
"version": "1.5.5",
"minAppVersion": "0.12.17",
"description": "This plugin automatically fetches the titles of links from the web",
"author": "Matt Furden",
"authorUrl": "https://github.com/zolrath",
"isDesktopOnly": false
}

View file

@ -0,0 +1 @@
/* no styles */

View file

@ -0,0 +1,489 @@
'use strict';
var obsidian = require('obsidian');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const DEFAULT_SETTINGS = {
enableAutoSuggest: true,
enableFootnoteSectionHeading: false,
FootnoteSectionHeading: "Footnotes",
};
class FootnotePluginSettingTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
containerEl.createEl("h2", {
text: "Footnote Shortcut",
});
const mainDesc = containerEl.createEl('p');
mainDesc.appendText('Need help? Check the ');
mainDesc.appendChild(createEl('a', {
text: "README",
href: "https://github.com/MichaBrugger/obsidian-footnotes",
}));
mainDesc.appendText('!');
containerEl.createEl('br');
new obsidian.Setting(containerEl)
.setName("Enable Footnote Autosuggest")
.setDesc("Suggests existing footnotes when entering named footnotes.")
.addToggle((toggle) => toggle
.setValue(this.plugin.settings.enableAutoSuggest)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.enableAutoSuggest = value;
yield this.plugin.saveSettings();
})));
containerEl.createEl("h3", {
text: "Footnotes Section Behavior",
});
new obsidian.Setting(containerEl)
.setName("Enable Footnote Section Heading")
.setDesc("Automatically adds a heading separating footnotes at the bottom of the note from the rest of the text.")
.addToggle((toggle) => toggle
.setValue(this.plugin.settings.enableFootnoteSectionHeading)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.enableFootnoteSectionHeading = value;
yield this.plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName("Footnote Section Heading")
.setDesc("Heading to place above footnotes section (Supports Markdown formatting). Heading will be H1 size.")
.addText((text) => text
.setPlaceholder("Heading is Empty")
.setValue(this.plugin.settings.FootnoteSectionHeading)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
this.plugin.settings.FootnoteSectionHeading = value;
yield this.plugin.saveSettings();
})));
}
}
var AllMarkers = /\[\^([^\[\]]+)\](?!:)/dg;
var AllNumberedMarkers = /\[\^(\d+)\]/gi;
var AllDetailsNameOnly = /\[\^([^\[\]]+)\]:/g;
var DetailInLine = /\[\^([^\[\]]+)\]:/;
var ExtractNameFromFootnote = /(\[\^)([^\[\]]+)(?=\])/;
function listExistingFootnoteDetails(doc) {
let FootnoteDetailList = [];
//search each line for footnote details and add to list
for (let i = 0; i < doc.lineCount(); i++) {
let theLine = doc.getLine(i);
let lineMatch = theLine.match(AllDetailsNameOnly);
if (lineMatch) {
let temp = lineMatch[0];
temp = temp.replace("[^", "");
temp = temp.replace("]:", "");
FootnoteDetailList.push(temp);
}
}
if (FootnoteDetailList.length > 0) {
return FootnoteDetailList;
}
else {
return null;
}
}
function listExistingFootnoteMarkersAndLocations(doc) {
let markerEntry;
let FootnoteMarkerInfo = [];
//search each line for footnote markers
//for each, add their name, line number, and start index to FootnoteMarkerInfo
for (let i = 0; i < doc.lineCount(); i++) {
let theLine = doc.getLine(i);
let lineMatch;
while ((lineMatch = AllMarkers.exec(theLine)) != null) {
markerEntry = {
footnote: lineMatch[0],
lineNum: i,
startIndex: lineMatch.index
};
FootnoteMarkerInfo.push(markerEntry);
}
}
return FootnoteMarkerInfo;
}
function shouldJumpFromDetailToMarker(lineText, cursorPosition, doc) {
// check if we're in a footnote detail line ("[^1]: footnote")
// if so, jump cursor back to the footnote in the text
let match = lineText.match(DetailInLine);
if (match) {
let s = match[0];
let index = s.replace("[^", "");
index = index.replace("]:", "");
let footnote = s.replace(":", "");
let returnLineIndex = cursorPosition.line;
// find the FIRST OCCURENCE where this footnote exists in the text
for (let i = 0; i < doc.lineCount(); i++) {
let scanLine = doc.getLine(i);
if (scanLine.contains(footnote)) {
let cursorLocationIndex = scanLine.indexOf(footnote);
returnLineIndex = i;
doc.setCursor({
line: returnLineIndex,
ch: cursorLocationIndex + footnote.length,
});
return true;
}
}
}
return false;
}
function shouldJumpFromMarkerToDetail(lineText, cursorPosition, doc) {
// Jump cursor TO detail marker
// does this line have a footnote marker?
// does the cursor overlap with one of them?
// if so, which one?
// find this footnote marker's detail line
// place cursor there
let markerTarget = null;
let FootnoteMarkerInfo = listExistingFootnoteMarkersAndLocations(doc);
let currentLine = cursorPosition.line;
let footnotesOnLine = FootnoteMarkerInfo.filter((markerEntry) => markerEntry.lineNum === currentLine);
if (footnotesOnLine != null) {
for (let i = 0; i <= footnotesOnLine.length - 1; i++) {
if (footnotesOnLine[i].footnote !== null) {
let marker = footnotesOnLine[i].footnote;
let indexOfMarkerInLine = footnotesOnLine[i].startIndex;
if (cursorPosition.ch >= indexOfMarkerInLine &&
cursorPosition.ch <= indexOfMarkerInLine + marker.length) {
markerTarget = marker;
break;
}
}
}
}
if (markerTarget !== null) {
// extract name
let match = markerTarget.match(ExtractNameFromFootnote);
if (match) {
let footnoteName = match[2];
// find the first line with this detail marker name in it.
for (let i = 0; i < doc.lineCount(); i++) {
let theLine = doc.getLine(i);
let lineMatch = theLine.match(DetailInLine);
if (lineMatch) {
// compare to the index
let nameMatch = lineMatch[1];
if (nameMatch == footnoteName) {
doc.setCursor({ line: i, ch: lineMatch[0].length + 1 });
return true;
}
}
}
}
}
return false;
}
function addFootnoteSectionHeader(plugin) {
//check if 'Enable Footnote Section Heading' is true
//if so, return the "Footnote Section Heading"
// else, return ""
if (plugin.settings.enableFootnoteSectionHeading == true) {
let returnHeading = `\n# ${plugin.settings.FootnoteSectionHeading}`;
return returnHeading;
}
return "";
}
//FUNCTIONS FOR AUTONUMBERED FOOTNOTES
function insertAutonumFootnote(plugin) {
const mdView = app.workspace.getActiveViewOfType(obsidian.MarkdownView);
if (!mdView)
return false;
if (mdView.editor == undefined)
return false;
const doc = mdView.editor;
const cursorPosition = doc.getCursor();
const lineText = doc.getLine(cursorPosition.line);
const markdownText = mdView.data;
if (shouldJumpFromDetailToMarker(lineText, cursorPosition, doc))
return;
if (shouldJumpFromMarkerToDetail(lineText, cursorPosition, doc))
return;
return shouldCreateAutonumFootnote(lineText, cursorPosition, plugin, doc, markdownText);
}
function shouldCreateAutonumFootnote(lineText, cursorPosition, plugin, doc, markdownText) {
// create new footnote with the next numerical index
let matches = markdownText.match(AllNumberedMarkers);
let currentMax = 1;
if (matches != null) {
for (let i = 0; i <= matches.length - 1; i++) {
let match = matches[i];
match = match.replace("[^", "");
match = match.replace("]", "");
let matchNumber = Number(match);
if (matchNumber + 1 > currentMax) {
currentMax = matchNumber + 1;
}
}
}
let footNoteId = currentMax;
let footnoteMarker = `[^${footNoteId}]`;
let linePart1 = lineText.substr(0, cursorPosition.ch);
let linePart2 = lineText.substr(cursorPosition.ch);
let newLine = linePart1 + footnoteMarker + linePart2;
doc.replaceRange(newLine, { line: cursorPosition.line, ch: 0 }, { line: cursorPosition.line, ch: lineText.length });
let lastLineIndex = doc.lastLine();
let lastLine = doc.getLine(lastLineIndex);
while (lastLineIndex > 0) {
lastLine = doc.getLine(lastLineIndex);
if (lastLine.length > 0) {
doc.replaceRange("", { line: lastLineIndex, ch: 0 }, { line: doc.lastLine(), ch: 0 });
break;
}
lastLineIndex--;
}
let footnoteDetail = `\n[^${footNoteId}]: `;
let list = listExistingFootnoteDetails(doc);
if (list === null && currentMax == 1) {
footnoteDetail = "\n" + footnoteDetail;
let Heading = addFootnoteSectionHeader(plugin);
doc.setLine(doc.lastLine(), lastLine + Heading + footnoteDetail);
doc.setCursor(doc.lastLine() - 1, footnoteDetail.length - 1);
}
else {
doc.setLine(doc.lastLine(), lastLine + footnoteDetail);
doc.setCursor(doc.lastLine(), footnoteDetail.length - 1);
}
}
//FUNCTIONS FOR NAMED FOOTNOTES
function insertNamedFootnote(plugin) {
const mdView = app.workspace.getActiveViewOfType(obsidian.MarkdownView);
if (!mdView)
return false;
if (mdView.editor == undefined)
return false;
const doc = mdView.editor;
const cursorPosition = doc.getCursor();
const lineText = doc.getLine(cursorPosition.line);
mdView.data;
if (shouldJumpFromDetailToMarker(lineText, cursorPosition, doc))
return;
if (shouldJumpFromMarkerToDetail(lineText, cursorPosition, doc))
return;
if (shouldCreateMatchingFootnoteDetail(lineText, cursorPosition, plugin, doc))
return;
return shouldCreateFootnoteMarker(lineText, cursorPosition, doc);
}
function shouldCreateMatchingFootnoteDetail(lineText, cursorPosition, plugin, doc) {
// Create matching footnote detail for footnote marker
// does this line have a footnote marker?
// does the cursor overlap with one of them?
// if so, which one?
// does this footnote marker have a detail line?
// if not, create it and place cursor there
let reOnlyMarkersMatches = lineText.match(AllMarkers);
let markerTarget = null;
if (reOnlyMarkersMatches) {
for (let i = 0; i <= reOnlyMarkersMatches.length; i++) {
let marker = reOnlyMarkersMatches[i];
if (marker != undefined) {
let indexOfMarkerInLine = lineText.indexOf(marker);
if (cursorPosition.ch >= indexOfMarkerInLine &&
cursorPosition.ch <= indexOfMarkerInLine + marker.length) {
markerTarget = marker;
break;
}
}
}
}
if (markerTarget != null) {
//extract footnote
let match = markerTarget.match(ExtractNameFromFootnote);
//find if this footnote exists by listing existing footnote details
if (match) {
let footnoteId = match[2];
let list = listExistingFootnoteDetails(doc);
// Check if the list is empty OR if the list doesn't include current footnote
// if so, add detail for the current footnote
if (list === null || !list.includes(footnoteId)) {
let lastLineIndex = doc.lastLine();
let lastLine = doc.getLine(lastLineIndex);
while (lastLineIndex > 0) {
lastLine = doc.getLine(lastLineIndex);
if (lastLine.length > 0) {
doc.replaceRange("", { line: lastLineIndex, ch: 0 }, { line: doc.lastLine(), ch: 0 });
break;
}
lastLineIndex--;
}
let footnoteDetail = `\n[^${footnoteId}]: `;
if (list === null || list.length < 1) {
footnoteDetail = "\n" + footnoteDetail;
let Heading = addFootnoteSectionHeader(plugin);
doc.setLine(doc.lastLine(), lastLine + Heading + footnoteDetail);
doc.setCursor(doc.lastLine() - 1, footnoteDetail.length - 1);
}
else {
doc.setLine(doc.lastLine(), lastLine + footnoteDetail);
doc.setCursor(doc.lastLine(), footnoteDetail.length - 1);
}
return true;
}
return;
}
}
}
function shouldCreateFootnoteMarker(lineText, cursorPosition, doc, markdownText) {
//create empty footnote marker for name input
let emptyMarker = `[^]`;
doc.replaceRange(emptyMarker, doc.getCursor());
//move cursor in between [^ and ]
doc.setCursor(cursorPosition.line, cursorPosition.ch + 2);
//open footnotePicker popup
}
class Autocomplete extends obsidian.EditorSuggest {
constructor(plugin) {
super(plugin.app);
this.Footnote_Detail_Names_And_Text = /\[\^([^\[\]]+)\]:(.+(?:\n(?:(?!\[\^[^\[\]]+\]:).)+)*)/g;
this.getSuggestions = (context) => {
const { query } = context;
const mdView = app.workspace.getActiveViewOfType(obsidian.MarkdownView);
const doc = mdView.editor;
const matches = this.Extract_Footnote_Detail_Names_And_Text(doc);
const filteredResults = matches.filter((entry) => entry[1].includes(query));
return filteredResults;
};
this.plugin = plugin;
}
onTrigger(cursorPosition, doc, file) {
if (this.plugin.settings.enableAutoSuggest) {
const mdView = app.workspace.getActiveViewOfType(obsidian.MarkdownView);
const lineText = doc.getLine(cursorPosition.line);
mdView.data;
let reOnlyMarkersMatches = lineText.match(AllMarkers);
let markerTarget = null;
let indexOfMarkerInLine = null;
if (reOnlyMarkersMatches) {
for (let i = 0; i <= reOnlyMarkersMatches.length; i++) {
let marker = reOnlyMarkersMatches[i];
if (marker != undefined) {
indexOfMarkerInLine = lineText.indexOf(marker);
if (cursorPosition.ch >= indexOfMarkerInLine &&
cursorPosition.ch <= indexOfMarkerInLine + marker.length) {
markerTarget = marker;
break;
}
}
}
}
if (markerTarget != null) {
//extract footnote
let match = markerTarget.match(ExtractNameFromFootnote);
//find if this footnote exists by listing existing footnote details
if (match) {
let footnoteId = match[2];
if (footnoteId !== undefined) {
this.latestTriggerInfo = {
end: cursorPosition,
start: {
ch: indexOfMarkerInLine + 2,
line: cursorPosition.line
},
query: footnoteId
};
return this.latestTriggerInfo;
}
}
}
return null;
}
}
Extract_Footnote_Detail_Names_And_Text(doc) {
//search each line for footnote details and add to list
//save the footnote detail name as capture group 1
//save the footnote detail text as capture group 2
let docText = doc.getValue();
const matches = Array.from(docText.matchAll(this.Footnote_Detail_Names_And_Text));
return matches;
}
renderSuggestion(value, el) {
el.createEl("b", { text: value[1] });
el.createEl("br");
el.createEl("p", { text: value[2] });
}
selectSuggestion(value, evt) {
const { context, plugin } = this;
if (!context)
return;
const mdView = app.workspace.getActiveViewOfType(obsidian.MarkdownView);
mdView.editor;
const field = value[1];
const replacement = `${field}`;
context.editor.replaceRange(replacement, this.latestTriggerInfo.start, this.latestTriggerInfo.end);
}
}
//Add chevron-up-square icon from lucide for mobile toolbar (temporary until Obsidian updates to Lucide v0.130.0)
obsidian.addIcon("chevron-up-square", `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-up-square"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"></rect><polyline points="8,14 12,10 16,14"></polyline></svg>`);
class FootnotePlugin extends obsidian.Plugin {
onload() {
return __awaiter(this, void 0, void 0, function* () {
yield this.loadSettings();
this.registerEditorSuggest(new Autocomplete(this));
this.addCommand({
id: "insert-autonumbered-footnote",
name: "Insert / Navigate Auto-Numbered Footnote",
icon: "plus-square",
checkCallback: (checking) => {
if (checking)
return !!this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
insertAutonumFootnote(this);
},
});
this.addCommand({
id: "insert-named-footnote",
name: "Insert / Navigate Named Footnote",
icon: "chevron-up-square",
checkCallback: (checking) => {
if (checking)
return !!this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
insertNamedFootnote(this);
}
});
this.addSettingTab(new FootnotePluginSettingTab(this.app, this));
});
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.settings);
});
}
}
module.exports = FootnotePlugin;
/* nosourcemap */

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-footnotes",
"name": "Footnote Shortcut",
"version": "0.1.3",
"minAppVersion": "0.12.0",
"description": "Insert and write footnotes faster",
"author": "Alexis Rondeau, Micha Brugger, Jason Qin",
"authorUrl": "https://publish.obsidian.md/alexisrondeau",
"isDesktopOnly": false
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-icon-folder",
"name": "Iconize",
"version": "2.14.7",
"minAppVersion": "0.9.12",
"description": "Add icons to anything you desire in Obsidian, including files, folders, and text.",
"author": "Florian Woelki",
"authorUrl": "https://florianwoelki.com/",
"isDesktopOnly": false
}

View file

@ -0,0 +1,120 @@
.iconize-inline-title-wrapper {
width: var(--line-width);
max-width: var(--max-width);
margin-inline: var(--content-margin);
}
.iconize-title-icon {
max-width: var(--max-width);
margin-right: var(--size-4-2);
}
.iconize-icon-in-link {
transform: translateY(20%);
margin-right: var(--size-2-2);
display: inline-flex;
}
.iconize-icon {
border: 1px solid transparent;
margin: 0px 4px 0px 0px;
display: flex;
align-self: center;
margin: auto 0;
}
.nav-folder-title,
.nav-file-title {
align-items: center;
}
.iconize-setting input[type='color'] {
margin: 0 6px;
}
.iconize-modal.prompt-results {
margin: 0;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
}
.prompt .iconize-subheadline {
margin-top: 12px;
font-size: 12px;
color: gray;
grid-column-start: 1;
grid-column-end: 6;
}
@media (max-width: 640px) {
.iconize-modal.prompt-results {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.prompt .iconize-subheadline {
grid-column-end: 4;
}
}
.iconize-modal.prompt-results .suggestion-item {
cursor: pointer;
white-space: pre-wrap;
display: flex;
justify-content: flex-end;
align-items: center;
flex-direction: column-reverse;
text-align: center;
font-size: 13px;
color: var(--text-muted);
padding: 16px 8px;
line-break: auto;
word-break: break-word;
line-height: 1.3;
}
.iconize-modal.prompt-results .suggestion-item.suggestion-item__center {
justify-content: center;
}
.iconize-icon-preview {
font-size: 22px;
}
.iconize-icon-preview img {
width: 16px;
height: 16px;
}
.iconize-icon-preview svg {
width: 24px;
height: 24px;
color: currentColor;
margin-bottom: 4px;
}
.iconize-dragover {
position: relative;
}
.iconize-dragover-el {
position: absolute;
width: 100%;
height: 100%;
color: var(--text-normal);
background-color: var(--background-secondary-alt);
display: flex;
align-items: center;
justify-content: center;
}
/* Custom rule modal. */
.iconize-custom-modal .modal-content {
display: flex;
align-items: center;
justify-content: center;
}
.iconize-custom-modal .modal-content input {
width: 100%;
margin-right: 0.5rem;
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-link-embed",
"name": "Link Embed",
"version": "2.5.5",
"minAppVersion": "0.12.0",
"description": "Instantly turn plain links in your notes into beautiful, Notion-style rich link previews. The plugin automatically fetches page metadata (title, description, favicon & image) and renders it as an elegant, card-styled embed—so your vault stays informative and visually appealing with zero extra effort.",
"author": "SErAphLi",
"authorUrl": "https://github.com/Seraphli",
"isDesktopOnly": false
}

View file

@ -0,0 +1,336 @@
.w {
overflow: hidden;
margin: 0;
padding: 0;
background: none transparent;
text-align: left;
}
.em > a,
.tc > a,
.th > a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
.em > a,
.tc > a,
.th > a {
text-decoration: none;
color: inherit;
-ms-touch-action: manipulation;
touch-action: manipulation;
}
.w {
line-height: 1.4;
font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI',
Roboto, 'Helvetica Neue', Arial, sans-serif;
font-weight: 400;
font-size: 15px;
color: inherit;
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
word-wrap: break-word;
overflow-wrap: break-word;
}
.t,
.w,
.wf {
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
max-width: 100%;
width: 100%;
}
@supports (-webkit-overflow-scrolling: touch) {
.w {
max-width: 100vw;
}
}
.wc,
.wt {
overflow: hidden;
}
._sm {
background: inherit;
}
._lc .wf {
-ms-flex-direction: row;
flex-direction: row;
}
._lc .wt {
display: -ms-flexbox;
display: flex;
-ms-flex: 1;
flex: 1;
-ms-flex-align: center;
align-items: center;
}
.wt {
padding: 8px 10px;
}
@media (min-width: 360px) {
.wt {
padding: 12px 15px;
}
}
@media (min-width: 600px) {
.wt {
padding: 16px 20px;
}
}
._lc._sm:not(.xd) .wc {
min-width: 100px;
width: 100px;
min-height: 100px;
}
._lc._sm:not(.xd) .wc._wi {
max-width: min(50%, 200px);
}
@media (min-width: 360px) {
._lc._sm:not(.xd) .wc {
min-width: 110px;
width: 110px;
min-height: 110px;
}
}
@media (min-width: 360px) {
._lc._sm:not(.xd) .wc._wi {
max-width: min(50%, 220px);
}
}
@media (min-width: 460px) {
._lc._sm:not(.xd) .wc {
min-width: 140px;
width: 140px;
min-height: 140px;
}
}
@media (min-width: 460px) {
._lc._sm:not(.xd) .wc._wi {
max-width: min(50%, 280px);
}
}
@media (min-width: 600px) {
._lc._sm:not(.xd) .wc {
min-width: 160px;
width: 160px;
min-height: 160px;
}
}
@media (min-width: 600px) {
._lc._sm:not(.xd) .wc._wi {
max-width: min(50%, 320px);
}
}
@supports (-moz-appearance: meterbar) and (all: initial) {
._lc .wc {
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
-ms-flex-align: stretch;
align-items: stretch;
-ms-flex-line-pack: stretch;
align-content: stretch;
}
}
@media (max-width: 459px) {
._lc .twt {
display: none;
}
}
@media (min-width: 460px) {
._lc .twd {
display: none;
}
}
._lc._ts .th {
-webkit-line-clamp: 1;
}
._lc._ts._lh14 .th {
max-height: 1.4em;
}
._lc._ts .td {
-webkit-line-clamp: 2;
}
._lc._ts._lh14 .td {
max-height: 2.8em;
}
@media (min-width: 460px) {
._lc._ts .th {
-webkit-line-clamp: 1;
}
._lc._ts._lh14 .th {
max-height: 1.4em;
}
._lc._ts .td {
-webkit-line-clamp: 3;
}
._lc._ts._lh14 .td {
max-height: 4.2em;
}
}
.t {
-webkit-hyphens: auto;
-moz-hyphens: auto;
-ms-hyphens: auto;
hyphens: auto;
}
.td,
.th {
overflow: hidden;
text-overflow: ellipsis;
display: block;
}
@supports (display: -webkit-box) {
.td,
.th {
display: -webkit-box;
-webkit-box-orient: vertical;
}
}
.td {
vertical-align: inherit;
}
.tf,
.th {
margin-bottom: 0.5em;
}
.td {
margin-bottom: 0.6em;
}
._od .tf:last-child {
margin-bottom: 0 !important;
}
.tf {
display: -ms-flexbox;
display: flex;
-ms-flex-align: center;
align-items: center;
}
.tc {
-ms-flex: 1;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
@media (min-width: 460px) {
.td {
margin-bottom: 0.7em;
}
}
._ffsa {
font-family: -apple-system, system-ui, BlinkMacSystemFont, 'Segoe UI',
Roboto, 'Helvetica Neue', Arial, sans-serif;
}
._fwn {
font-weight: 400;
}
._fwb {
font-weight: 700;
}
._fsn {
font-style: normal;
}
._lh14 {
line-height: 1.4;
}
._f0,
._f1m {
font-size: 12px;
}
._f1p {
font-size: 13px;
}
@media (min-width: 360px) {
._f0 {
font-size: 13px;
}
._f1p {
font-size: 14px;
}
}
@media (min-width: 460px) {
._f1m {
font-size: 13px;
}
._f0 {
font-size: 14px;
}
._f1p {
font-size: 15px;
}
}
@media (min-width: 600px) {
._f1m {
font-size: 14px;
}
._f0 {
font-size: 15px;
}
._f1p {
font-size: 17px;
}
}
.e {
overflow: hidden;
position: relative;
width: 100%;
}
@supports (-moz-appearance: meterbar) and (all: initial) {
._lc .e {
-ms-flex: 1;
flex: 1;
}
}
._lc:not(._ap) .e {
height: 100%;
}
.em {
position: absolute;
width: 100%;
height: 100%;
}
.c {
position: absolute;
width: 100%;
height: 100%;
}
.c {
display: block;
width: 100%;
height: 100%;
background: no-repeat center;
background-size: cover;
}
.c {
z-index: 20;
}
.w {
background-color: inherit;
}
.t {
line-height: 1.4;
color: inherit;
}
.th {
color: inherit;
}
.tf {
color: #999;
}
.tw {
color: #999;
}
.thl {
font-weight: 600;
}
.embed {
border: 1px solid var(--background-modifier-border);
overflow: hidden;
border-radius: var(--radius-s);
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-markdown-formatting-assistant-plugin",
"name": "Markdown Formatting Assistant",
"version": "0.4.1",
"minAppVersion": "0.15.6",
"description": "This Plugin provides a simple Editor for Markdown, HTML and Colors and in addition a command interface. The command interface facilitate a faster workflow.",
"author": "Reocin",
"authorUrl": "https://github.com/Reocin/obsidian-markdown-formatting-assistant-plugin",
"isDesktopOnly": false
}

View file

@ -0,0 +1,62 @@
/* Sets all the text color to red! */
.nav-action-button {
color: var(--text-muted);
cursor: pointer;
padding: 0px;
margin: 5px;
border-radius: 4px;
}
.nav-action-text-button {
color: var(--text-muted);
cursor: pointer;
padding: 5px;
margin: 4px;
border-radius: 4px;
text-align: center;
border: 1px solid;
}
.nav-action-text-button.is-active {
background-color: var(--interactive-accent);
color: var(--text-on-accent);
}
.nav-action-text-button.is-active:hover {
color: var(--text-on-accent);
}
.nav-action-text-button:hover {
color: var(--text-accent);
}
.color-icon {
color: var(--text-muted);
cursor: pointer;
width: 16px;
min-width: 16px;
max-width: 16px;
height: 16px;
min-height: 16px;
max-height: 16px;
margin: 3px;
display: inline-block;
border-radius: 4px;
}
.command-list-view-row {
display: flex;
}
.command-list-view-container {
min-width: 60px;
display: flex;
}
.command-list-view-icon {
height: 24px;
max-height: 24px;
border: 1px solid gray;
margin-right: auto;
}
.command-list-view-text {
padding-left: 12px;
color: #c7254e;
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
{
"id": "obsidian-style-settings",
"name": "Style Settings",
"version": "1.0.9",
"minAppVersion": "0.11.5",
"description": "Offers controls for adjusting theme, plugin, and snippet CSS variables.",
"author": "mgmeyers",
"authorUrl": "https://github.com/mgmeyers/obsidian-style-settings",
"isDesktopOnly": false
}

File diff suppressed because one or more lines are too long

5561
.obsidian/plugins/periodic-notes/main.js vendored Normal file

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more