1923 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1923 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						||
<html lang='en'>
 | 
						||
 | 
						||
<head>
 | 
						||
  <meta charset='UTF-8' />
 | 
						||
  <meta name='viewport' content='width=device-width, initial-scale=1' />
 | 
						||
  <title>
 | 
						||
    Webapp-Example: Main.hs – Home
 | 
						||
  </title>
 | 
						||
  
 | 
						||
    
 | 
						||
      <meta property='og:description' content='Wie man das verwendet, siehe [[Webapp-Example]].' />
 | 
						||
      <meta property='og:site_name' content='Home' />
 | 
						||
      <meta property='og:image' content />
 | 
						||
      <meta property='og:type' content='website' />
 | 
						||
      <meta property='og:title' content='Webapp-Example: Main.hs' />
 | 
						||
    
 | 
						||
    
 | 
						||
      <base href='/' />
 | 
						||
      <link href='favicon.svg' rel='icon' />
 | 
						||
    
 | 
						||
    <script>
 | 
						||
  window.MathJax = {
 | 
						||
    startup: {
 | 
						||
      ready: () => {
 | 
						||
        MathJax.startup.defaultReady();
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
</script>
 | 
						||
<script async id='MathJax-script' src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js'></script>
 | 
						||
 | 
						||
<!-- mermaid.js --><script src='https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js'></script>
 | 
						||
<script>
 | 
						||
  mermaid.initialize({startOnLoad:false});
 | 
						||
  mermaid.init(undefined,document.querySelectorAll(".mermaid"));
 | 
						||
</script>
 | 
						||
 | 
						||
<!-- highlight.js -->
 | 
						||
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/hybrid.min.css' />
 | 
						||
<script src='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js'></script>
 | 
						||
<!-- Include languages that Emanote itself uses -->
 | 
						||
<script src='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/haskell.min.js'></script>
 | 
						||
<script src='https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/nix.min.js'></script>
 | 
						||
<script>hljs.highlightAll();</script>
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  <link href='tailwind.css?instanceId=491bb520-566c-4957-b60d-e90510adcf88' rel='stylesheet' type='text/css' />
 | 
						||
 | 
						||
  <style>
 | 
						||
    /* Heist error element */
 | 
						||
    strong.error {
 | 
						||
      color: lightcoral;
 | 
						||
      font-size: 90%;
 | 
						||
      font-family: monospace;
 | 
						||
    }
 | 
						||
 | 
						||
    /* External link icon */
 | 
						||
    a[data-linkicon=""]::after {
 | 
						||
      content: ""
 | 
						||
    }
 | 
						||
 | 
						||
    a[data-linkicon=none]::after {
 | 
						||
      content: ""
 | 
						||
    }
 | 
						||
 | 
						||
    a[data-linkicon="external"]::after {
 | 
						||
      content: url('data:image/svg+xml,\
 | 
						||
      <svg xmlns="http://www.w3.org/2000/svg" height="0.7em" viewBox="0 0 20 20"> \
 | 
						||
        <g style="stroke:gray;stroke-width:1"> \
 | 
						||
          <line x1="5" y1="5" x2="5" y2="14" /> \
 | 
						||
          <line x1="14" y1="9" x2="14" y2="14" /> \
 | 
						||
          <line x1="5" y1="14" x2="14" y2="14" /> \
 | 
						||
          <line x1="5" y1="5" x2="9" y2="5"  /> \
 | 
						||
          <line x1="10" y1="2" x2="17" y2="2"  /> \
 | 
						||
          <line x1="17" y1="2" x2="17" y2="9" /> \
 | 
						||
          <line x1="10" y1="9" x2="17" y2="2" style="stroke-width:1.0" /> \
 | 
						||
        </g> \
 | 
						||
      </svg>');
 | 
						||
    }
 | 
						||
 | 
						||
    a[data-linkicon="external"][href^="mailto:"]::after {
 | 
						||
      content: url('data:image/svg+xml,\
 | 
						||
        <svg \
 | 
						||
          xmlns="http://www.w3.org/2000/svg" \
 | 
						||
          height="0.7em" \
 | 
						||
          fill="none" \
 | 
						||
          viewBox="0 0 24 24" \
 | 
						||
          stroke="gray" \
 | 
						||
          stroke-width="2"> \
 | 
						||
          <path \
 | 
						||
            stroke-linecap="round" \
 | 
						||
            stroke-linejoin="round" \
 | 
						||
            d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /> \
 | 
						||
        </svg>');
 | 
						||
    }
 | 
						||
  </style>
 | 
						||
  <!-- What goes in this file will appear on near the end of <head>--><link rel='preload' href='_emanote-static/fonts/Work_Sans/WorkSans-VariableFont_wght.ttf' as='font' type='font/ttf' crossorigin />
 | 
						||
 | 
						||
<style>
 | 
						||
  @font-face {
 | 
						||
    font-family: 'WorkSans';
 | 
						||
    /* FIXME: This ought to be: ${ema:emanoteStaticLayerUrl}/fonts/Work_Sans/WorkSans-VariableFont_wght.ttf */
 | 
						||
    src: url(_emanote-static/fonts/Work_Sans/WorkSans-VariableFont_wght.ttf) format("truetype");
 | 
						||
    font-display: swap;
 | 
						||
  }
 | 
						||
 | 
						||
  body {
 | 
						||
    font-family: 'WorkSans', sans-serif;
 | 
						||
    font-variation-settings: 'wght' 350;
 | 
						||
  }
 | 
						||
 | 
						||
  a.mavenLinkBold {
 | 
						||
    font-variation-settings: 'wght' 400;
 | 
						||
  }
 | 
						||
 | 
						||
  strong {
 | 
						||
    font-variation-settings: 'wght' 500;
 | 
						||
  }
 | 
						||
 | 
						||
  h1,
 | 
						||
  h2,
 | 
						||
  h3,
 | 
						||
  h4,
 | 
						||
  h5,
 | 
						||
  h6,
 | 
						||
  header,
 | 
						||
  .header-font {
 | 
						||
    font-family: 'WorkSans', sans-serif;
 | 
						||
  }
 | 
						||
 | 
						||
  h1 {
 | 
						||
    font-variation-settings: 'wght' 500;
 | 
						||
  }
 | 
						||
 | 
						||
  h2 {
 | 
						||
    font-variation-settings: 'wght' 400;
 | 
						||
  }
 | 
						||
 | 
						||
  h3 {
 | 
						||
    font-variation-settings: 'wght' 300;
 | 
						||
  }
 | 
						||
</style>
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
    <link rel='stylesheet' href='_emanote-static/inverted-tree.css' />
 | 
						||
  
 | 
						||
  <link rel='stylesheet' href='_emanote-static/stork/flat.css' />
 | 
						||
<!-- Custom Stork-search styling for Emanote -->
 | 
						||
<style>
 | 
						||
  #stork-search-container {
 | 
						||
    z-index: 1000;
 | 
						||
    background-color: rgb(15 23 42/.8);
 | 
						||
  }
 | 
						||
 | 
						||
  .stork-overflow-hidden-important {
 | 
						||
    overflow: hidden !important;
 | 
						||
  }
 | 
						||
</style>
 | 
						||
 | 
						||
 | 
						||
<script src='_emanote-static/stork/stork.js'></script>
 | 
						||
 | 
						||
  
 | 
						||
    <script id='emanote-stork' data-emanote-base-url='/'>
 | 
						||
      window.emanote = {};
 | 
						||
      window.emanote.stork = {
 | 
						||
        searchShown: false,
 | 
						||
        indexIsStale: false,
 | 
						||
        toggleSearch: function () {
 | 
						||
          window.emanote.stork.refreshIndex();
 | 
						||
          document.getElementById('stork-search-container').classList.toggle('hidden');
 | 
						||
          window.emanote.stork.searchShown = document.body.classList.toggle('stork-overflow-hidden-important');
 | 
						||
          if (window.emanote.stork.searchShown) {
 | 
						||
            document.getElementById('stork-search-input').focus();
 | 
						||
          }
 | 
						||
        },
 | 
						||
        clearSearch: function () {
 | 
						||
          document.getElementById('stork-search-container').classList.add('hidden');
 | 
						||
          document.body.classList.remove('stork-overflow-hidden-important');
 | 
						||
          window.emanote.stork.searchShown = false;
 | 
						||
        },
 | 
						||
 | 
						||
        getBaseUrl: function () {
 | 
						||
          const baseUrl = document.getElementById("emanote-stork").getAttribute('data-emanote-base-url') || '/';
 | 
						||
          return baseUrl;
 | 
						||
        },
 | 
						||
 | 
						||
        registerIndex: function (options) {
 | 
						||
          const indexName = 'emanote-search'; // used to match input[data-stork] attribute value
 | 
						||
          const indexUrl = window.emanote.stork.getBaseUrl() + '-/stork.st';
 | 
						||
          stork.register(
 | 
						||
            indexName,
 | 
						||
            indexUrl,
 | 
						||
            options);
 | 
						||
        },
 | 
						||
 | 
						||
        init: function () {
 | 
						||
          if (document.readyState !== 'complete') {
 | 
						||
            window.addEventListener('load', function () {
 | 
						||
              stork.initialize(window.emanote.stork.getBaseUrl() + '_emanote-static/stork/stork.wasm');
 | 
						||
              window.emanote.stork.registerIndex();
 | 
						||
            });
 | 
						||
 | 
						||
            document.addEventListener('keydown', event => {
 | 
						||
              if (window.emanote.stork.searchShown && event.key === 'Escape') {
 | 
						||
                window.emanote.stork.clearSearch();
 | 
						||
                event.preventDefault();
 | 
						||
              } else if ((event.key == 'k' || event.key == 'K') && (event.ctrlKey || event.metaKey)) {
 | 
						||
                window.emanote.stork.toggleSearch();
 | 
						||
                event.preventDefault();
 | 
						||
              }
 | 
						||
            });
 | 
						||
          } else {
 | 
						||
            // This section is called during Ema's hot reload.
 | 
						||
            // 
 | 
						||
            // Mark the current index as stale, and refresh it *only when* the
 | 
						||
            // user actually invokes search.
 | 
						||
            // 
 | 
						||
            // We do not refresh the index *right away*, as that will cause
 | 
						||
            // memory leaks in the browser. See
 | 
						||
            // https://github.com/srid/emanote/issues/411#issuecomment-1402056235
 | 
						||
            console.log("stork: Marking index as stale");
 | 
						||
            window.emanote.stork.markIndexAsStale();
 | 
						||
          }
 | 
						||
        },
 | 
						||
 | 
						||
        markIndexAsStale: function () {
 | 
						||
          window.emanote.stork.indexIsStale = true;
 | 
						||
        },
 | 
						||
 | 
						||
        refreshIndex: function () {
 | 
						||
          if (window.emanote.stork.indexIsStale) {
 | 
						||
            console.log("stork: Reloading index");
 | 
						||
            window.emanote.stork.indexIsStale = false;
 | 
						||
            // NOTE: This will leak memory. See the comment above.
 | 
						||
            window.emanote.stork.registerIndex({ forceOverwrite: true });
 | 
						||
          }
 | 
						||
        }
 | 
						||
 | 
						||
      };
 | 
						||
 | 
						||
      window.emanote.stork.init();
 | 
						||
    </script>
 | 
						||
  
 | 
						||
 | 
						||
</head>
 | 
						||
 | 
						||
<!-- DoNotFormat -->
 | 
						||
 | 
						||
 | 
						||
 | 
						||
<!-- DoNotFormat -->
 | 
						||
 | 
						||
<body class='bg-gray-400 overflow-y-scroll'>
 | 
						||
  
 | 
						||
    <div class='container mx-auto'>
 | 
						||
 | 
						||
      <nav id='breadcrumbs' class='w-full text-gray-700 md:hidden'>
 | 
						||
  <div class='flex justify-left'>
 | 
						||
    <div class='w-full px-2 py-2 bg-gray-50'>
 | 
						||
      <ul class='flex flex-wrap text-lg'>
 | 
						||
        <li class='inline-flex items-center'>
 | 
						||
          
 | 
						||
            
 | 
						||
              <img style='width: 1rem;' src='favicon.svg' />
 | 
						||
            
 | 
						||
          
 | 
						||
        </li>
 | 
						||
        
 | 
						||
          
 | 
						||
            <li class='inline-flex items-center'>
 | 
						||
              <a class='px-1 font-bold' href=''>
 | 
						||
                Home
 | 
						||
              </a>
 | 
						||
              <svg fill='currentColor' viewBox='0 0 20 20' class='w-auto h-5 text-gray-400'>
 | 
						||
                <path fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd'></path>
 | 
						||
              </svg>
 | 
						||
            </li>
 | 
						||
          
 | 
						||
            <li class='inline-flex items-center'>
 | 
						||
              <a class='px-1 font-bold' href='Coding'>
 | 
						||
                Coding
 | 
						||
              </a>
 | 
						||
              <svg fill='currentColor' viewBox='0 0 20 20' class='w-auto h-5 text-gray-400'>
 | 
						||
                <path fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd'></path>
 | 
						||
              </svg>
 | 
						||
            </li>
 | 
						||
          
 | 
						||
            <li class='inline-flex items-center'>
 | 
						||
              <a class='px-1 font-bold' href='Coding/Haskell'>
 | 
						||
                Haskell
 | 
						||
              </a>
 | 
						||
              <svg fill='currentColor' viewBox='0 0 20 20' class='w-auto h-5 text-gray-400'>
 | 
						||
                <path fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd'></path>
 | 
						||
              </svg>
 | 
						||
            </li>
 | 
						||
          
 | 
						||
            <li class='inline-flex items-center'>
 | 
						||
              <a class='px-1 font-bold' href='Coding/Haskell/Webapp-Example'>
 | 
						||
                Webapp-Development in Haskell
 | 
						||
              </a>
 | 
						||
              <svg fill='currentColor' viewBox='0 0 20 20' class='w-auto h-5 text-gray-400'>
 | 
						||
                <path fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd'></path>
 | 
						||
              </svg>
 | 
						||
            </li>
 | 
						||
          
 | 
						||
        
 | 
						||
      </ul>
 | 
						||
    </div>
 | 
						||
    <button class='inline px-2 py-1 bg-gray-50 outline-none cursor-pointer focus:outline-none' title='Search (Ctrl+K)' type='button' onclick='window.emanote.stork.toggleSearch()'>
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' style='width: 1rem;' class='hover:text-purple-700' f
 | 
						||
 fill='none' viewBox='0 0 24 24' stroke='currentColor' stroke-width='2'>
 | 
						||
  <path stroke-linecap='round' stroke-linejoin='round' d='M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z'></path>
 | 
						||
</svg>
 | 
						||
    </button>
 | 
						||
    <button class='inline px-2 py-1 text-white bg-purple-600 outline-none cursor-pointer focus:outline-none' title='Toggle sidebar' type='button' onclick="toggleHidden('sidebar')">
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4' fill='none' viewBox='0 0 24 24' stroke='currentColor'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 6h16M4 12h16M4 18h16'></path>
 | 
						||
      </svg>
 | 
						||
    </button>
 | 
						||
    <script>
 | 
						||
      function toggleHidden(elemId) {
 | 
						||
        document.getElementById(elemId).classList.toggle("hidden");
 | 
						||
      }
 | 
						||
    </script>
 | 
						||
  </div>
 | 
						||
</nav>
 | 
						||
 | 
						||
      <div id='container' class='flex flex-nowrap flex-col md:flex-row bg-gray-50 md:mt-8 md:shadow-2xl md:mb-8'>
 | 
						||
        <!-- Sidebar column -->
 | 
						||
        <nav id='sidebar' class='flex-shrink hidden leading-relaxed md:block md:sticky md:top-0 md:h-full md:w-48 xl:w-64'>
 | 
						||
          <div class='px-2 py-2 text-gray-800'>
 | 
						||
            <div id='indexing-links' class='flex flex-row float-right p-2 space-x-2 text-gray-500'>
 | 
						||
              <a href='-/tags' title='View tags'>
 | 
						||
                <svg style='width: 1rem;' class='hover:text-purple-700' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
                  <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z'>
 | 
						||
                  </path>
 | 
						||
                </svg>
 | 
						||
              </a>
 | 
						||
              <a href='-/all' title='Expand full tree'>
 | 
						||
                <svg style='width: 1rem;' class='hover:text-purple-700' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
                  <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4'>
 | 
						||
                  </path>
 | 
						||
                </svg>
 | 
						||
              </a>
 | 
						||
              <a title='Search (Ctrl+K)' class='cursor-pointer' onclick='window.emanote.stork.toggleSearch()'>
 | 
						||
                <svg xmlns='http://www.w3.org/2000/svg' style='width: 1rem;' class='hover:text-purple-700' f
 | 
						||
 fill='none' viewBox='0 0 24 24' stroke='currentColor' stroke-width='2'>
 | 
						||
  <path stroke-linecap='round' stroke-linejoin='round' d='M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z'></path>
 | 
						||
</svg>
 | 
						||
              </a>
 | 
						||
            </div>
 | 
						||
 | 
						||
            <div id='site-logo' class='pl-2'>
 | 
						||
              <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
                <a href='' title='Go to Home'>
 | 
						||
                  
 | 
						||
                    
 | 
						||
                      <!-- The style width attribute here is to prevent huge
 | 
						||
                      icon from displaying at those rare occasions when Tailwind
 | 
						||
                      hasn't kicked in immediately on page load 
 | 
						||
                      -->
 | 
						||
                      <img style='width: 1rem;' class='transition transform hover:scale-110 hover:opacity-80' src='favicon.svg' />
 | 
						||
                    
 | 
						||
                  
 | 
						||
                </a>
 | 
						||
                <a class='font-bold truncate' title='Go to Home' href=''>
 | 
						||
                  Home
 | 
						||
                </a>
 | 
						||
              </div>
 | 
						||
            </div>
 | 
						||
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='About me - Drezil' href='About'>
 | 
						||
      About me - Drezil
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Curriculum Vitae' href='About/CV'>
 | 
						||
      Curriculum Vitae
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Highlights of my experiences in the programming world' href='About/Experience'>
 | 
						||
      Highlights of my experiences in the programming world
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Work-Experience' href='About/Work'>
 | 
						||
      Work-Experience
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Android' href='Android'>
 | 
						||
      Android
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Einrichtung Android-Smartphones' href='Android/Einrichtung'>
 | 
						||
      Einrichtung Android-Smartphones
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Coding' href='Coding'>
 | 
						||
      Coding
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Haskell' href='Coding/Haskell'>
 | 
						||
      Haskell
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Talks und Posts zu Haskell' href='Coding/Haskell/Advantages'>
 | 
						||
      Talks und Posts zu Haskell
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
        
 | 
						||
    
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-500' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path d='M2 6a2 2 0 012-2h5l2 2h5a2 2 0 012 2v6a2 2 0 01-2 2H4a2 2 0 01-2-2V6z'></path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Code-Snippets' href='Coding/Haskell/Code%20Snippets'>
 | 
						||
      Code-Snippets
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
        <span class='text-gray-300' title='2 children inside'>
 | 
						||
          2
 | 
						||
        </span>
 | 
						||
      
 | 
						||
    
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Fortgeschrittene funktionale Programmierung in Haskell' href='Coding/Haskell/FFPiH'>
 | 
						||
      Fortgeschrittene funktionale Programmierung in Haskell
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
        
 | 
						||
    
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Lenses' href='Coding/Haskell/Lenses'>
 | 
						||
      Lenses
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
        
 | 
						||
    
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Webapp-Development in Haskell' href='Coding/Haskell/Webapp-Example'>
 | 
						||
      Webapp-Development in Haskell
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold text-purple-600 hover:underline truncate' title='Webapp-Example: Main.hs' href='Coding/Haskell/Webapp-Example/Main.hs'>
 | 
						||
      Webapp-Example: Main.hs
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Webapp-Example: MyService/Types.hs' href='Coding/Haskell/Webapp-Example/MyService_Types.hs'>
 | 
						||
      Webapp-Example: MyService/Types.hs
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
        
 | 
						||
    
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Openapi-generator' href='Coding/OpenAPI'>
 | 
						||
      Openapi-generator
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Health' href='Health'>
 | 
						||
      Health
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Mental Health' href='Health/Issues'>
 | 
						||
      Mental Health
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Logik für Dummies' href='Logik'>
 | 
						||
      Logik für Dummies
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Opinions' href='Opinions'>
 | 
						||
      Opinions
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Editors' href='Opinions/Editors'>
 | 
						||
      Editors
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Keyboard-Layouts' href='Opinions/Layout'>
 | 
						||
      Keyboard-Layouts
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Stuff' href='Stuff'>
 | 
						||
      Stuff
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Die Bielefeld-Verschwörung' href='Stuff/Bielefeldverschwoerung'>
 | 
						||
      Die Bielefeld-Verschwörung
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Todo' href='TODO'>
 | 
						||
      Todo
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Uni' href='Uni'>
 | 
						||
      Uni
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Studium generale / University-Life' href='Uni/Extracurricular'>
 | 
						||
      Studium generale / University-Life
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='Wie lerne ich richtig an der Uni?' href='Uni/Lernerfolg_an_der_Uni'>
 | 
						||
      Wie lerne ich richtig an der Uni?
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
              <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
      
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
  
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-4 h-4 flex-shrink-0 inline text-gray-700' viewBox='0 0 20 20' fill='currentColor'>
 | 
						||
        <path fill-rule='evenodd' d='M2 6a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1H8a3 3 0 00-3 3v1.5a1.5 1.5 0 01-3 0V6z' clip-rule='evenodd'></path>
 | 
						||
        <path d='M6 12a2 2 0 012-2h8a2 2 0 012 2v2a2 2 0 01-2 2H2h2a2 2 0 002-2v-2z'></path>
 | 
						||
      </svg>
 | 
						||
      
 | 
						||
  
 | 
						||
    <a class='font-bold hover:underline truncate' title='Unix' href='Unix'>
 | 
						||
      Unix
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
      <!-- Variable bindings for this tree-->
 | 
						||
  
 | 
						||
    
 | 
						||
      
 | 
						||
    
 | 
						||
    
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  
 | 
						||
 | 
						||
 | 
						||
<!-- Rendering of this tree -->
 | 
						||
<div class='pl-2'>
 | 
						||
  <!-- Node's rootLabel-->
 | 
						||
  <div class='flex items-center my-2 space-x-2 justify-left'>
 | 
						||
    
 | 
						||
    
 | 
						||
      <svg class='w-4 h-4 flex-shrink-0 inline' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    
 | 
						||
  
 | 
						||
    <a class='hover:underline truncate' title='SSH-Filter' href='Unix/SSH-Filter'>
 | 
						||
      SSH-Filter
 | 
						||
    </a>
 | 
						||
    
 | 
						||
      
 | 
						||
  </div>
 | 
						||
 | 
						||
  <!-- Node's children forest, displayed only on active trees
 | 
						||
    TODO: Use <details> to toggle visibility?
 | 
						||
  -->
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
    
 | 
						||
  
 | 
						||
</div>
 | 
						||
            
 | 
						||
 | 
						||
          </div>
 | 
						||
        </nav>
 | 
						||
 | 
						||
        <!-- Main body column -->
 | 
						||
        <div class='flex-1 w-full overflow-x-auto bg-white'>
 | 
						||
          <main class='px-4 py-4'>
 | 
						||
            <!-- DoNotFormat -->
 | 
						||
<!-- DoNotFormat -->
 | 
						||
 | 
						||
<nav id='uptree' class='flipped tree' style='transform-origin: 50%;'>
 | 
						||
  <ul class='root'>
 | 
						||
    <li>
 | 
						||
      
 | 
						||
        <ul>
 | 
						||
          
 | 
						||
            <li>
 | 
						||
 | 
						||
  <div class='text-gray-900 forest-link'>
 | 
						||
    <a href='Coding/Haskell/Webapp-Example'>
 | 
						||
      Webapp-Development in Haskell
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
 | 
						||
  
 | 
						||
    <ul>
 | 
						||
      
 | 
						||
        <li>
 | 
						||
 | 
						||
  <div class='text-gray-900 forest-link'>
 | 
						||
    <a href='Coding/OpenAPI'>
 | 
						||
      Openapi-generator
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
 | 
						||
  
 | 
						||
    <ul>
 | 
						||
      
 | 
						||
        <li>
 | 
						||
 | 
						||
  <div class='text-gray-900 forest-link'>
 | 
						||
    <a href='Coding'>
 | 
						||
      Coding
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
 | 
						||
  
 | 
						||
    <ul>
 | 
						||
      
 | 
						||
        <li>
 | 
						||
 | 
						||
  <div class='text-gray-900 forest-link'>
 | 
						||
    <a href=''>
 | 
						||
      Home
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
 | 
						||
  
 | 
						||
</li>
 | 
						||
      
 | 
						||
    </ul>
 | 
						||
  
 | 
						||
</li>
 | 
						||
      
 | 
						||
    </ul>
 | 
						||
  
 | 
						||
</li>
 | 
						||
      
 | 
						||
        <li>
 | 
						||
 | 
						||
  <div class='text-gray-900 forest-link'>
 | 
						||
    <a href='Coding/Haskell'>
 | 
						||
      Haskell
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
 | 
						||
  
 | 
						||
</li>
 | 
						||
      
 | 
						||
    </ul>
 | 
						||
  
 | 
						||
</li>
 | 
						||
          
 | 
						||
        </ul>
 | 
						||
      
 | 
						||
    </li>
 | 
						||
  </ul>
 | 
						||
</nav>
 | 
						||
            <h1 class='flex items-end justify-center mb-4 p-3 bg-purple-100 text-5xl font-extrabold text-black rounded'>
 | 
						||
  <a class='z-40 tracking-tighter '>
 | 
						||
    Webapp-Example: Main.hs
 | 
						||
  </a>
 | 
						||
</h1>
 | 
						||
            <article class='overflow-auto'>
 | 
						||
  <!-- What goes in this file will appear on top of note body-->
 | 
						||
  
 | 
						||
    <p class='mb-3'>
 | 
						||
      Wie man das verwendet, siehe <a href='Coding/Haskell/Webapp-Example' class='text-purple-600 mavenLinkBold hover:underline' data-wikilink-type='WikiLinkTag'>Webapp-Development in Haskell</a>.
 | 
						||
    </p>
 | 
						||
  <div class='py-0.5 mb-3 text-sm'><pre><code class='haskell language-haskell'>{-# OPTIONS_GHC -Wno-name-shadowing #-}
 | 
						||
{-# LANGUAGE FlexibleContexts    #-}
 | 
						||
{-# LANGUAGE LambdaCase          #-}
 | 
						||
{-# LANGUAGE OverloadedStrings   #-}
 | 
						||
{-# LANGUAGE RankNTypes          #-}
 | 
						||
{-# LANGUAGE RecordWildCards     #-}
 | 
						||
{-# LANGUAGE ScopedTypeVariables #-}
 | 
						||
module MyService where
 | 
						||
 
 | 
						||
-- generische imports aus den dependencies/base, nicht in der prelude
 | 
						||
import           Codec.MIME.Type
 | 
						||
import           Configuration.Dotenv                 as Dotenv
 | 
						||
import           Control.Concurrent                   (forkIO, threadDelay)
 | 
						||
import           Control.Concurrent.Async
 | 
						||
import           Control.Concurrent.STM
 | 
						||
import           Control.Monad
 | 
						||
import           Control.Monad.Catch
 | 
						||
import           Control.Monad.Except
 | 
						||
import           Conversion
 | 
						||
import           Conversion.Text                      ()
 | 
						||
import           Data.Binary.Builder
 | 
						||
import           Data.String                          (IsString (..))
 | 
						||
import           Data.Time
 | 
						||
import           Data.Time.Clock
 | 
						||
import           Data.Time.Format
 | 
						||
import           Data.Default
 | 
						||
import           Network.HostName
 | 
						||
import           Network.HTTP.Client                  as HTTP hiding
 | 
						||
                                                               (withConnection)
 | 
						||
import           Network.HTTP.Types                   (Status, statusCode)
 | 
						||
import           Network.Mom.Stompl.Client.Queue
 | 
						||
import           Network.Wai                          (Middleware)
 | 
						||
import           Network.Wai.Logger
 | 
						||
import           Network.Wai.Middleware.Cors
 | 
						||
import           Network.Wai.Middleware.RequestLogger (OutputFormat (..),
 | 
						||
                                                       logStdout,
 | 
						||
                                                       mkRequestLogger,
 | 
						||
                                                       outputFormat)
 | 
						||
import           Servant.Client                       (mkClientEnv,
 | 
						||
                                                       parseBaseUrl)
 | 
						||
import           System.Directory
 | 
						||
import           System.Envy
 | 
						||
import           System.IO
 | 
						||
import           System.Log.FastLogger
 | 
						||
import           Text.PrettyPrint.GenericPretty
 | 
						||
 
 | 
						||
-- generische imports, aber qualified, weil es sonst zu name-clashes kommt
 | 
						||
 
 | 
						||
import qualified Data.ByteString                      as BS
 | 
						||
-- import qualified Data.ByteString.Char8 as BS8
 | 
						||
import qualified Data.ByteString.Lazy                 as LBS
 | 
						||
import qualified Network.HTTP.Client.TLS              as UseDefaultHTTPSSettings (tlsManagerSettings)
 | 
						||
import qualified Network.Mom.Stompl.Client.Queue      as AMQ
 | 
						||
import qualified Network.Wai                          as WAI
 | 
						||
 
 | 
						||
-- Handler für den MyServiceBackend-Typen und Imports aus den Libraries
 | 
						||
import           MyService.Handler                    as H  -- handler der H.myApiEndpointV1Post implementiert
 | 
						||
import           MyService.Types                            -- weitere Type (s. nächste box)
 | 
						||
import           MyServiceGen.API                     as MS -- aus der generierten library
 | 
						||
 | 
						||
 
 | 
						||
myServicemain :: IO ()
 | 
						||
myServicemain = do
 | 
						||
  -- .env-Datei ins Prozess-Environment laden, falls noch nicht von außen gesetzt
 | 
						||
  void $ loadFile $ Dotenv.Config [".env"] [] False
 | 
						||
  -- Config holen (defaults + overrides aus dem Environment)
 | 
						||
  sc@ServerConfig{..} <- decodeWithDefaults defConfig
 | 
						||
  -- Backend-Setup
 | 
						||
  -- legt sowas wie Proxy-Server fest und wo man wie dran kommt. Benötigt für das Sprechen mit anderen Microservices
 | 
						||
  let defaultHTTPSSettings = UseDefaultHTTPSSettings.tlsManagerSettings { managerResponseTimeout = responseTimeoutMicro $ 1000 * 1000 * myserviceMaxTimeout }
 | 
						||
      createBackend url proxy = do
 | 
						||
        manager <- newManager . managerSetProxy proxy
 | 
						||
          $ defaultHTTPSSettings
 | 
						||
        url' <- parseBaseUrl url
 | 
						||
        return (mkClientEnv manager url')
 | 
						||
      internalProxy = case myserviceInternalProxyUrl of
 | 
						||
                        ""  -> noProxy
 | 
						||
                        url -> useProxy $ HTTP.Proxy (fromString url) myserviceInternalProxyPort
 | 
						||
      -- externalProxy = case myserviceExternalProxyUrl of
 | 
						||
      --                   ""  -> noProxy
 | 
						||
      --                   url -> useProxy $ HTTP.Proxy (fromString url) myserviceExternalProxyPort
 | 
						||
 
 | 
						||
  -- Definieren & Erzeugen der Funktionen um die anderen Services anzusprechen.
 | 
						||
  calls <- (,)
 | 
						||
           <$> createBackend myserviceAUri internalProxy  
 | 
						||
           <*> createBackend myserviceBUri internalProxy 
 | 
						||
 
 | 
						||
  -- Logging-Setup
 | 
						||
  hSetBuffering stdout LineBuffering
 | 
						||
  hSetBuffering stderr LineBuffering
 | 
						||
 
 | 
						||
 
 | 
						||
  -- Infos holen, brauchen wir später
 | 
						||
  myName <- getHostName
 | 
						||
  today <- formatTime defaultTimeLocale "%F" . utctDay <$> getCurrentTime
 | 
						||
 
 | 
						||
 
 | 
						||
  -- activeMQ-Transaktional-Queue zum schreiben nachher vorbereiten
 | 
						||
  amqPost <- newTQueueIO
 | 
						||
 
 | 
						||
 
 | 
						||
  -- bracket a b c == erst a machen, ergebnis an c als variablen übergeben. Schmeisst c ne exception/wird gekillt/..., werden die variablen an b übergeben.
 | 
						||
  bracket
 | 
						||
   -- logfiles öffnen
 | 
						||
   (LogFiles <$> openFile ("/logs/myservice-"<>myName<>"-"<>today<>".info") AppendMode
 | 
						||
             <*> openFile (if myserviceDebug then "/logs/myservice-"<>myName<>"-"<>today<>".debug" else "/dev/null") AppendMode
 | 
						||
             <*> openFile ("/logs/myservice-"<>myName<>"-"<>today<>".error") AppendMode
 | 
						||
             <*> openFile ("/logs/myservice-"<>myName<>"-"<>today<>".timings") AppendMode
 | 
						||
   )
 | 
						||
   -- und bei exception/beendigung schlißen.h
 | 
						||
   (\(LogFiles a b c d) -> mapM_ hClose [a,b,c,d])
 | 
						||
   $ \logfiles -> do
 | 
						||
 
 | 
						||
 
 | 
						||
    -- logschreibe-funktionen aliasen; log ist hier abstrakt, iolog spezialisiert auf io.
 | 
						||
    let log = printLogFiles logfiles :: MonadIO m => [LogItem] -> m ()
 | 
						||
        iolog = printLogFilesIO logfiles :: [LogItem] -> IO ()
 | 
						||
 
 | 
						||
 
 | 
						||
        -- H.myApiEndpointV1Post ist ein Handler (alle Handler werden mit alias H importiert) und in einer eigenen Datei
 | 
						||
        -- Per Default bekommen Handler sowas wie die server-config, die Funktionen um mit anderen Services zu reden, die AMQ-Queue um ins Kibana zu loggen und eine Datei-Logging-Funktion
 | 
						||
        -- Man kann aber noch viel mehr machen - z.b. gecachte Daten übergeben, eine Talk-Instanz, etc. pp.
 | 
						||
        server = MyServiceBackend{ myApiEndpointV1Post = H.myApiEndpointV1Post sc calls amqPost log
 | 
						||
                                   }
 | 
						||
        config = MS.Config $ "http://" ++ myserviceHost ++ ":" ++ show myservicePort ++ "/"
 | 
						||
    iolog . pure . Info $ "Using Server configuration:"
 | 
						||
    iolog . pure . Info $ pretty sc { myserviceActivemqPassword = "******" -- Do NOT log the password ;)
 | 
						||
                                    , myserviceMongoPassword = "******"
 | 
						||
                                    }
 | 
						||
    -- alle Services starten (Hintergrund-Aktionen wie z.b. einen MongoDB-Dumper, einen Talk-Server oder wie hier die ActiveMQ
 | 
						||
    void $ forkIO $ keepActiveMQConnected sc iolog amqPost
 | 
						||
    -- logging-Framework erzeugen
 | 
						||
    loggingMW <- loggingMiddleware
 | 
						||
    -- server starten
 | 
						||
    if myserviceDebug
 | 
						||
       then runMyServiceMiddlewareServer config (cors (\_ -> Just (simpleCorsResourcePolicy {corsRequestHeaders = ["Content-Type"]})) . loggingMW . logStdout) server
 | 
						||
       else runMyServiceMiddlewareServer config (cors (\_ -> Just (simpleCorsResourcePolicy {corsRequestHeaders = ["Content-Type"]}))) server
 | 
						||
 
 | 
						||
 
 | 
						||
-- Sollte bald in die Library hs-stomp ausgelagert werden
 | 
						||
-- ist ein Beispiel für einen ActiveMQ-Dumper
 | 
						||
keepActiveMQConnected :: ServerConfig -> ([LogItem] -> IO ()) -> TQueue BS.ByteString -> IO ()
 | 
						||
keepActiveMQConnected sc@ServerConfig{..} printLog var = do
 | 
						||
  res <- handle (\(e :: SomeException) -> do
 | 
						||
      printLog . pure . Error $ "Exception in AMQ-Thread: "<>show e
 | 
						||
      return $ Right ()
 | 
						||
    ) $ AMQ.try $ do -- catches all AMQ-Exception that we can handle. All others bubble up.
 | 
						||
        printLog . pure . Info $ "AMQ: connecting..."
 | 
						||
        withConnection myserviceActivemqHost myserviceActivemqPort [ OAuth myserviceActivemqUsername myserviceActivemqPassword
 | 
						||
                                                                   , OTmo (30*1000) {- 30 sec timeout -}
 | 
						||
                                                                   ]
 | 
						||
                                                                   [] $ \c -> do
 | 
						||
          let oconv = return
 | 
						||
          printLog . pure . Info $ "AMQ: connected"
 | 
						||
          withWriter c "Chaos-Logger for Kibana" "chaos.logs" [] [] oconv $ \writer -> do
 | 
						||
            printLog . pure . Info $ "AMQ: queue created"
 | 
						||
            let postfun = writeQ writer (Type (Application "json") []) []
 | 
						||
            void $ race
 | 
						||
              (forever $ atomically (readTQueue var) >>= postfun)
 | 
						||
              (threadDelay (600*1000*1000)) -- wait 10 Minutes
 | 
						||
          -- close writer
 | 
						||
        -- close connection
 | 
						||
  -- get outside of all try/handle/...-constructions befor recursing.
 | 
						||
  case res of
 | 
						||
    Left ex -> do
 | 
						||
      printLog . pure . Error $ "AMQ: "<>show ex
 | 
						||
      keepActiveMQConnected sc printLog var
 | 
						||
    Right _ -> keepActiveMQConnected sc printLog var
 | 
						||
 
 | 
						||
 
 | 
						||
-- Beispiel für eine Custom-Logging-Middleware.
 | 
						||
-- Hier werden z.B. alle 4xx-Status-Codes inkl. Payload ins stdout-Log geschrieben.
 | 
						||
-- Nützlich, wenn die Kollegen ihre Requests nicht ordentlich schreiben können und der Server das Format zurecht mit einem BadRequest ablehnt ;)
 | 
						||
loggingMiddleware :: IO Middleware
 | 
						||
loggingMiddleware = liftIO $ mkRequestLogger $ def { outputFormat = CustomOutputFormatWithDetails out }
 | 
						||
  where
 | 
						||
    out :: ZonedDate -> WAI.Request -> Status -> Maybe Integer -> NominalDiffTime -> [BS.ByteString] -> Builder -> LogStr
 | 
						||
    out _ r status _ _ payload _
 | 
						||
      | statusCode status < 300 = ""
 | 
						||
      | statusCode status > 399 && statusCode status < 500 = "Error code "<>toLogStr (statusCode status) <>" sent. Request-Payload was: "<> mconcat (toLogStr <$> payload) <> "\n"
 | 
						||
      | otherwise = toLogStr (show r) <> "\n"
 | 
						||
</code></pre></div>
 | 
						||
 | 
						||
  <!-- div class="flex items-center justify-center mt-2">
 | 
						||
  <ema:metadata>
 | 
						||
    <with var="template">
 | 
						||
      <a class="text-gray-300 hover:text-${theme}-600 text-sm" title="Edit this page on GitHub"
 | 
						||
        href="${value:editBaseUrl}/${ema:note:source-path}">
 | 
						||
        <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
 | 
						||
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
 | 
						||
            d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
 | 
						||
        </svg>
 | 
						||
      </a>
 | 
						||
    </with>
 | 
						||
  </ema:metadata>
 | 
						||
</div -->
 | 
						||
</article>
 | 
						||
            <div class='flex flex-col lg:flex-row lg:space-x-2'>
 | 
						||
              
 | 
						||
              
 | 
						||
  <div class='flex-1 p-4 mt-8 bg-gray-100 rounded'>
 | 
						||
    <header class='mb-2 text-xl font-semibold text-gray-500'>Links to this page</header>
 | 
						||
    <ul class='space-y-1'>
 | 
						||
      
 | 
						||
        <li>
 | 
						||
          <a class='text-purple-600 mavenLinkBold hover:bg-purple-50' href='Coding/Haskell/Webapp-Example'>
 | 
						||
            Webapp-Development in Haskell
 | 
						||
          </a>
 | 
						||
          
 | 
						||
            <div class='mb-4 overflow-auto text-sm text-gray-500'>
 | 
						||
  
 | 
						||
    <div class='pl-2 mt-2 border-l-2 border-purple-200 hover:border-purple-500'>
 | 
						||
      <div><p><a href='Coding/Haskell/Webapp-Example/Main.hs' class='text-gray-600 font-bold hover:bg-gray-50' data-wikilink-type='WikiLinkEmbed'>Webapp-Example: Main.hs</a></p></div>
 | 
						||
    </div>
 | 
						||
  
 | 
						||
</div>
 | 
						||
          
 | 
						||
        </li>
 | 
						||
      
 | 
						||
    </ul>
 | 
						||
  </div>
 | 
						||
 | 
						||
            </div>
 | 
						||
            
 | 
						||
  <section class='flex flex-wrap items-end justify-center my-4 space-x-2 space-y-2 font-mono text-sm'>
 | 
						||
    
 | 
						||
  </section>
 | 
						||
 | 
						||
            <!-- What goes in this file will at the very end of the main div -->
 | 
						||
          </main>
 | 
						||
        </div>
 | 
						||
      </div>
 | 
						||
      <footer class='flex items-center justify-center mt-2 mb-8 space-x-4 text-center text-gray-800'>
 | 
						||
  
 | 
						||
  <div>
 | 
						||
    <a href='' title='Go to Home page'>
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-6 h-6 hover:text-purple-700' fill='none' viewBox='0 0 24 24' stroke='currentColor'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6'></path>
 | 
						||
      </svg>
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
  <div>
 | 
						||
    <a href='-/all' title='View Index'>
 | 
						||
      <svg class='w-6 h-6 hover:text-purple-700' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
  <div>
 | 
						||
    <a href='https://emanote.srid.ca' target='_blank' title='Generated by Emanote 1.0.3.11'>
 | 
						||
      <img class='w-6 h-6 hover:text-purple-700' src='_emanote-static/emanote-logo.svg' />
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
  <div>
 | 
						||
    <a href='-/tags' title='View tags'>
 | 
						||
      <svg class='w-6 h-6 hover:text-purple-700' fill='none' stroke='currentColor' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z'>
 | 
						||
        </path>
 | 
						||
      </svg>
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
  <div>
 | 
						||
    <a href='-/tasks' title='View tasks'>
 | 
						||
      <svg xmlns='http://www.w3.org/2000/svg' class='w-6 h-6 hover:text-purple-700' fill='none' viewBox='0 0 24 24' stroke='currentColor'>
 | 
						||
        <path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z'></path>
 | 
						||
      </svg>
 | 
						||
    </a>
 | 
						||
  </div>
 | 
						||
</footer>
 | 
						||
    </div>
 | 
						||
  
 | 
						||
  <div id='stork-search-container' class='hidden fixed w-screen h-screen inset-0 backdrop-filter backdrop-blur-sm'>
 | 
						||
  <div class='fixed w-screen h-screen inset-0' onclick='window.emanote.stork.toggleSearch()'></div>
 | 
						||
 | 
						||
  <div class='container mx-auto p-10 mt-10'>
 | 
						||
    <div class='stork-wrapper-flat container mx-auto'>
 | 
						||
      <input id='stork-search-input' data-stork='emanote-search' class='stork-input' placeholder='Search (Ctrl+K) ...' />
 | 
						||
      <div data-stork='emanote-search-output' class='stork-output'></div>
 | 
						||
    </div>
 | 
						||
  </div>
 | 
						||
</div>
 | 
						||
  
 | 
						||
    
 | 
						||
  
 | 
						||
</body>
 | 
						||
 | 
						||
</html>
 |