Merge branch 'develop' into calendar

This commit is contained in:
Jin 2025-04-01 18:57:09 +02:00
commit bbf7bc9324
41 changed files with 1358 additions and 1226 deletions

8
.gitattributes vendored
View File

@ -2,4 +2,12 @@ package-lock.json linguist-generated=true
**/package-lock.json linguist-generated=true **/package-lock.json linguist-generated=true
src/public/app/doc_notes/en/User[[:space:]]Guide/** linguist-generated=true src/public/app/doc_notes/en/User[[:space:]]Guide/** linguist-generated=true
src/public/app/doc_notes/en/User[[:space:]]Guide/**/*.md eol=lf src/public/app/doc_notes/en/User[[:space:]]Guide/**/*.md eol=lf
demo/**/*.html eol=lf
demo/**/*.json eol=lf
demo/**/*.svg eol=lf
demo/**/*.txt eol=lf
demo/**/*.js eol=lf
demo/**/*.css eol=lf
libraries/** linguist-vendored libraries/** linguist-vendored

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -18,24 +18,30 @@
height="150"> height="150">
</figure> </figure>
<p><strong>Welcome to TriliumNext Notes!</strong> <p><strong>Welcome to TriliumNext Notes!</strong>
</p> </p>
<p>This is initial "demo" document provided by TriliumNext by default to <p>This is initial "demo" document provided by TriliumNext by default to
showcase some of its features and also give you some ideas how you might showcase some of its features and also give you some ideas how you might
structure your notes. You can play with it, modify note content and tree structure your notes. You can play with it, modify note content and tree
structure as you wish.</p> structure as you wish.</p>
<p>If you need any help, visit TriliumNext website: <a href="https://github.com/TriliumNext">https://github.com/TriliumNext</a> <p>If you need any help, visit TriliumNext website: <a href="https://github.com/TriliumNext">https://github.com/TriliumNext</a>
</p> </p>
<h3>Cleanup</h3> <h3>Cleanup</h3>
<p>Once you're finished with experimenting and want to cleanup these pages, <p>Once you're finished with experimenting and want to cleanup these pages,
you can simply delete them all.</p> you can simply delete them all.</p>
<section class="include-note" data-note-id="cFn1UU5L0tbk" <section class="include-note" data-note-id="CN3CCLggUqf4"
data-box-size="medium">&nbsp;</section> data-box-size="medium">&nbsp;</section>
<h3>Formatting</h3> <h3>Formatting</h3>
<p>TriliumNext supports classic formatting like <em>italic</em>, <strong>bold</strong>, <em><strong>bold and italic</strong></em>. <p>TriliumNext supports classic formatting like <em>italic</em>, <strong>bold</strong>, <em><strong>bold and italic</strong></em>.
Of course you can add links like this one pointing to <a href="http://www.google.com">google.com</a> Of course you can add links like this one pointing to <a href="http://www.google.com">google.com</a>
</p> </p>
<p>Lists</p> <p>Lists</p>
<p><strong>Ordered:</strong> <p><strong>Ordered:</strong>
</p> </p>
<ol> <ol>
<li>First Item</li> <li>First Item</li>
@ -50,6 +56,7 @@
</li> </li>
</ol> </ol>
<p><strong>Unordered:</strong> <p><strong>Unordered:</strong>
</p> </p>
<ul> <ul>
<li>Item</li> <li>Item</li>

View File

@ -14,17 +14,22 @@
<div class="ck-content"> <div class="ck-content">
<h2>Main characters</h2> <h2>Main characters</h2>
<p>… here put main characters …</p> <p>… here put main characters …</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<h2>Plot</h2> <h2>Plot</h2>
<p>… describe main plot lines …</p> <p>… describe main plot lines …</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<h2>Tone</h2> <h2>Tone</h2>
<p>&nbsp;</p> <p>&nbsp;</p>
<h2>Genre</h2> <h2>Genre</h2>
<p>scifi / drama / romance</p> <p>scifi / drama / romance</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<h2>Similar books</h2> <h2>Similar books</h2>
<ul> <ul>
<li></li> <li></li>
</ul> </ul>

View File

@ -14,11 +14,14 @@
<div class="ck-content"> <div class="ck-content">
<p>Checkout Kindle daily deals: <a href="https://www.amazon.com/gp/feature.html?docId=1000677541">https://www.amazon.com/gp/feature.html?docId=1000677541</a> <p>Checkout Kindle daily deals: <a href="https://www.amazon.com/gp/feature.html?docId=1000677541">https://www.amazon.com/gp/feature.html?docId=1000677541</a>
</p> </p>
<ul> <ul>
<li>Cixin Liu - <a href="https://www.amazon.com/Dark-Forest-Remembrance-Earths-Past/dp/0765386690/ref=pd_bxgy_14_img_2?_encoding=UTF8&amp;pd_rd_i=0765386690&amp;pd_rd_r=AB0J179TM9NTEAMHE240&amp;pd_rd_w=FAhxX&amp;pd_rd_wg=pLGK7&amp;psc=1&amp;refRID=AB0J179TM9NTEAMHE240">The Dark Forest</a> <li>Cixin Liu - <a href="https://www.amazon.com/Dark-Forest-Remembrance-Earths-Past/dp/0765386690/ref=pd_bxgy_14_img_2?_encoding=UTF8&amp;pd_rd_i=0765386690&amp;pd_rd_r=AB0J179TM9NTEAMHE240&amp;pd_rd_w=FAhxX&amp;pd_rd_wg=pLGK7&amp;psc=1&amp;refRID=AB0J179TM9NTEAMHE240">The Dark Forest</a>
</li> </li>
<li>Ann Leckie - <a href="https://www.amazon.com/Ancillary-Sword-Imperial-Radch-Leckie/dp/0316246654/ref=pd_sim_14_1?_encoding=UTF8&amp;pd_rd_i=0316246654&amp;pd_rd_r=D7KDTGZFP7YM1YSYVY4G&amp;pd_rd_w=jkn28&amp;pd_rd_wg=JVhtw&amp;psc=1&amp;refRID=D7KDTGZFP7YM1YSYVY4G">Ancillary Sword</a> <li>Ann Leckie - <a href="https://www.amazon.com/Ancillary-Sword-Imperial-Radch-Leckie/dp/0316246654/ref=pd_sim_14_1?_encoding=UTF8&amp;pd_rd_i=0316246654&amp;pd_rd_r=D7KDTGZFP7YM1YSYVY4G&amp;pd_rd_w=jkn28&amp;pd_rd_wg=JVhtw&amp;psc=1&amp;refRID=D7KDTGZFP7YM1YSYVY4G">Ancillary Sword</a>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -18,21 +18,25 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">buy milk&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">buy milk&nbsp;</span>
</label> </label>
</li> </li>
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">do the laundry&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">do the laundry&nbsp;</span>
</label> </label>
</li> </li>
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">watch TV&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">watch TV&nbsp;</span>
</label> </label>
</li> </li>
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">eat ice cream&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">eat ice cream&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -22,6 +22,7 @@
scheme for the syntax highlighting is adjustable in settings.&nbsp;</p><pre><code class="language-application-javascript-env-frontend">function helloWorld() { scheme for the syntax highlighting is adjustable in settings.&nbsp;</p><pre><code class="language-application-javascript-env-frontend">function helloWorld() {
alert("Hello world"); alert("Hello world");
}</code></pre> }</code></pre>
<p>For larger pieces of code it is better to use a code note, which uses <p>For larger pieces of code it is better to use a code note, which uses
a fully-fledged code editor (CodeMirror). For an example of a code note, a fully-fledged code editor (CodeMirror). For an example of a code note,
see&nbsp;<a class="reference-link" href="../Scripting%20examples/Custom%20request%20handler.js">Custom request handler</a>.</p> see&nbsp;<a class="reference-link" href="../Scripting%20examples/Custom%20request%20handler.js">Custom request handler</a>.</p>

View File

@ -15,7 +15,9 @@
<div class="ck-content"> <div class="ck-content">
<p><span class="math-tex">\(% \f is defined as #1f(#2) using the macro \f\relax{x} = \int_{-\infty}^\infty &nbsp; &nbsp; \f\hat\xi\,e^{2 \pi i \xi x} &nbsp; &nbsp; \,d\xi\)</span>Some <p><span class="math-tex">\(% \f is defined as #1f(#2) using the macro \f\relax{x} = \int_{-\infty}^\infty &nbsp; &nbsp; \f\hat\xi\,e^{2 \pi i \xi x} &nbsp; &nbsp; \,d\xi\)</span>Some
math examples:</p><span class="math-tex">\[\displaystyle \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots} } } }\]</span> math examples:</p><span class="math-tex">\[\displaystyle \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} = 1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}} {1+\frac{e^{-8\pi}} {1+\cdots} } } }\]</span>
<p>Another:</p><span class="math-tex">\[\displaystyle \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)\]</span> <p>Another:</p><span class="math-tex">\[\displaystyle \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)\]</span>
<p>Inline math is also possible:&nbsp;<span class="math-tex">\(c^2 = a^2 + b^2\)</span>&nbsp;Neat!</p> <p>Inline math is also possible:&nbsp;<span class="math-tex">\(c^2 = a^2 + b^2\)</span>&nbsp;Neat!</p>
<p>&nbsp;</p> <p>&nbsp;</p>
</div> </div>

View File

@ -18,10 +18,11 @@
href="https://en.wikipedia.org/wiki/Short_story">short story</a>by American writer <a href="https://en.wikipedia.org/wiki/Isaac_Asimov">Isaac Asimov</a>. href="https://en.wikipedia.org/wiki/Short_story">short story</a>by American writer <a href="https://en.wikipedia.org/wiki/Isaac_Asimov">Isaac Asimov</a>.
It first appeared in the November 1956 issue of <a href="https://en.wikipedia.org/wiki/Science_Fiction_Quarterly"><em>Science Fiction Quarterly</em></a>.</p> It first appeared in the November 1956 issue of <a href="https://en.wikipedia.org/wiki/Science_Fiction_Quarterly"><em>Science Fiction Quarterly</em></a>.</p>
<section <section
class="include-note" data-note-id="WdDLhuzYxRlW" data-box-size="medium">&nbsp;</section> class="include-note" data-note-id="ZWCYra81yOFO" data-box-size="medium">&nbsp;</section>
<p>This page demonstrates two things:</p> <p>This page demonstrates two things:</p>
<ul> <ul>
<li>possibility to <a href="https://github.com/zadam/trilium/wiki/Text-editor#include-note">include one note into another</a> <li>possibility to <a href="https://github.com/zadam/trilium/wiki/Text-editor#include-note">include one note into another</a>
</li> </li>
<li>PDF preview - you can read PDFs directly in Trilium!</li> <li>PDF preview - you can read PDFs directly in Trilium!</li>
</ul> </ul>

View File

@ -68,6 +68,7 @@
<div> <div>
<div> <div>
<p>You can read some explanation on how this journal works here: <a href="https://github.com/zadam/trilium/wiki/Day-notes">https://github.com/zadam/trilium/wiki/Day-notes</a> <p>You can read some explanation on how this journal works here: <a href="https://github.com/zadam/trilium/wiki/Day-notes">https://github.com/zadam/trilium/wiki/Day-notes</a>
</p> </p>
</div> </div>
</div> </div>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -17,6 +17,7 @@
<li>XBox</li> <li>XBox</li>
<li>Candles</li> <li>Candles</li>
<li><a href="https://www.amazon.ca/Anker-SoundCore-Portable-Bluetooth-Resistance/dp/B01MTB55WH?pd_rd_wg=honW8&amp;pd_rd_r=c9bb7c0f-0051-4da7-991f-4ca711a1b3e3&amp;pd_rd_w=ciUpR&amp;ref_=pd_gw_simh&amp;pf_rd_r=K10XKX0NGPDNTYYP4BS4&amp;pf_rd_p=5f1b460b-78c1-580e-929e-2878fe4859e8">Portable speakers</a> <li><a href="https://www.amazon.ca/Anker-SoundCore-Portable-Bluetooth-Resistance/dp/B01MTB55WH?pd_rd_wg=honW8&amp;pd_rd_r=c9bb7c0f-0051-4da7-991f-4ca711a1b3e3&amp;pd_rd_w=ciUpR&amp;ref_=pd_gw_simh&amp;pf_rd_r=K10XKX0NGPDNTYYP4BS4&amp;pf_rd_p=5f1b460b-78c1-580e-929e-2878fe4859e8">Portable speakers</a>
</li> </li>
<li>...?</li> <li>...?</li>
</ul> </ul>

View File

@ -14,8 +14,10 @@
<div class="ck-content"> <div class="ck-content">
<p>Wiki: <a href="https://en.wikipedia.org/wiki/Trusted_timestamping">https://en.wikipedia.org/wiki/Trusted_timestamping</a> <p>Wiki: <a href="https://en.wikipedia.org/wiki/Trusted_timestamping">https://en.wikipedia.org/wiki/Trusted_timestamping</a>
</p> </p>
<p>Bozho: <a href="https://techblog.bozho.net/using-trusted-timestamping-java/">https://techblog.bozho.net/using-trusted-timestamping-java/</a> <p>Bozho: <a href="https://techblog.bozho.net/using-trusted-timestamping-java/">https://techblog.bozho.net/using-trusted-timestamping-java/</a>
</p> </p>
<p><strong>Trusted timestamping</strong> is the process of <a href="https://en.wikipedia.org/wiki/Computer_security">securely</a> keeping <p><strong>Trusted timestamping</strong> is the process of <a href="https://en.wikipedia.org/wiki/Computer_security">securely</a> keeping
track of the creation and modification time of a document. Security here track of the creation and modification time of a document. Security here

View File

@ -16,6 +16,7 @@
<p>Miscellaneous notes done on monday ...</p> <p>Miscellaneous notes done on monday ...</p>
<p>&nbsp;</p> <p>&nbsp;</p>
<p>Interesting video: <a href="https://www.youtube.com/watch?v=_eSAF_qT_FY&amp;feature=youtu.be">https://www.youtube.com/watch?v=_eSAF_qT_FY&amp;feature=youtu.be</a> <p>Interesting video: <a href="https://www.youtube.com/watch?v=_eSAF_qT_FY&amp;feature=youtu.be">https://www.youtube.com/watch?v=_eSAF_qT_FY&amp;feature=youtu.be</a>
</p> </p>
<p>&nbsp;</p> <p>&nbsp;</p>
<p>&nbsp;</p> <p>&nbsp;</p>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -18,6 +18,7 @@
width="209" height="300"> width="209" height="300">
</figure> </figure>
<p>Maybe CodeNames? <a href="https://boardgamegeek.com/boardgame/178900/codenames">https://boardgamegeek.com/boardgame/178900/codenames</a> <p>Maybe CodeNames? <a href="https://boardgamegeek.com/boardgame/178900/codenames">https://boardgamegeek.com/boardgame/178900/codenames</a>
</p> </p>
</div> </div>
</div> </div>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -18,6 +18,7 @@
<li> <li>
<label class="todo-list__label"> <label class="todo-list__label">
<input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span> <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">&nbsp;&nbsp;</span>
</label> </label>
</li> </li>
</ul> </ul>

View File

@ -15,6 +15,7 @@
<div class="ck-content"> <div class="ck-content">
<p>This is a simple TODO/Task manager. You can see some description and explanation <p>This is a simple TODO/Task manager. You can see some description and explanation
here: <a href="https://github.com/zadam/trilium/wiki/Task-manager">https://github.com/zadam/trilium/wiki/Task-manager</a> here: <a href="https://github.com/zadam/trilium/wiki/Task-manager">https://github.com/zadam/trilium/wiki/Task-manager</a>
</p> </p>
<p>Please note that this is meant as scripting example only and feature/bug <p>Please note that this is meant as scripting example only and feature/bug
support is very limited.</p> support is very limited.</p>

View File

@ -71,6 +71,7 @@
<img src="Buy a board game for Alice.jpg"> <img src="Buy a board game for Alice.jpg">
</figure> </figure>
<p>Maybe CodeNames? <a href="https://boardgamegeek.com/boardgame/178900/codenames">https://boardgamegeek.com/boardgame/178900/codenames</a> <p>Maybe CodeNames? <a href="https://boardgamegeek.com/boardgame/178900/codenames">https://boardgamegeek.com/boardgame/178900/codenames</a>
</p> </p>
</div> </div>
</div> </div>

View File

@ -14,6 +14,7 @@
<div class="ck-content"> <div class="ck-content">
<p><a href="https://en.wikipedia.org/wiki/The_Black_Swan:_The_Impact_of_the_Highly_Improbable">https://en.wikipedia.org/wiki/The_Black_Swan:_The_Impact_of_the_Highly_Improbable</a> <p><a href="https://en.wikipedia.org/wiki/The_Black_Swan:_The_Impact_of_the_Highly_Improbable">https://en.wikipedia.org/wiki/The_Black_Swan:_The_Impact_of_the_Highly_Improbable</a>
</p> </p>
<p><em><strong>The Black Swan: The Impact of the Highly Improbable</strong></em> is <p><em><strong>The Black Swan: The Impact of the Highly Improbable</strong></em> is
a 2007 book by author and former <a href="https://en.wikipedia.org/wiki/Options_trader">options trader</a> a 2007 book by author and former <a href="https://en.wikipedia.org/wiki/Options_trader">options trader</a>

View File

@ -25,6 +25,7 @@
and <a href="https://en.wikipedia.org/wiki/Apple_Inc.">Apple's</a> <a href="https://en.wikipedia.org/wiki/MacOS">macOS</a> (formerly and <a href="https://en.wikipedia.org/wiki/Apple_Inc.">Apple's</a> <a href="https://en.wikipedia.org/wiki/MacOS">macOS</a> (formerly
OS X). A version <a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux">is also available for Windows 10</a>.</p> OS X). A version <a href="https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux">is also available for Windows 10</a>.</p>
<p><a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)">Bash on Wikipedia</a> <p><a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)">Bash on Wikipedia</a>
</p> </p>
</div> </div>
</div> </div>

View File

@ -14,6 +14,7 @@
<div class="ck-content"> <div class="ck-content">
<h3>Login shell</h3> <h3>Login shell</h3>
<p>As a "login shell", Bash reads and sets (executes) the user's profile <p>As a "login shell", Bash reads and sets (executes) the user's profile
from /etc/profile and one of ~/.bash_profile, ~/.bash_login, or ~/.profile from /etc/profile and one of ~/.bash_profile, ~/.bash_login, or ~/.profile
(in that order, using the first one that's readable!).</p> (in that order, using the first one that's readable!).</p>
@ -23,6 +24,7 @@
that only make sense for the initial user login. That's why all UNIX® shells that only make sense for the initial user login. That's why all UNIX® shells
have (should have) a "login" mode.</p> have (should have) a "login" mode.</p>
<p><em><strong>Methods to start Bash as a login shell:</strong></em> <p><em><strong>Methods to start Bash as a login shell:</strong></em>
</p> </p>
<ul> <ul>
<li>the first character of argv[0] is - (a hyphen): traditional UNIX® shells <li>the first character of argv[0] is - (a hyphen): traditional UNIX® shells
@ -31,17 +33,20 @@
<li>Bash is started with the --login option</li> <li>Bash is started with the --login option</li>
</ul> </ul>
<p><em><strong>Methods to test for login shell mode:</strong></em> <p><em><strong>Methods to test for login shell mode:</strong></em>
</p> </p>
<ul> <ul>
<li>the shell option <a href="http://wiki.bash-hackers.org/internals/shell_options#login_shell">login_shell</a> is <li>the shell option <a href="http://wiki.bash-hackers.org/internals/shell_options#login_shell">login_shell</a> is
set</li> set</li>
</ul> </ul>
<p><em><strong>Related switches:</strong></em> <p><em><strong>Related switches:</strong></em>
</p> </p>
<ul> <ul>
<li>--noprofile disables reading of all profile files</li> <li>--noprofile disables reading of all profile files</li>
</ul> </ul>
<h3>Interactive shell</h3> <h3>Interactive shell</h3>
<p>When Bash starts as an interactive non-login shell, it reads and executes <p>When Bash starts as an interactive non-login shell, it reads and executes
commands from ~/.bashrc. This file should contain, for example, aliases, commands from ~/.bashrc. This file should contain, for example, aliases,
since they need to be defined in every shell as they're not inherited from since they need to be defined in every shell as they're not inherited from
@ -51,11 +56,13 @@
The classic way to have a system-wide rc file is to source /etc/bashrc The classic way to have a system-wide rc file is to source /etc/bashrc
from every user's ~/.bashrc.</p> from every user's ~/.bashrc.</p>
<p><em><strong>Methods to test for interactive-shell mode:</strong></em> <p><em><strong>Methods to test for interactive-shell mode:</strong></em>
</p> </p>
<ul> <ul>
<li>the special parameter $- contains the letter i (lowercase I)</li> <li>the special parameter $- contains the letter i (lowercase I)</li>
</ul> </ul>
<p><em><strong>Related switches:</strong></em> <p><em><strong>Related switches:</strong></em>
</p> </p>
<ul> <ul>
<li>-i forces the interactive mode</li> <li>-i forces the interactive mode</li>
@ -64,7 +71,8 @@
<li>--rcfile defines another startup file (instead of /etc/bash.bashrc and <li>--rcfile defines another startup file (instead of /etc/bash.bashrc and
~/.bashrc)</li> ~/.bashrc)</li>
</ul> </ul>
<h3>SH mode</h3> <h3>SH mode</h3>
<p>When Bash starts in SH compatiblity mode, it tries to mimic the startup <p>When Bash starts in SH compatiblity mode, it tries to mimic the startup
behaviour of historical versions of sh as closely as possible, while conforming behaviour of historical versions of sh as closely as possible, while conforming
to the POSIX® standard as well. The profile files read are /etc/profile to the POSIX® standard as well. The profile files read are /etc/profile
@ -74,6 +82,7 @@
file.</p> file.</p>
<p>After the startup files are read, Bash enters the <a href="http://wiki.bash-hackers.org/scripting/bashbehaviour#posix_run_mode">POSIX(r) compatiblity mode (for running, not for starting!)</a>.</p> <p>After the startup files are read, Bash enters the <a href="http://wiki.bash-hackers.org/scripting/bashbehaviour#posix_run_mode">POSIX(r) compatiblity mode (for running, not for starting!)</a>.</p>
<p><em><strong>Bash starts in sh compatiblity mode when:</strong></em> <p><em><strong>Bash starts in sh compatiblity mode when:</strong></em>
</p> </p>
<ul> <ul>
<li> <li>

View File

@ -14,6 +14,7 @@
<div class="ck-content"> <div class="ck-content">
<p>Documentation: <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html">http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html</a> <p>Documentation: <a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html">http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_02.html</a>
</p><pre><code class="language-text-x-sh">#!/bin/bash </p><pre><code class="language-text-x-sh">#!/bin/bash
# This script opens 4 terminal windows. # This script opens 4 terminal windows.

View File

@ -74,6 +74,7 @@
href="https://en.wikipedia.org/wiki/Node.js#cite_note-b1-31">[31]</a>Developers can create scalable servers without using <a href="https://en.wikipedia.org/wiki/Thread_(computing)">threading</a>, href="https://en.wikipedia.org/wiki/Node.js#cite_note-b1-31">[31]</a>Developers can create scalable servers without using <a href="https://en.wikipedia.org/wiki/Thread_(computing)">threading</a>,
by using a simplified model of <a href="https://en.wikipedia.org/wiki/Event-driven_programming">event-driven programming</a> that by using a simplified model of <a href="https://en.wikipedia.org/wiki/Event-driven_programming">event-driven programming</a> that
uses callbacks to signal the completion of a task.<a href="https://en.wikipedia.org/wiki/Node.js#cite_note-b1-31">[31]</a> uses callbacks to signal the completion of a task.<a href="https://en.wikipedia.org/wiki/Node.js#cite_note-b1-31">[31]</a>
</p> </p>
</div> </div>
</div> </div>

View File

@ -8,7 +8,7 @@ export async function initializeDatabase() {
cls.init(() => { cls.init(() => {
if (!sqlInit.isDbInitialized()) { if (!sqlInit.isDbInitialized()) {
sqlInit.createInitialDatabase(); sqlInit.createInitialDatabase(true);
} }
}); });
} }

228
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "trilium", "name": "trilium",
"version": "0.92.5", "version": "0.92.5-beta",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "trilium", "name": "trilium",
"version": "0.92.5", "version": "0.92.5-beta",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"dependencies": { "dependencies": {
"@braintree/sanitize-url": "7.1.1", "@braintree/sanitize-url": "7.1.1",
@ -157,7 +157,7 @@
"@types/ws": "8.18.0", "@types/ws": "8.18.0",
"@types/xml2js": "0.4.14", "@types/xml2js": "0.4.14",
"@types/yargs": "17.0.33", "@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.0.9", "@vitest/coverage-v8": "3.1.1",
"autoprefixer": "10.4.21", "autoprefixer": "10.4.21",
"bootstrap": "5.3.3", "bootstrap": "5.3.3",
"copy-webpack-plugin": "13.0.0", "copy-webpack-plugin": "13.0.0",
@ -181,7 +181,7 @@
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"rimraf": "6.0.1", "rimraf": "6.0.1",
"sass": "1.86.0", "sass": "1.86.1",
"sass-loader": "16.0.5", "sass-loader": "16.0.5",
"script-loader": "0.7.2", "script-loader": "0.7.2",
"split.js": "1.6.5", "split.js": "1.6.5",
@ -193,9 +193,9 @@
"tsx": "4.19.3", "tsx": "4.19.3",
"typedoc": "0.28.1", "typedoc": "0.28.1",
"typescript": "5.8.2", "typescript": "5.8.2",
"typescript-eslint": "8.28.0", "typescript-eslint": "8.29.0",
"vanilla-js-wheel-zoom": "9.0.4", "vanilla-js-wheel-zoom": "9.0.4",
"vitest": "3.0.9", "vitest": "3.1.1",
"webpack": "5.98.0", "webpack": "5.98.0",
"webpack-cli": "6.0.1", "webpack-cli": "6.0.1",
"webpack-dev-middleware": "7.4.2" "webpack-dev-middleware": "7.4.2"
@ -5588,17 +5588,17 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.0.tgz",
"integrity": "sha512-lvFK3TCGAHsItNdWZ/1FkvpzCxTHUVuFrdnOGLMa0GGCFIbCgQWVk3CzCGdA7kM3qGVc+dfW9tr0Z/sHnGDFyg==", "integrity": "sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.28.0", "@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/type-utils": "8.28.0", "@typescript-eslint/type-utils": "8.29.0",
"@typescript-eslint/utils": "8.28.0", "@typescript-eslint/utils": "8.29.0",
"@typescript-eslint/visitor-keys": "8.28.0", "@typescript-eslint/visitor-keys": "8.29.0",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^5.3.1", "ignore": "^5.3.1",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
@ -5618,16 +5618,16 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.0.tgz",
"integrity": "sha512-LPcw1yHD3ToaDEoljFEfQ9j2xShY367h7FZ1sq5NJT9I3yj4LHer1Xd1yRSOdYy9BpsrxU7R+eoDokChYM53lQ==", "integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.28.0", "@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/types": "8.28.0", "@typescript-eslint/types": "8.29.0",
"@typescript-eslint/typescript-estree": "8.28.0", "@typescript-eslint/typescript-estree": "8.29.0",
"@typescript-eslint/visitor-keys": "8.28.0", "@typescript-eslint/visitor-keys": "8.29.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -5643,14 +5643,14 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.0.tgz",
"integrity": "sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw==", "integrity": "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.28.0", "@typescript-eslint/types": "8.29.0",
"@typescript-eslint/visitor-keys": "8.28.0" "@typescript-eslint/visitor-keys": "8.29.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5661,14 +5661,14 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.0.tgz",
"integrity": "sha512-oRoXu2v0Rsy/VoOGhtWrOKDiIehvI+YNrDk5Oqj40Mwm0Yt01FC/Q7nFqg088d3yAsR1ZcZFVfPCTTFCe/KPwg==", "integrity": "sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.28.0", "@typescript-eslint/typescript-estree": "8.29.0",
"@typescript-eslint/utils": "8.28.0", "@typescript-eslint/utils": "8.29.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^2.0.1" "ts-api-utils": "^2.0.1"
}, },
@ -5685,9 +5685,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.0.tgz",
"integrity": "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA==", "integrity": "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -5699,14 +5699,14 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.0.tgz",
"integrity": "sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA==", "integrity": "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.28.0", "@typescript-eslint/types": "8.29.0",
"@typescript-eslint/visitor-keys": "8.28.0", "@typescript-eslint/visitor-keys": "8.29.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -5752,16 +5752,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.0.tgz",
"integrity": "sha512-OELa9hbTYciYITqgurT1u/SzpQVtDLmQMFzy/N8pQE+tefOyCWT79jHsav294aTqV1q1u+VzqDGbuujvRYaeSQ==", "integrity": "sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.28.0", "@typescript-eslint/scope-manager": "8.29.0",
"@typescript-eslint/types": "8.28.0", "@typescript-eslint/types": "8.29.0",
"@typescript-eslint/typescript-estree": "8.28.0" "@typescript-eslint/typescript-estree": "8.29.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5776,13 +5776,13 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.28.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.0.tgz",
"integrity": "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg==", "integrity": "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.28.0", "@typescript-eslint/types": "8.29.0",
"eslint-visitor-keys": "^4.2.0" "eslint-visitor-keys": "^4.2.0"
}, },
"engines": { "engines": {
@ -5794,9 +5794,9 @@
} }
}, },
"node_modules/@vitest/coverage-v8": { "node_modules/@vitest/coverage-v8": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.1.tgz",
"integrity": "sha512-15OACZcBtQ34keIEn19JYTVuMFTlFrClclwWjHo/IRPg/8ELpkgNTl0o7WLP9WO9XGH6+tip9CPYtEOrIDJvBA==", "integrity": "sha512-MgV6D2dhpD6Hp/uroUoAIvFqA8AuvXEFBC2eepG3WFc1pxTfdk1LEqqkWoWhjz+rytoqrnUUCdf6Lzco3iHkLQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5809,7 +5809,7 @@
"istanbul-reports": "^3.1.7", "istanbul-reports": "^3.1.7",
"magic-string": "^0.30.17", "magic-string": "^0.30.17",
"magicast": "^0.3.5", "magicast": "^0.3.5",
"std-env": "^3.8.0", "std-env": "^3.8.1",
"test-exclude": "^7.0.1", "test-exclude": "^7.0.1",
"tinyrainbow": "^2.0.0" "tinyrainbow": "^2.0.0"
}, },
@ -5817,8 +5817,8 @@
"url": "https://opencollective.com/vitest" "url": "https://opencollective.com/vitest"
}, },
"peerDependencies": { "peerDependencies": {
"@vitest/browser": "3.0.9", "@vitest/browser": "3.1.1",
"vitest": "3.0.9" "vitest": "3.1.1"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@vitest/browser": { "@vitest/browser": {
@ -5827,14 +5827,14 @@
} }
}, },
"node_modules/@vitest/expect": { "node_modules/@vitest/expect": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.1.tgz",
"integrity": "sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==", "integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/spy": "3.0.9", "@vitest/spy": "3.1.1",
"@vitest/utils": "3.0.9", "@vitest/utils": "3.1.1",
"chai": "^5.2.0", "chai": "^5.2.0",
"tinyrainbow": "^2.0.0" "tinyrainbow": "^2.0.0"
}, },
@ -5843,13 +5843,13 @@
} }
}, },
"node_modules/@vitest/mocker": { "node_modules/@vitest/mocker": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.1.tgz",
"integrity": "sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==", "integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/spy": "3.0.9", "@vitest/spy": "3.1.1",
"estree-walker": "^3.0.3", "estree-walker": "^3.0.3",
"magic-string": "^0.30.17" "magic-string": "^0.30.17"
}, },
@ -5870,9 +5870,9 @@
} }
}, },
"node_modules/@vitest/pretty-format": { "node_modules/@vitest/pretty-format": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz",
"integrity": "sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==", "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5883,13 +5883,13 @@
} }
}, },
"node_modules/@vitest/runner": { "node_modules/@vitest/runner": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.1.tgz",
"integrity": "sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==", "integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/utils": "3.0.9", "@vitest/utils": "3.1.1",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
"funding": { "funding": {
@ -5904,13 +5904,13 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vitest/snapshot": { "node_modules/@vitest/snapshot": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.1.tgz",
"integrity": "sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==", "integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "3.0.9", "@vitest/pretty-format": "3.1.1",
"magic-string": "^0.30.17", "magic-string": "^0.30.17",
"pathe": "^2.0.3" "pathe": "^2.0.3"
}, },
@ -5926,9 +5926,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@vitest/spy": { "node_modules/@vitest/spy": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz",
"integrity": "sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==", "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -5939,13 +5939,13 @@
} }
}, },
"node_modules/@vitest/utils": { "node_modules/@vitest/utils": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.9.tgz", "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz",
"integrity": "sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==", "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/pretty-format": "3.0.9", "@vitest/pretty-format": "3.1.1",
"loupe": "^3.1.3", "loupe": "^3.1.3",
"tinyrainbow": "^2.0.0" "tinyrainbow": "^2.0.0"
}, },
@ -11002,9 +11002,9 @@
} }
}, },
"node_modules/expect-type": { "node_modules/expect-type": {
"version": "1.1.0", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz",
"integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
@ -18275,9 +18275,9 @@
} }
}, },
"node_modules/sass": { "node_modules/sass": {
"version": "1.86.0", "version": "1.86.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.86.0.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.1.tgz",
"integrity": "sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==", "integrity": "sha512-Yaok4XELL1L9Im/ZUClKu//D2OP1rOljKj0Gf34a+GzLbMveOzL7CfqYo+JUa5Xt1nhTCW+OcKp/FtR7/iqj1w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -19038,9 +19038,9 @@
} }
}, },
"node_modules/std-env": { "node_modules/std-env": {
"version": "3.8.0", "version": "3.8.1",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz",
"integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
@ -20380,15 +20380,15 @@
} }
}, },
"node_modules/typescript-eslint": { "node_modules/typescript-eslint": {
"version": "8.28.0", "version": "8.29.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.28.0.tgz", "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.29.0.tgz",
"integrity": "sha512-jfZtxJoHm59bvoCMYCe2BM0/baMswRhMmYhy+w6VfcyHrjxZ0OJe0tGasydCpIpA+A/WIJhTyZfb3EtwNC/kHQ==", "integrity": "sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/eslint-plugin": "8.28.0", "@typescript-eslint/eslint-plugin": "8.29.0",
"@typescript-eslint/parser": "8.28.0", "@typescript-eslint/parser": "8.29.0",
"@typescript-eslint/utils": "8.28.0" "@typescript-eslint/utils": "8.29.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -20884,9 +20884,9 @@
} }
}, },
"node_modules/vite-node": { "node_modules/vite-node": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.9.tgz", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.1.tgz",
"integrity": "sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==", "integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -20929,31 +20929,31 @@
} }
}, },
"node_modules/vitest": { "node_modules/vitest": {
"version": "3.0.9", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.1.tgz",
"integrity": "sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==", "integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vitest/expect": "3.0.9", "@vitest/expect": "3.1.1",
"@vitest/mocker": "3.0.9", "@vitest/mocker": "3.1.1",
"@vitest/pretty-format": "^3.0.9", "@vitest/pretty-format": "^3.1.1",
"@vitest/runner": "3.0.9", "@vitest/runner": "3.1.1",
"@vitest/snapshot": "3.0.9", "@vitest/snapshot": "3.1.1",
"@vitest/spy": "3.0.9", "@vitest/spy": "3.1.1",
"@vitest/utils": "3.0.9", "@vitest/utils": "3.1.1",
"chai": "^5.2.0", "chai": "^5.2.0",
"debug": "^4.4.0", "debug": "^4.4.0",
"expect-type": "^1.1.0", "expect-type": "^1.2.0",
"magic-string": "^0.30.17", "magic-string": "^0.30.17",
"pathe": "^2.0.3", "pathe": "^2.0.3",
"std-env": "^3.8.0", "std-env": "^3.8.1",
"tinybench": "^2.9.0", "tinybench": "^2.9.0",
"tinyexec": "^0.3.2", "tinyexec": "^0.3.2",
"tinypool": "^1.0.2", "tinypool": "^1.0.2",
"tinyrainbow": "^2.0.0", "tinyrainbow": "^2.0.0",
"vite": "^5.0.0 || ^6.0.0", "vite": "^5.0.0 || ^6.0.0",
"vite-node": "3.0.9", "vite-node": "3.1.1",
"why-is-node-running": "^2.3.0" "why-is-node-running": "^2.3.0"
}, },
"bin": { "bin": {
@ -20969,8 +20969,8 @@
"@edge-runtime/vm": "*", "@edge-runtime/vm": "*",
"@types/debug": "^4.1.12", "@types/debug": "^4.1.12",
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
"@vitest/browser": "3.0.9", "@vitest/browser": "3.1.1",
"@vitest/ui": "3.0.9", "@vitest/ui": "3.1.1",
"happy-dom": "*", "happy-dom": "*",
"jsdom": "*" "jsdom": "*"
}, },

View File

@ -214,7 +214,7 @@
"@types/ws": "8.18.0", "@types/ws": "8.18.0",
"@types/xml2js": "0.4.14", "@types/xml2js": "0.4.14",
"@types/yargs": "17.0.33", "@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.0.9", "@vitest/coverage-v8": "3.1.1",
"autoprefixer": "10.4.21", "autoprefixer": "10.4.21",
"bootstrap": "5.3.3", "bootstrap": "5.3.3",
"copy-webpack-plugin": "13.0.0", "copy-webpack-plugin": "13.0.0",
@ -238,7 +238,7 @@
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"rimraf": "6.0.1", "rimraf": "6.0.1",
"sass": "1.86.0", "sass": "1.86.1",
"sass-loader": "16.0.5", "sass-loader": "16.0.5",
"script-loader": "0.7.2", "script-loader": "0.7.2",
"split.js": "1.6.5", "split.js": "1.6.5",
@ -250,9 +250,9 @@
"tsx": "4.19.3", "tsx": "4.19.3",
"typedoc": "0.28.1", "typedoc": "0.28.1",
"typescript": "5.8.2", "typescript": "5.8.2",
"typescript-eslint": "8.28.0", "typescript-eslint": "8.29.0",
"vanilla-js-wheel-zoom": "9.0.4", "vanilla-js-wheel-zoom": "9.0.4",
"vitest": "3.0.9", "vitest": "3.1.1",
"webpack": "5.98.0", "webpack": "5.98.0",
"webpack-cli": "6.0.1", "webpack-cli": "6.0.1",
"webpack-dev-middleware": "7.4.2" "webpack-dev-middleware": "7.4.2"

View File

@ -0,0 +1,22 @@
import { describe, expect, it } from "vitest";
import { getSizeFromSvg } from "./utils.js";
describe("getSizeFromSvg", () => {
it("parses width & height attribute", () => {
const svg = `<svg aria-roledescription="sequence" role="graphics-document document" viewBox="-50 -10 714 574" height="574" xmlns="http://www.w3.org/2000/svg" width="714" id="mermaid-graph-2"></svg>`;
const result = getSizeFromSvg(svg);
expect(result).toMatchObject({
width: 714,
height: 574,
});
});
it("parses viewbox", () => {
const svg = `<svg aria-roledescription="er" role="graphics-document document" viewBox="0 0 872.2750244140625 655" style="max-width: 872.2750244140625px;" class="erDiagram" xmlns="http://www.w3.org/2000/svg" width="100%" id="mermaid-graph-2">`;
const result = getSizeFromSvg(svg);
expect(result).toMatchObject({
width: 872.2750244140625,
height: 655
});
});
});

View File

@ -2,6 +2,8 @@ import dayjs from "dayjs";
import { Modal } from "bootstrap"; import { Modal } from "bootstrap";
import type { ViewScope } from "./link.js"; import type { ViewScope } from "./link.js";
const SVG_MIME = "image/svg+xml";
function reloadFrontendApp(reason?: string) { function reloadFrontendApp(reason?: string) {
if (reason) { if (reason) {
logInfo(`Frontend app reload: ${reason}`); logInfo(`Frontend app reload: ${reason}`);
@ -650,47 +652,80 @@ function triggerDownload(fileName: string, dataUrl: string) {
* *
* @param nameWithoutExtension the name of the file. The .png suffix is automatically added to it. * @param nameWithoutExtension the name of the file. The .png suffix is automatically added to it.
* @param svgContent the content of the SVG file download. * @param svgContent the content of the SVG file download.
* @returns `true` if the operation succeeded (width/height present), or `false` if the download was not triggered. * @returns a promise which resolves if the operation was successful, or rejects if it failed (permissions issue or some other issue).
*/ */
function downloadSvgAsPng(nameWithoutExtension: string, svgContent: string) { function downloadSvgAsPng(nameWithoutExtension: string, svgContent: string) {
const mime = "image/svg+xml"; return new Promise<void>((resolve, reject) => {
// First, we need to determine the width and the height from the input SVG.
const result = getSizeFromSvg(svgContent);
if (!result) {
reject();
return;
}
// First, we need to determine the width and the height from the input SVG. // Convert the image to a blob.
const svgDocument = (new DOMParser()).parseFromString(svgContent, mime); const { width, height } = result;
const width = svgDocument.documentElement?.getAttribute("width");
const height = svgDocument.documentElement?.getAttribute("height");
// Create an image element and load the SVG.
const imageEl = new Image();
imageEl.width = width;
imageEl.height = height;
imageEl.crossOrigin = "anonymous";
imageEl.onload = () => {
try {
// Draw the image with a canvas.
const canvasEl = document.createElement("canvas");
canvasEl.width = imageEl.width;
canvasEl.height = imageEl.height;
document.body.appendChild(canvasEl);
const ctx = canvasEl.getContext("2d");
if (!ctx) {
reject();
}
ctx?.drawImage(imageEl, 0, 0);
const imgUri = canvasEl.toDataURL("image/png")
triggerDownload(`${nameWithoutExtension}.png`, imgUri);
document.body.removeChild(canvasEl);
resolve();
} catch (e) {
console.warn(e);
reject();
}
};
imageEl.onerror = (e) => reject(e);
imageEl.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgContent)}`;
});
}
export function getSizeFromSvg(svgContent: string) {
const svgDocument = (new DOMParser()).parseFromString(svgContent, SVG_MIME);
// Try to use width & height attributes if available.
let width = svgDocument.documentElement?.getAttribute("width");
let height = svgDocument.documentElement?.getAttribute("height");
// If not, use the viewbox.
if (!width || !height) { if (!width || !height) {
return false; const viewBox = svgDocument.documentElement?.getAttribute("viewBox");
if (viewBox) {
const viewBoxParts = viewBox.split(" ");
width = viewBoxParts[2];
height = viewBoxParts[3];
}
} }
// Convert the image to a blob. if (width && height) {
const svgBlob = new Blob([ svgContent ], { return {
type: mime width: parseFloat(width),
}) height: parseFloat(height)
}
// Create an image element and load the SVG. } else {
const imageEl = new Image(); console.warn("SVG export error", svgDocument.documentElement);
imageEl.width = parseFloat(width); return null;
imageEl.height = parseFloat(height); }
imageEl.src = URL.createObjectURL(svgBlob);
imageEl.onload = () => {
// Draw the image with a canvas.
const canvasEl = document.createElement("canvas");
canvasEl.width = imageEl.width;
canvasEl.height = imageEl.height;
document.body.appendChild(canvasEl);
const ctx = canvasEl.getContext("2d");
ctx?.drawImage(imageEl, 0, 0);
URL.revokeObjectURL(imageEl.src);
const imgUri = canvasEl.toDataURL("image/png")
triggerDownload(`${nameWithoutExtension}.png`, imgUri);
document.body.removeChild(canvasEl);
};
return true;
} }
/** /**

View File

@ -2,7 +2,9 @@ import type { EventData } from "../../components/app_context.js";
import type FNote from "../../entities/fnote.js"; import type FNote from "../../entities/fnote.js";
import { t } from "../../services/i18n.js"; import { t } from "../../services/i18n.js";
import server from "../../services/server.js"; import server from "../../services/server.js";
import toast from "../../services/toast.js";
import utils from "../../services/utils.js"; import utils from "../../services/utils.js";
import ws from "../../services/ws.js";
import OnClickButtonWidget from "../buttons/onclick_button.js"; import OnClickButtonWidget from "../buttons/onclick_button.js";
import AbstractSplitTypeWidget from "./abstract_split_type_widget.js"; import AbstractSplitTypeWidget from "./abstract_split_type_widget.js";
@ -218,11 +220,18 @@ export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTy
} }
async exportPngEvent({ ntxId }: EventData<"exportPng">) { async exportPngEvent({ ntxId }: EventData<"exportPng">) {
console.log("Export to PNG", this.noteContext?.noteId, ntxId, this.svg);
if (!this.isNoteContext(ntxId) || this.note?.type !== "mermaid" || !this.svg) { if (!this.isNoteContext(ntxId) || this.note?.type !== "mermaid" || !this.svg) {
console.log("Return");
return; return;
} }
utils.downloadSvgAsPng(this.note.title, this.svg); try {
await utils.downloadSvgAsPng(this.note.title, this.svg);
} catch (e) {
console.warn(e);
toast.showError(t("svg.export_to_png"));
}
} }
} }

View File

@ -595,7 +595,7 @@ body a.tn-link:visited,
box-shadow: 0 0 0 0 var(--background); box-shadow: 0 0 0 0 var(--background);
border-radius: 4px; border-radius: 4px;
background: var(--background); background: var(--background);
color: currentColor; color: var(--link-color);
font-weight: normal; font-weight: normal;
text-decoration: underline; text-decoration: underline;

View File

@ -1754,5 +1754,8 @@
}, },
"png_export_button": { "png_export_button": {
"button_title": "Export diagram as PNG" "button_title": "Export diagram as PNG"
},
"svg": {
"export_to_png": "The diagram could not be exported to PNG."
} }
} }

View File

@ -28,7 +28,7 @@ function checkAuth(req: Request, res: Response, next: NextFunction) {
} else if (currentTotpStatus !== lastAuthState.totpEnabled || currentSsoStatus !== lastAuthState.ssoEnabled) { } else if (currentTotpStatus !== lastAuthState.totpEnabled || currentSsoStatus !== lastAuthState.ssoEnabled) {
req.session.destroy((err) => { req.session.destroy((err) => {
if (err) console.error('Error destroying session:', err); if (err) console.error('Error destroying session:', err);
res.redirect('/login'); res.redirect('login');
}); });
return; return;
} else if (currentSsoStatus) { } else if (currentSsoStatus) {
@ -36,7 +36,7 @@ function checkAuth(req: Request, res: Response, next: NextFunction) {
next(); next();
return; return;
} }
res.redirect('/login'); res.redirect('login');
return; return;
} else if (!req.session.loggedIn && !noAuthentication) { } else if (!req.session.loggedIn && !noAuthentication) {
const redirectToShare = options.getOptionBool("redirectBareDomain"); const redirectToShare = options.getOptionBool("redirectBareDomain");

View File

@ -64,7 +64,7 @@ async function initDbConnection() {
dbReady.resolve(); dbReady.resolve();
} }
async function createInitialDatabase() { async function createInitialDatabase(preserveIds?: boolean) {
if (isDbInitialized()) { if (isDbInitialized()) {
throw new Error("DB is already initialized"); throw new Error("DB is already initialized");
} }
@ -112,7 +112,9 @@ async function createInitialDatabase() {
const dummyTaskContext = new TaskContext("no-progress-reporting", "import", false); const dummyTaskContext = new TaskContext("no-progress-reporting", "import", false);
await zipImportService.importZip(dummyTaskContext, demoFile, rootNote); await zipImportService.importZip(dummyTaskContext, demoFile, rootNote, {
preserveIds
});
sql.transactional(() => { sql.transactional(() => {
// this needs to happen after ZIP import, // this needs to happen after ZIP import,