mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-03 21:19:01 +01:00 
			
		
		
		
	Merge branch 'develop' into calendar
This commit is contained in:
		
						commit
						bbf7bc9324
					
				
							
								
								
									
										8
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@ -2,4 +2,12 @@ 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/**/*.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
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								db/demo.zip
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								db/demo.zip
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2114
									
								
								demo/!!!meta.json
									
									
									
									
									
								
							
							
						
						
									
										2114
									
								
								demo/!!!meta.json
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -18,24 +18,30 @@
 | 
			
		||||
          height="150">
 | 
			
		||||
        </figure>
 | 
			
		||||
        <p><strong>Welcome to TriliumNext Notes!</strong>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <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
 | 
			
		||||
          structure your notes. You can play with it, modify note content and tree
 | 
			
		||||
          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>
 | 
			
		||||
         <h3>Cleanup</h3>
 | 
			
		||||
 | 
			
		||||
        <p>Once you're finished with experimenting and want to cleanup these pages,
 | 
			
		||||
          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"> </section>
 | 
			
		||||
         <h3>Formatting</h3>
 | 
			
		||||
 | 
			
		||||
        <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>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <p>Lists</p>
 | 
			
		||||
        <p><strong>Ordered:</strong>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ol>
 | 
			
		||||
          <li>First Item</li>
 | 
			
		||||
@ -50,6 +56,7 @@
 | 
			
		||||
          </li>
 | 
			
		||||
        </ol>
 | 
			
		||||
        <p><strong>Unordered:</strong>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>Item</li>
 | 
			
		||||
 | 
			
		||||
@ -14,17 +14,22 @@
 | 
			
		||||
 | 
			
		||||
      <div class="ck-content">
 | 
			
		||||
        <h2>Main characters</h2>
 | 
			
		||||
 | 
			
		||||
        <p>… here put main characters …</p>
 | 
			
		||||
        <p> </p>
 | 
			
		||||
         <h2>Plot</h2>
 | 
			
		||||
 | 
			
		||||
        <p>… describe main plot lines …</p>
 | 
			
		||||
        <p> </p>
 | 
			
		||||
         <h2>Tone</h2>
 | 
			
		||||
 | 
			
		||||
        <p> </p>
 | 
			
		||||
         <h2>Genre</h2>
 | 
			
		||||
 | 
			
		||||
        <p>scifi / drama / romance</p>
 | 
			
		||||
        <p> </p>
 | 
			
		||||
         <h2>Similar books</h2>
 | 
			
		||||
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>…</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -14,11 +14,14 @@
 | 
			
		||||
 | 
			
		||||
      <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>
 | 
			
		||||
        <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&pd_rd_i=0765386690&pd_rd_r=AB0J179TM9NTEAMHE240&pd_rd_w=FAhxX&pd_rd_wg=pLGK7&psc=1&refRID=AB0J179TM9NTEAMHE240">The Dark Forest</a>
 | 
			
		||||
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>Ann Leckie - <a href="https://www.amazon.com/Ancillary-Sword-Imperial-Radch-Leckie/dp/0316246654/ref=pd_sim_14_1?_encoding=UTF8&pd_rd_i=0316246654&pd_rd_r=D7KDTGZFP7YM1YSYVY4G&pd_rd_w=jkn28&pd_rd_wg=JVhtw&psc=1&refRID=D7KDTGZFP7YM1YSYVY4G">Ancillary Sword</a>
 | 
			
		||||
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
@ -18,21 +18,25 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">buy milk </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">do the laundry </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">watch TV </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">eat ice cream </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,7 @@
 | 
			
		||||
          scheme for the syntax highlighting is adjustable in settings. </p><pre><code class="language-application-javascript-env-frontend">function helloWorld() {
 | 
			
		||||
	alert("Hello world");
 | 
			
		||||
}</code></pre>
 | 
			
		||||
 | 
			
		||||
        <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,
 | 
			
		||||
          see <a class="reference-link" href="../Scripting%20examples/Custom%20request%20handler.js">Custom request handler</a>.</p>
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,9 @@
 | 
			
		||||
      <div class="ck-content">
 | 
			
		||||
        <p><span class="math-tex">\(% \f is defined as #1f(#2) using the macro \f\relax{x} = \int_{-\infty}^\infty     \f\hat\xi\,e^{2 \pi i \xi x}     \,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>
 | 
			
		||||
 | 
			
		||||
        <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: <span class="math-tex">\(c^2 = a^2 + b^2\)</span> Neat!</p>
 | 
			
		||||
        <p> </p>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
@ -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>.
 | 
			
		||||
            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
 | 
			
		||||
        class="include-note" data-note-id="WdDLhuzYxRlW" data-box-size="medium"> </section>
 | 
			
		||||
        class="include-note" data-note-id="ZWCYra81yOFO" data-box-size="medium"> </section>
 | 
			
		||||
          <p>This page demonstrates two things:</p>
 | 
			
		||||
          <ul>
 | 
			
		||||
            <li>possibility to <a href="https://github.com/zadam/trilium/wiki/Text-editor#include-note">include one note into another</a>
 | 
			
		||||
 | 
			
		||||
            </li>
 | 
			
		||||
            <li>PDF preview - you can read PDFs directly in Trilium!</li>
 | 
			
		||||
          </ul>
 | 
			
		||||
 | 
			
		||||
@ -68,6 +68,7 @@
 | 
			
		||||
                                                                                                                <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>
 | 
			
		||||
                                                                                                                  </div>
 | 
			
		||||
                                                                                                                </div>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@
 | 
			
		||||
          <li>XBox</li>
 | 
			
		||||
          <li>Candles</li>
 | 
			
		||||
          <li><a href="https://www.amazon.ca/Anker-SoundCore-Portable-Bluetooth-Resistance/dp/B01MTB55WH?pd_rd_wg=honW8&pd_rd_r=c9bb7c0f-0051-4da7-991f-4ca711a1b3e3&pd_rd_w=ciUpR&ref_=pd_gw_simh&pf_rd_r=K10XKX0NGPDNTYYP4BS4&pf_rd_p=5f1b460b-78c1-580e-929e-2878fe4859e8">Portable speakers</a>
 | 
			
		||||
 | 
			
		||||
          </li>
 | 
			
		||||
          <li>...?</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,10 @@
 | 
			
		||||
 | 
			
		||||
      <div class="ck-content">
 | 
			
		||||
        <p>Wiki: <a href="https://en.wikipedia.org/wiki/Trusted_timestamping">https://en.wikipedia.org/wiki/Trusted_timestamping</a>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <p>Bozho: <a href="https://techblog.bozho.net/using-trusted-timestamping-java/">https://techblog.bozho.net/using-trusted-timestamping-java/</a>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <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
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,7 @@
 | 
			
		||||
        <p>Miscellaneous notes done on monday ...</p>
 | 
			
		||||
        <p> </p>
 | 
			
		||||
        <p>Interesting video: <a href="https://www.youtube.com/watch?v=_eSAF_qT_FY&feature=youtu.be">https://www.youtube.com/watch?v=_eSAF_qT_FY&feature=youtu.be</a>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <p> </p>
 | 
			
		||||
        <p> </p>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          width="209" height="300">
 | 
			
		||||
        </figure>
 | 
			
		||||
        <p>Maybe CodeNames? <a href="https://boardgamegeek.com/boardgame/178900/codenames">https://boardgamegeek.com/boardgame/178900/codenames</a>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,7 @@
 | 
			
		||||
          <li>
 | 
			
		||||
            <label class="todo-list__label">
 | 
			
		||||
              <input type="checkbox" disabled="disabled"><span class="todo-list__label__description">  </span>
 | 
			
		||||
 | 
			
		||||
            </label>
 | 
			
		||||
          </li>
 | 
			
		||||
        </ul>
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@
 | 
			
		||||
      <div class="ck-content">
 | 
			
		||||
        <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>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <p>Please note that this is meant as scripting example only and feature/bug
 | 
			
		||||
          support is very limited.</p>
 | 
			
		||||
 | 
			
		||||
@ -71,6 +71,7 @@
 | 
			
		||||
                                                                                                                      <img src="Buy a board game for Alice.jpg">
 | 
			
		||||
                                                                                                                    </figure>
 | 
			
		||||
                                                                                                                    <p>Maybe CodeNames? <a href="https://boardgamegeek.com/boardgame/178900/codenames">https://boardgamegeek.com/boardgame/178900/codenames</a>
 | 
			
		||||
 | 
			
		||||
                                                                                                                    </p>
 | 
			
		||||
                                                                                                                  </div>
 | 
			
		||||
                                                                                                                </div>
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
      <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>
 | 
			
		||||
        <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> 
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
              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>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
      <div class="ck-content">
 | 
			
		||||
        <h3>Login shell</h3>
 | 
			
		||||
 | 
			
		||||
        <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
 | 
			
		||||
          (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
 | 
			
		||||
          have (should have) a "login" mode.</p>
 | 
			
		||||
        <p><em><strong>Methods to start Bash as a login shell:</strong></em>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ul>
 | 
			
		||||
          <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>
 | 
			
		||||
        </ul>
 | 
			
		||||
        <p><em><strong>Methods to test for login shell mode:</strong></em>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>the shell option <a href="http://wiki.bash-hackers.org/internals/shell_options#login_shell">login_shell</a> is
 | 
			
		||||
            set</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
        <p><em><strong>Related switches:</strong></em>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>--noprofile disables reading of all profile files</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
         <h3>Interactive shell</h3>
 | 
			
		||||
 | 
			
		||||
        <p>When Bash starts as an interactive non-login shell, it reads and executes
 | 
			
		||||
          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
 | 
			
		||||
@ -51,11 +56,13 @@
 | 
			
		||||
          The classic way to have a system-wide rc file is to source /etc/bashrc
 | 
			
		||||
          from every user's ~/.bashrc.</p>
 | 
			
		||||
        <p><em><strong>Methods to test for interactive-shell mode:</strong></em>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>the special parameter $- contains the letter i (lowercase I)</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
        <p><em><strong>Related switches:</strong></em>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>-i forces the interactive mode</li>
 | 
			
		||||
@ -65,6 +72,7 @@
 | 
			
		||||
            ~/.bashrc)</li>
 | 
			
		||||
        </ul>
 | 
			
		||||
         <h3>SH mode</h3>
 | 
			
		||||
 | 
			
		||||
        <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
 | 
			
		||||
          to the POSIX® standard as well. The profile files read are /etc/profile
 | 
			
		||||
@ -74,6 +82,7 @@
 | 
			
		||||
          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><em><strong>Bash starts in sh compatiblity mode when:</strong></em>
 | 
			
		||||
 | 
			
		||||
        </p>
 | 
			
		||||
        <ul>
 | 
			
		||||
          <li>
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@
 | 
			
		||||
 | 
			
		||||
      <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><pre><code class="language-text-x-sh">#!/bin/bash
 | 
			
		||||
# This script opens 4 terminal windows.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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>,
 | 
			
		||||
                                                                                                                          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>
 | 
			
		||||
 | 
			
		||||
                                                                                                                    </p>
 | 
			
		||||
                                                                                                                  </div>
 | 
			
		||||
                                                                                                                </div>
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ export async function initializeDatabase() {
 | 
			
		||||
 | 
			
		||||
    cls.init(() => {
 | 
			
		||||
        if (!sqlInit.isDbInitialized()) {
 | 
			
		||||
            sqlInit.createInitialDatabase();
 | 
			
		||||
            sqlInit.createInitialDatabase(true);
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										228
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										228
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -1,12 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "trilium",
 | 
			
		||||
  "version": "0.92.5",
 | 
			
		||||
  "version": "0.92.5-beta",
 | 
			
		||||
  "lockfileVersion": 3,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "packages": {
 | 
			
		||||
    "": {
 | 
			
		||||
      "name": "trilium",
 | 
			
		||||
      "version": "0.92.5",
 | 
			
		||||
      "version": "0.92.5-beta",
 | 
			
		||||
      "license": "AGPL-3.0-only",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@braintree/sanitize-url": "7.1.1",
 | 
			
		||||
@ -157,7 +157,7 @@
 | 
			
		||||
        "@types/ws": "8.18.0",
 | 
			
		||||
        "@types/xml2js": "0.4.14",
 | 
			
		||||
        "@types/yargs": "17.0.33",
 | 
			
		||||
        "@vitest/coverage-v8": "3.0.9",
 | 
			
		||||
        "@vitest/coverage-v8": "3.1.1",
 | 
			
		||||
        "autoprefixer": "10.4.21",
 | 
			
		||||
        "bootstrap": "5.3.3",
 | 
			
		||||
        "copy-webpack-plugin": "13.0.0",
 | 
			
		||||
@ -181,7 +181,7 @@
 | 
			
		||||
        "react": "18.3.1",
 | 
			
		||||
        "react-dom": "18.3.1",
 | 
			
		||||
        "rimraf": "6.0.1",
 | 
			
		||||
        "sass": "1.86.0",
 | 
			
		||||
        "sass": "1.86.1",
 | 
			
		||||
        "sass-loader": "16.0.5",
 | 
			
		||||
        "script-loader": "0.7.2",
 | 
			
		||||
        "split.js": "1.6.5",
 | 
			
		||||
@ -193,9 +193,9 @@
 | 
			
		||||
        "tsx": "4.19.3",
 | 
			
		||||
        "typedoc": "0.28.1",
 | 
			
		||||
        "typescript": "5.8.2",
 | 
			
		||||
        "typescript-eslint": "8.28.0",
 | 
			
		||||
        "typescript-eslint": "8.29.0",
 | 
			
		||||
        "vanilla-js-wheel-zoom": "9.0.4",
 | 
			
		||||
        "vitest": "3.0.9",
 | 
			
		||||
        "vitest": "3.1.1",
 | 
			
		||||
        "webpack": "5.98.0",
 | 
			
		||||
        "webpack-cli": "6.0.1",
 | 
			
		||||
        "webpack-dev-middleware": "7.4.2"
 | 
			
		||||
@ -5588,17 +5588,17 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/eslint-plugin": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-lvFK3TCGAHsItNdWZ/1FkvpzCxTHUVuFrdnOGLMa0GGCFIbCgQWVk3CzCGdA7kM3qGVc+dfW9tr0Z/sHnGDFyg==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@eslint-community/regexpp": "^4.10.0",
 | 
			
		||||
        "@typescript-eslint/scope-manager": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/type-utils": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/utils": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/scope-manager": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/type-utils": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/utils": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.29.0",
 | 
			
		||||
        "graphemer": "^1.4.0",
 | 
			
		||||
        "ignore": "^5.3.1",
 | 
			
		||||
        "natural-compare": "^1.4.0",
 | 
			
		||||
@ -5618,16 +5618,16 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/parser": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-LPcw1yHD3ToaDEoljFEfQ9j2xShY367h7FZ1sq5NJT9I3yj4LHer1Xd1yRSOdYy9BpsrxU7R+eoDokChYM53lQ==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@typescript-eslint/scope-manager": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/types": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/typescript-estree": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/scope-manager": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/types": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/typescript-estree": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.29.0",
 | 
			
		||||
        "debug": "^4.3.4"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
@ -5643,14 +5643,14 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/scope-manager": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@typescript-eslint/types": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.28.0"
 | 
			
		||||
        "@typescript-eslint/types": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.29.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
 | 
			
		||||
@ -5661,14 +5661,14 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/type-utils": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-oRoXu2v0Rsy/VoOGhtWrOKDiIehvI+YNrDk5Oqj40Mwm0Yt01FC/Q7nFqg088d3yAsR1ZcZFVfPCTTFCe/KPwg==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@typescript-eslint/typescript-estree": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/utils": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/typescript-estree": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/utils": "8.29.0",
 | 
			
		||||
        "debug": "^4.3.4",
 | 
			
		||||
        "ts-api-utils": "^2.0.1"
 | 
			
		||||
      },
 | 
			
		||||
@ -5685,9 +5685,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/types": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "engines": {
 | 
			
		||||
@ -5699,14 +5699,14 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/typescript-estree": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@typescript-eslint/types": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/types": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/visitor-keys": "8.29.0",
 | 
			
		||||
        "debug": "^4.3.4",
 | 
			
		||||
        "fast-glob": "^3.3.2",
 | 
			
		||||
        "is-glob": "^4.0.3",
 | 
			
		||||
@ -5752,16 +5752,16 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/utils": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-OELa9hbTYciYITqgurT1u/SzpQVtDLmQMFzy/N8pQE+tefOyCWT79jHsav294aTqV1q1u+VzqDGbuujvRYaeSQ==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@eslint-community/eslint-utils": "^4.4.0",
 | 
			
		||||
        "@typescript-eslint/scope-manager": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/types": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/typescript-estree": "8.28.0"
 | 
			
		||||
        "@typescript-eslint/scope-manager": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/types": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/typescript-estree": "8.29.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
 | 
			
		||||
@ -5776,13 +5776,13 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@typescript-eslint/visitor-keys": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@typescript-eslint/types": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/types": "8.29.0",
 | 
			
		||||
        "eslint-visitor-keys": "^4.2.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
@ -5794,9 +5794,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/coverage-v8": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-15OACZcBtQ34keIEn19JYTVuMFTlFrClclwWjHo/IRPg/8ELpkgNTl0o7WLP9WO9XGH6+tip9CPYtEOrIDJvBA==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-MgV6D2dhpD6Hp/uroUoAIvFqA8AuvXEFBC2eepG3WFc1pxTfdk1LEqqkWoWhjz+rytoqrnUUCdf6Lzco3iHkLQ==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
@ -5809,7 +5809,7 @@
 | 
			
		||||
        "istanbul-reports": "^3.1.7",
 | 
			
		||||
        "magic-string": "^0.30.17",
 | 
			
		||||
        "magicast": "^0.3.5",
 | 
			
		||||
        "std-env": "^3.8.0",
 | 
			
		||||
        "std-env": "^3.8.1",
 | 
			
		||||
        "test-exclude": "^7.0.1",
 | 
			
		||||
        "tinyrainbow": "^2.0.0"
 | 
			
		||||
      },
 | 
			
		||||
@ -5817,8 +5817,8 @@
 | 
			
		||||
        "url": "https://opencollective.com/vitest"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "@vitest/browser": "3.0.9",
 | 
			
		||||
        "vitest": "3.0.9"
 | 
			
		||||
        "@vitest/browser": "3.1.1",
 | 
			
		||||
        "vitest": "3.1.1"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependenciesMeta": {
 | 
			
		||||
        "@vitest/browser": {
 | 
			
		||||
@ -5827,14 +5827,14 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/expect": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@vitest/spy": "3.0.9",
 | 
			
		||||
        "@vitest/utils": "3.0.9",
 | 
			
		||||
        "@vitest/spy": "3.1.1",
 | 
			
		||||
        "@vitest/utils": "3.1.1",
 | 
			
		||||
        "chai": "^5.2.0",
 | 
			
		||||
        "tinyrainbow": "^2.0.0"
 | 
			
		||||
      },
 | 
			
		||||
@ -5843,13 +5843,13 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/mocker": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-ryERPIBOnvevAkTq+L1lD+DTFBRcjueL9lOUfXsLfwP92h4e+Heb+PjiqS3/OURWPtywfafK0kj++yDFjWUmrA==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@vitest/spy": "3.0.9",
 | 
			
		||||
        "@vitest/spy": "3.1.1",
 | 
			
		||||
        "estree-walker": "^3.0.3",
 | 
			
		||||
        "magic-string": "^0.30.17"
 | 
			
		||||
      },
 | 
			
		||||
@ -5870,9 +5870,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/pretty-format": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
@ -5883,13 +5883,13 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/runner": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-NX9oUXgF9HPfJSwl8tUZCMP1oGx2+Sf+ru6d05QjzQz4OwWg0psEzwY6VexP2tTHWdOkhKHUIZH+fS6nA7jfOw==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@vitest/utils": "3.0.9",
 | 
			
		||||
        "@vitest/utils": "3.1.1",
 | 
			
		||||
        "pathe": "^2.0.3"
 | 
			
		||||
      },
 | 
			
		||||
      "funding": {
 | 
			
		||||
@ -5904,13 +5904,13 @@
 | 
			
		||||
      "license": "MIT"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/snapshot": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-AiLUiuZ0FuA+/8i19mTYd+re5jqjEc2jZbgJ2up0VY0Ddyyxg/uUtBDpIFAy4uzKaQxOW8gMgBdAJJ2ydhu39A==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@vitest/pretty-format": "3.0.9",
 | 
			
		||||
        "@vitest/pretty-format": "3.1.1",
 | 
			
		||||
        "magic-string": "^0.30.17",
 | 
			
		||||
        "pathe": "^2.0.3"
 | 
			
		||||
      },
 | 
			
		||||
@ -5926,9 +5926,9 @@
 | 
			
		||||
      "license": "MIT"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/spy": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
@ -5939,13 +5939,13 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@vitest/utils": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@vitest/pretty-format": "3.0.9",
 | 
			
		||||
        "@vitest/pretty-format": "3.1.1",
 | 
			
		||||
        "loupe": "^3.1.3",
 | 
			
		||||
        "tinyrainbow": "^2.0.0"
 | 
			
		||||
      },
 | 
			
		||||
@ -11002,9 +11002,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/expect-type": {
 | 
			
		||||
      "version": "1.1.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz",
 | 
			
		||||
      "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==",
 | 
			
		||||
      "version": "1.2.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz",
 | 
			
		||||
      "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "Apache-2.0",
 | 
			
		||||
      "engines": {
 | 
			
		||||
@ -18275,9 +18275,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/sass": {
 | 
			
		||||
      "version": "1.86.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.0.tgz",
 | 
			
		||||
      "integrity": "sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==",
 | 
			
		||||
      "version": "1.86.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.1.tgz",
 | 
			
		||||
      "integrity": "sha512-Yaok4XELL1L9Im/ZUClKu//D2OP1rOljKj0Gf34a+GzLbMveOzL7CfqYo+JUa5Xt1nhTCW+OcKp/FtR7/iqj1w==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
@ -19038,9 +19038,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/std-env": {
 | 
			
		||||
      "version": "3.8.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz",
 | 
			
		||||
      "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==",
 | 
			
		||||
      "version": "3.8.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz",
 | 
			
		||||
      "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT"
 | 
			
		||||
    },
 | 
			
		||||
@ -20380,15 +20380,15 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/typescript-eslint": {
 | 
			
		||||
      "version": "8.28.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-jfZtxJoHm59bvoCMYCe2BM0/baMswRhMmYhy+w6VfcyHrjxZ0OJe0tGasydCpIpA+A/WIJhTyZfb3EtwNC/kHQ==",
 | 
			
		||||
      "version": "8.29.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.29.0.tgz",
 | 
			
		||||
      "integrity": "sha512-ep9rVd9B4kQsZ7ZnWCVxUE/xDLUUUsRzE0poAeNu+4CkFErLfuvPt/qtm2EpnSyfvsR0S6QzDFSrPCFBwf64fg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@typescript-eslint/eslint-plugin": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/parser": "8.28.0",
 | 
			
		||||
        "@typescript-eslint/utils": "8.28.0"
 | 
			
		||||
        "@typescript-eslint/eslint-plugin": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/parser": "8.29.0",
 | 
			
		||||
        "@typescript-eslint/utils": "8.29.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
 | 
			
		||||
@ -20884,9 +20884,9 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/vite-node": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-w3Gdx7jDcuT9cNn9jExXgOyKmf5UOTb6WMHz8LGAm54eS1Elf5OuBhCxl6zJxGhEeIkgsE1WbHuoL0mj/UXqXg==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
@ -20929,31 +20929,31 @@
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/vitest": {
 | 
			
		||||
      "version": "3.0.9",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.9.tgz",
 | 
			
		||||
      "integrity": "sha512-BbcFDqNyBlfSpATmTtXOAOj71RNKDDvjBM/uPfnxxVGrG+FSH2RQIwgeEngTaTkuU/h0ScFvf+tRcKfYXzBybQ==",
 | 
			
		||||
      "version": "3.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.1.tgz",
 | 
			
		||||
      "integrity": "sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@vitest/expect": "3.0.9",
 | 
			
		||||
        "@vitest/mocker": "3.0.9",
 | 
			
		||||
        "@vitest/pretty-format": "^3.0.9",
 | 
			
		||||
        "@vitest/runner": "3.0.9",
 | 
			
		||||
        "@vitest/snapshot": "3.0.9",
 | 
			
		||||
        "@vitest/spy": "3.0.9",
 | 
			
		||||
        "@vitest/utils": "3.0.9",
 | 
			
		||||
        "@vitest/expect": "3.1.1",
 | 
			
		||||
        "@vitest/mocker": "3.1.1",
 | 
			
		||||
        "@vitest/pretty-format": "^3.1.1",
 | 
			
		||||
        "@vitest/runner": "3.1.1",
 | 
			
		||||
        "@vitest/snapshot": "3.1.1",
 | 
			
		||||
        "@vitest/spy": "3.1.1",
 | 
			
		||||
        "@vitest/utils": "3.1.1",
 | 
			
		||||
        "chai": "^5.2.0",
 | 
			
		||||
        "debug": "^4.4.0",
 | 
			
		||||
        "expect-type": "^1.1.0",
 | 
			
		||||
        "expect-type": "^1.2.0",
 | 
			
		||||
        "magic-string": "^0.30.17",
 | 
			
		||||
        "pathe": "^2.0.3",
 | 
			
		||||
        "std-env": "^3.8.0",
 | 
			
		||||
        "std-env": "^3.8.1",
 | 
			
		||||
        "tinybench": "^2.9.0",
 | 
			
		||||
        "tinyexec": "^0.3.2",
 | 
			
		||||
        "tinypool": "^1.0.2",
 | 
			
		||||
        "tinyrainbow": "^2.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"
 | 
			
		||||
      },
 | 
			
		||||
      "bin": {
 | 
			
		||||
@ -20969,8 +20969,8 @@
 | 
			
		||||
        "@edge-runtime/vm": "*",
 | 
			
		||||
        "@types/debug": "^4.1.12",
 | 
			
		||||
        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
 | 
			
		||||
        "@vitest/browser": "3.0.9",
 | 
			
		||||
        "@vitest/ui": "3.0.9",
 | 
			
		||||
        "@vitest/browser": "3.1.1",
 | 
			
		||||
        "@vitest/ui": "3.1.1",
 | 
			
		||||
        "happy-dom": "*",
 | 
			
		||||
        "jsdom": "*"
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
@ -214,7 +214,7 @@
 | 
			
		||||
    "@types/ws": "8.18.0",
 | 
			
		||||
    "@types/xml2js": "0.4.14",
 | 
			
		||||
    "@types/yargs": "17.0.33",
 | 
			
		||||
    "@vitest/coverage-v8": "3.0.9",
 | 
			
		||||
    "@vitest/coverage-v8": "3.1.1",
 | 
			
		||||
    "autoprefixer": "10.4.21",
 | 
			
		||||
    "bootstrap": "5.3.3",
 | 
			
		||||
    "copy-webpack-plugin": "13.0.0",
 | 
			
		||||
@ -238,7 +238,7 @@
 | 
			
		||||
    "react": "18.3.1",
 | 
			
		||||
    "react-dom": "18.3.1",
 | 
			
		||||
    "rimraf": "6.0.1",
 | 
			
		||||
    "sass": "1.86.0",
 | 
			
		||||
    "sass": "1.86.1",
 | 
			
		||||
    "sass-loader": "16.0.5",
 | 
			
		||||
    "script-loader": "0.7.2",
 | 
			
		||||
    "split.js": "1.6.5",
 | 
			
		||||
@ -250,9 +250,9 @@
 | 
			
		||||
    "tsx": "4.19.3",
 | 
			
		||||
    "typedoc": "0.28.1",
 | 
			
		||||
    "typescript": "5.8.2",
 | 
			
		||||
    "typescript-eslint": "8.28.0",
 | 
			
		||||
    "typescript-eslint": "8.29.0",
 | 
			
		||||
    "vanilla-js-wheel-zoom": "9.0.4",
 | 
			
		||||
    "vitest": "3.0.9",
 | 
			
		||||
    "vitest": "3.1.1",
 | 
			
		||||
    "webpack": "5.98.0",
 | 
			
		||||
    "webpack-cli": "6.0.1",
 | 
			
		||||
    "webpack-dev-middleware": "7.4.2"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								src/public/app/services/utils.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/public/app/services/utils.spec.ts
									
									
									
									
									
										Normal 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
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
@ -2,6 +2,8 @@ import dayjs from "dayjs";
 | 
			
		||||
import { Modal } from "bootstrap";
 | 
			
		||||
import type { ViewScope } from "./link.js";
 | 
			
		||||
 | 
			
		||||
const SVG_MIME = "image/svg+xml";
 | 
			
		||||
 | 
			
		||||
function reloadFrontendApp(reason?: string) {
 | 
			
		||||
    if (reason) {
 | 
			
		||||
        logInfo(`Frontend app reload: ${reason}`);
 | 
			
		||||
@ -650,31 +652,27 @@ function triggerDownload(fileName: string, dataUrl: string) {
 | 
			
		||||
 *
 | 
			
		||||
 * @param nameWithoutExtension the name of the file. The .png suffix is automatically added to it.
 | 
			
		||||
 * @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) {
 | 
			
		||||
    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 svgDocument = (new DOMParser()).parseFromString(svgContent, mime);
 | 
			
		||||
    const width = svgDocument.documentElement?.getAttribute("width");
 | 
			
		||||
    const height = svgDocument.documentElement?.getAttribute("height");
 | 
			
		||||
 | 
			
		||||
    if (!width || !height) {
 | 
			
		||||
        return false;
 | 
			
		||||
        const result = getSizeFromSvg(svgContent);
 | 
			
		||||
        if (!result) {
 | 
			
		||||
            reject();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Convert the image to a blob.
 | 
			
		||||
    const svgBlob = new Blob([ svgContent ], {
 | 
			
		||||
        type: mime
 | 
			
		||||
    })
 | 
			
		||||
        const { width, height } = result;
 | 
			
		||||
 | 
			
		||||
        // Create an image element and load the SVG.
 | 
			
		||||
        const imageEl = new Image();
 | 
			
		||||
    imageEl.width = parseFloat(width);
 | 
			
		||||
    imageEl.height = parseFloat(height);
 | 
			
		||||
    imageEl.src = URL.createObjectURL(svgBlob);
 | 
			
		||||
        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;
 | 
			
		||||
@ -682,15 +680,52 @@ function downloadSvgAsPng(nameWithoutExtension: string, svgContent: string) {
 | 
			
		||||
                document.body.appendChild(canvasEl);
 | 
			
		||||
 | 
			
		||||
                const ctx = canvasEl.getContext("2d");
 | 
			
		||||
                if (!ctx) {
 | 
			
		||||
                    reject();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ctx?.drawImage(imageEl, 0, 0);
 | 
			
		||||
        URL.revokeObjectURL(imageEl.src);
 | 
			
		||||
 | 
			
		||||
                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)}`;
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
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) {
 | 
			
		||||
        const viewBox = svgDocument.documentElement?.getAttribute("viewBox");
 | 
			
		||||
        if (viewBox) {
 | 
			
		||||
            const viewBoxParts = viewBox.split(" ");
 | 
			
		||||
            width = viewBoxParts[2];
 | 
			
		||||
            height = viewBoxParts[3];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (width && height) {
 | 
			
		||||
        return {
 | 
			
		||||
            width: parseFloat(width),
 | 
			
		||||
            height: parseFloat(height)
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        console.warn("SVG export error", svgDocument.documentElement);
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,9 @@ import type { EventData } from "../../components/app_context.js";
 | 
			
		||||
import type FNote from "../../entities/fnote.js";
 | 
			
		||||
import { t } from "../../services/i18n.js";
 | 
			
		||||
import server from "../../services/server.js";
 | 
			
		||||
import toast from "../../services/toast.js";
 | 
			
		||||
import utils from "../../services/utils.js";
 | 
			
		||||
import ws from "../../services/ws.js";
 | 
			
		||||
import OnClickButtonWidget from "../buttons/onclick_button.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">) {
 | 
			
		||||
        console.log("Export to PNG", this.noteContext?.noteId, ntxId, this.svg);
 | 
			
		||||
        if (!this.isNoteContext(ntxId) || this.note?.type !== "mermaid" || !this.svg) {
 | 
			
		||||
            console.log("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"));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -595,7 +595,7 @@ body a.tn-link:visited,
 | 
			
		||||
    box-shadow: 0 0 0 0 var(--background);
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    background: var(--background);
 | 
			
		||||
    color: currentColor;
 | 
			
		||||
    color: var(--link-color);
 | 
			
		||||
    font-weight: normal;
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1754,5 +1754,8 @@
 | 
			
		||||
  },
 | 
			
		||||
  "png_export_button": {
 | 
			
		||||
    "button_title": "Export diagram as PNG"
 | 
			
		||||
  },
 | 
			
		||||
  "svg": {
 | 
			
		||||
    "export_to_png": "The diagram could not be exported to PNG."
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ function checkAuth(req: Request, res: Response, next: NextFunction) {
 | 
			
		||||
    } else if (currentTotpStatus !== lastAuthState.totpEnabled || currentSsoStatus !== lastAuthState.ssoEnabled) {
 | 
			
		||||
        req.session.destroy((err) => {
 | 
			
		||||
            if (err) console.error('Error destroying session:', err);
 | 
			
		||||
            res.redirect('/login');
 | 
			
		||||
            res.redirect('login');
 | 
			
		||||
        });
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (currentSsoStatus) {
 | 
			
		||||
@ -36,7 +36,7 @@ function checkAuth(req: Request, res: Response, next: NextFunction) {
 | 
			
		||||
            next();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        res.redirect('/login');
 | 
			
		||||
        res.redirect('login');
 | 
			
		||||
        return;
 | 
			
		||||
    } else if (!req.session.loggedIn && !noAuthentication) {
 | 
			
		||||
        const redirectToShare = options.getOptionBool("redirectBareDomain");
 | 
			
		||||
 | 
			
		||||
@ -64,7 +64,7 @@ async function initDbConnection() {
 | 
			
		||||
    dbReady.resolve();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function createInitialDatabase() {
 | 
			
		||||
async function createInitialDatabase(preserveIds?: boolean) {
 | 
			
		||||
    if (isDbInitialized()) {
 | 
			
		||||
        throw new Error("DB is already initialized");
 | 
			
		||||
    }
 | 
			
		||||
@ -112,7 +112,9 @@ async function createInitialDatabase() {
 | 
			
		||||
 | 
			
		||||
    const dummyTaskContext = new TaskContext("no-progress-reporting", "import", false);
 | 
			
		||||
 | 
			
		||||
    await zipImportService.importZip(dummyTaskContext, demoFile, rootNote);
 | 
			
		||||
    await zipImportService.importZip(dummyTaskContext, demoFile, rootNote, {
 | 
			
		||||
        preserveIds
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    sql.transactional(() => {
 | 
			
		||||
        // this needs to happen after ZIP import,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user