Compare commits

...
161 Commits
Author SHA1 Message Date
Philippe Torrel 1fc7aea2c3 2026-11-06 14:34:05 +01:00
Philippe Torrel cf5e373303 2026-11-06 13:28:47 +01:00
Philippe Torrel d918c197ae 2026-11-06 11:28:45 +01:00
Philippe Torrel 6c9b06b983 2026-11-06 10:57:46 +01:00
Philippe Torrel 38867d737c 2026-11-06 10:45:42 +01:00
Philippe Torrel 24dacde5a9 2026-11-05 14:46:04 +01:00
Philippe Torrel 00be33abcc 2026-11-05 09:37:54 +01:00
Philippe Torrel 21ad1ceb30 2026-11-05 09:29:05 +01:00
Philippe Torrel 2f1b79a86a 2026-11-04 14:57:27 +01:00
Philippe Torrel 1dcec632d8 2026-11-04 14:42:53 +01:00
Philippe Torrel 7cd82c0954 2026-11-04 13:28:39 +01:00
Philippe Torrel 3ae7bb13b8 2026-11-04 13:21:50 +01:00
Philippe Torrel 2cd098e5a2 2026-11-04 11:38:17 +01:00
Philippe Torrel 6b58d09ec9 2026-11-04 11:35:00 +01:00
Philippe Torrel c356167f97 2026-11-04 09:59:51 +01:00
Philippe Torrel f475f40350 2026-11-03 14:52:15 +01:00
Philippe Torrel ed2c0b9906 2026-11-03 13:28:24 +01:00
Philippe Torrel baf557f666 2026-11-03 11:40:59 +01:00
Philippe Torrel a885cd9550 2026-11-03 09:09:37 +01:00
Philippe Torrel c5806140ae 2026-11-02 14:22:00 +01:00
Philippe Torrel c322bf1edf 2026-11-02 14:21:30 +01:00
Philippe Torrel 6c7b9a0032 2026-11-02 14:15:06 +01:00
Philippe Torrel 5c5e64aac9 2026-11-02 14:13:12 +01:00
Philippe Torrel 3e77bd3f49 2026-11-02 14:03:48 +01:00
Philippe Torrel b21be6c1d1 2026-11-02 13:02:29 +01:00
Philippe Torrel 50c1e85931 2026-11-02 12:10:09 +01:00
Philippe Torrel c936a7f00c 2026-11-02 11:17:53 +01:00
Philippe Torrel 7936f3387b 2026-11-02 09:29:11 +01:00
Philippe Torrel da7fd3f7eb 2026-11-02 09:20:35 +01:00
Philippe Torrel 451e19b3a1 2026-10-30 14:21:02 +01:00
Philippe Torrel cd9acfb9eb 2026-10-30 14:19:57 +01:00
Philippe Torrel 7828535330 2026-10-30 13:49:51 +01:00
Philippe Torrel e91c11346e 2026-10-30 12:17:04 +01:00
Philippe Torrel e9211c0a92 2026-10-30 10:55:55 +01:00
Philippe Torrel 2426cd56bc 2026-10-30 09:31:44 +01:00
Philippe Torrel e955f3fc4f 2026-10-29 15:15:34 +01:00
Philippe Torrel f65a30752f 2026-10-29 14:09:14 +01:00
Philippe Torrel ce35a827c3 2026-10-29 11:09:13 +01:00
Philippe Torrel cdb30b2ea3 2026-10-29 10:08:58 +01:00
Philippe Torrel d823a35ac1 2026-10-28 14:33:56 +01:00
Philippe Torrel b00bf0c183 2026-10-28 13:37:20 +01:00
Philippe Torrel 5ca16567d2 2026-10-28 11:42:38 +01:00
Philippe Torrel 3370aa2caa 2026-10-28 11:37:43 +01:00
Philippe Torrel a2b463d491 2026-10-28 11:36:44 +01:00
Philippe Torrel c623e6f9d6 2026-10-28 09:56:49 +01:00
Philippe Torrel 34172beb12 2026-10-28 09:53:04 +01:00
Philippe Torrel 3367fea887 2026-10-27 14:34:42 +01:00
Philippe Torrel acf2deaea3 2026-10-27 13:55:51 +01:00
Philippe Torrel 6985789ef7 2026-10-27 13:21:23 +01:00
Philippe Torrel 75a26bda91 2026-10-27 13:15:18 +01:00
Philippe Torrel 2efeba53f2 2026-10-27 11:36:15 +01:00
Philippe Torrel 3b5f77b95e 2026-10-27 10:33:45 +01:00
Philippe Torrel 72d02ee501 2026-10-27 08:59:48 +01:00
Philippe Torrel b2577c249a 2026-10-26 14:25:47 +01:00
Philippe Torrel 12a7bc895c 2026-10-26 13:29:18 +01:00
Philippe Torrel a1a85e4743 2026-10-26 11:38:50 +01:00
Philippe Torrel 688ad6e2cf 2026-10-26 11:18:23 +01:00
Philippe Torrel f8fc579c6f 2026-10-26 10:10:08 +01:00
Philippe Torrel 778d1f2929 2026-10-26 08:49:43 +01:00
Philippe Torrel 7927009320 2026-10-26 08:39:38 +01:00
Philippe Torrel 4036beca67 2026-10-23 14:31:45 +02:00
Philippe Torrel 4a81288194 2026-10-23 13:57:26 +02:00
Philippe Torrel 5739309790 2026-10-23 13:07:02 +02:00
Philippe Torrel 72ee23c158 2026-10-23 11:21:52 +02:00
Philippe Torrel 7489f4288c 2026-10-23 10:41:47 +02:00
Philippe Torrel 62b63ff196 2026-10-22 14:44:23 +02:00
Philippe Torrel fd7a5a03ca 2026-10-22 13:45:38 +02:00
Philippe Torrel 5b6dc89bb5 2026-10-22 11:46:40 +02:00
Philippe Torrel 5d11cf5541 2026-10-21 15:18:43 +02:00
Philippe Torrel a385afacf9 2026-10-21 15:12:12 +02:00
Philippe Torrel f115c02ed5 2026-10-21 15:09:59 +02:00
Philippe Torrel e54f22a25c 2026-10-21 14:45:58 +02:00
Philippe Torrel eda043f0c6 2026-10-21 14:45:39 +02:00
Philippe Torrel 0526e28413 2026-10-21 14:05:40 +02:00
Philippe Torrel 017583b8c8 2026-10-21 13:27:49 +02:00
Philippe Torrel 6ec63fb1ec 2026-10-21 10:33:38 +02:00
Philippe Torrel e3547acc13 2026-10-20 14:42:50 +02:00
Philippe Torrel fe8fc15363 2026-10-20 13:25:06 +02:00
Philippe Torrel 9f316103e9 2026-10-20 13:17:52 +02:00
Philippe Torrel 490de9179b 2026-10-20 10:40:15 +02:00
Philippe Torrel 8e7c8112a3 2026-10-20 10:40:07 +02:00
Philippe Torrel bcb589d15e 2026-10-20 09:51:20 +02:00
Philippe Torrel 16416a0239 2026-10-19 14:31:58 +02:00
Philippe Torrel 73de568a05 2026-10-19 13:18:13 +02:00
Philippe Torrel f474ba8ea0 2026-10-19 11:23:25 +02:00
Philippe Torrel 141a2ab609 2026-10-19 10:27:26 +02:00
Philippe Torrel a51aa72cc9 2026-10-19 08:46:20 +02:00
Philippe Torrel 864b3f27d9 2026-10-16 14:47:08 +02:00
Philippe Torrel 5a14dd3f10 2026-10-16 14:35:19 +02:00
Philippe Torrel 42583441cc 2026-10-16 11:43:13 +02:00
Philippe Torrel 5b04511a91 2026-10-16 10:41:26 +02:00
Philippe Torrel 64ff587b2c 2026-10-15 15:31:35 +02:00
Philippe Torrel e797e9e8dd 2026-10-15 14:37:59 +02:00
Philippe Torrel 5bf1292c21 2026-10-15 13:43:04 +02:00
Philippe Torrel 2a541fcdb1 2026-10-15 10:33:51 +02:00
Philippe Torrel 64722b9dd2 2026-10-14 14:41:26 +02:00
Philippe Torrel 34a9abfe23 2026-10-14 13:25:22 +02:00
Philippe Torrel 7964b5e15c 2026-10-14 11:09:17 +02:00
Philippe Torrel 69655e8ef6 2026-10-14 10:33:34 +02:00
Philippe Torrel 42356cfd31 2026-10-13 13:47:13 +02:00
Philippe Torrel 707e3bebe9 2026-10-13 13:41:26 +02:00
Philippe Torrel bc06824ab6 2026-10-13 13:18:21 +02:00
Philippe Torrel 36c0c2c7ea 2026-10-13 11:49:05 +02:00
Philippe Torrel c41a126ea6 2026-10-13 11:00:26 +02:00
Philippe Torrel 7e46647b86 2026-10-13 09:18:06 +02:00
Philippe Torrel 11044693c9 2026-10-13 08:43:39 +02:00
Philippe Torrel 29d4c7504f 2026-10-12 12:27:10 +02:00
Philippe Torrel d83afa36d9 2026-10-12 11:46:07 +02:00
Philippe Torrel b9eb9f8f70 2026-10-12 11:17:01 +02:00
Philippe Torrel 2c4aba89a9 2026-10-12 09:42:38 +02:00
Philippe Torrel 87773ffa50 2026-10-12 09:22:39 +02:00
Philippe Torrel ff82f5a054 2026-10-12 08:29:27 +02:00
Philippe Torrel b8fe2dfafe 2026-10-09 14:05:04 +02:00
Philippe Torrel 588960732e 2026-10-09 11:30:28 +02:00
Philippe Torrel 7fd7301202 2026-10-09 11:30:10 +02:00
Philippe Torrel 80c664c78a 2026-10-09 11:01:53 +02:00
Philippe Torrel df640e0af2 2026-10-09 10:54:32 +02:00
Philippe Torrel 19dc8aed74 2026-10-09 08:31:55 +02:00
Philippe Torrel e3d489e247 2026-10-08 14:27:52 +02:00
Philippe Torrel ebe9ab0e34 2026-10-08 14:26:06 +02:00
Philippe Torrel a064006966 2026-10-08 10:29:05 +02:00
Philippe Torrel 7e6ec5b9ef 2026-10-07 14:34:48 +02:00
Philippe Torrel 1fe62103a8 2026-10-07 13:19:45 +02:00
Philippe Torrel fc5c2ad59e 2026-10-07 12:13:46 +02:00
Philippe Torrel 31a58172b5 2026-10-07 10:32:46 +02:00
Philippe Torrel 723c95a3f9 2026-10-07 09:55:58 +02:00
Philippe Torrel 7763aa89dc 2026-10-07 08:29:28 +02:00
Philippe Torrel 68ec935f9a 2026-10-06 14:23:51 +02:00
Philippe Torrel 7d06d95ab6 2026-10-06 14:18:57 +02:00
Philippe Torrel c1af899035 2026-10-06 14:14:42 +02:00
Philippe Torrel 057001ad03 2026-10-06 12:12:17 +02:00
Philippe Torrel e8c2fc145f 2026-10-06 10:32:07 +02:00
Philippe Torrel 7e1d20d0ec 2026-10-05 14:47:25 +02:00
Philippe Torrel 1bd81120cc 2026-10-05 14:36:39 +02:00
Philippe Torrel 7ba49fc673 2026-10-05 13:51:50 +02:00
Philippe Torrel 6c4bc185b3 2026-10-05 12:10:33 +02:00
Philippe Torrel 2a2bdc3c63 2026-10-05 11:57:07 +02:00
Philippe Torrel 6f4f54522c 2026-10-05 10:40:06 +02:00
Philippe Torrel 967bd5c7ea 2026-10-05 08:24:44 +02:00
Philippe Torrel 0987345152 2026-10-02 19:34:53 +02:00
Philippe Torrel 78b97c124a 2026-10-02 15:05:40 +02:00
Philippe Torrel 643fdfc410 2026-10-02 14:37:41 +02:00
Philippe Torrel c388855bf9 2026-10-02 13:56:03 +02:00
Philippe Torrel c612d6d873 2026-10-02 13:55:03 +02:00
Philippe Torrel 4582633d83 2026-10-02 11:53:06 +02:00
Philippe Torrel 39962434d0 2026-10-02 11:31:12 +02:00
Philippe Torrel 5a688bc7ea 2026-10-02 09:50:52 +02:00
Philippe Torrel 4dec8a5680 Updated agenda 2026-10-02 08:34:58 +02:00
Philippe Torrel 7b234167fa 2026-10-01 14:44:59 +02:00
Philippe Torrel 6972ee5e4f 2026-10-01 13:24:27 +02:00
Philippe Torrel af025ac50c 2026-10-01 13:13:09 +02:00
Philippe Torrel 366a821a0e 2026-10-01 11:18:16 +02:00
Philippe Torrel 02b3745b88 2026-10-01 10:37:23 +02:00
Philippe Torrel 58bdd6018f 2026-10-01 08:31:35 +02:00
Philippe Torrel 7a4748b549 2026-09-30 15:00:47 +02:00
Philippe Torrel 8c7380fde9 2026-09-30 13:40:36 +02:00
Philippe Torrel 9dad0f06a2 2026-09-30 10:30:27 +02:00
Philippe Torrel 635c23d5e8 2026-09-30 09:42:22 +02:00
Philippe Torrel 102a818a83 2026-09-30 08:22:13 +02:00
Philippe Torrel 9e243cbaf2 2026-09-30 08:12:42 +02:00
Philippe Torrel ef9a956a2c 2026-09-30 08:09:20 +02:00
5765 changed files with 730405 additions and 34 deletions
+3
View File
@@ -1,4 +1,7 @@
{ {
"terminal.explorerKind": "external",
"terminal.external.osxExec": "iTerm.app",
"terminal.external.windowsExec": "wt.exe",
"workbench.iconTheme": "vscode-icons", "workbench.iconTheme": "vscode-icons",
"workbench.colorTheme": "One Dark Pro", "workbench.colorTheme": "One Dark Pro",
"prettier.printWidth": 120, "prettier.printWidth": 120,
+24 -19
View File
@@ -280,15 +280,31 @@ Projektarbeit + Wetter API Key besorgen
**Inhalt:** **Inhalt:**
- XML-HttpRequest und AJAX mit jQuery - XML-HttpRequest und AJAX mit jQuery
- Node Module für die Projekt-Entwicklungsumgebung
- Wetter API auslesen - Wetter API auslesen
- Node Standardbib (fs, zlib (stream), Crypto)
- fetch in der Praxis: Joke API auslesen - fetch in der Praxis: Joke API auslesen
- Abschluss von JS für Fortgeschrittene - Was ist Node.js? (Wiederholung)
- Projektvorstellung 1 + 2
**Übungen:** **Übungen:**
Projektarbeit Projektarbeit
Übungen Public API auslesen
---
#### Tag 18
**Inhalt:**
- Node Standardbib (fs, zlib (stream), Crypto)
- Import vs. require (Teil II)
- NPM Befehle
- Abschluss von JS für Fortgeschrittene
- Projektvorstellung 1 + 2 JS Advanced
**Übungen:**
Übungen 25 - 31 Übungen 25 - 31
--- ---
@@ -297,23 +313,12 @@ Projektarbeit
--- ---
#### Tag 18
**Inhalt:**
- Einführung in JS DOM
- DOM Selection (querySelector, querySelectorAll)
- $ & $$ Helper
- CSS Selektoren
**Übungen:**
Übungen 01 - 05
---
#### Tag 19 #### Tag 19
- Einführung in JS DOM
- DOM Selection (querySelector, querySelectorAll, $ & $$ Helper)
- CSS Selektoren
- Defer & Async - Defer & Async
- JS Dateien auslagern - JS Dateien auslagern
- Chat Gestaltung (DOMTokenList Objekt) - Chat Gestaltung (DOMTokenList Objekt)
@@ -322,7 +327,7 @@ Projektarbeit
**Übungen:** **Übungen:**
Übungen 06 - 07 Übungen 01 - 06
--- ---
@@ -337,4 +342,4 @@ Projektarbeit
**Übungen:** **Übungen:**
Übung 08 - 10 Übung 07 - 10
+114
View File
@@ -0,0 +1,114 @@
## NVM - Node Version Manager
nvm ist ein Versionsmanager für node.js. Über nvm können mehrere unterschiedliche Node Versionen installiert werden. NVM wird über die Konsole aufgerufen und ist mit verschiedenen Shells kompatibel (sh, dash, ksh, zsh, bash).
#### Links
- <https://github.com/coreybutler/nvm-windows> (Win)
- <https://github.com/nvm-sh/nvm> (Mac OS)
#### Installation Windows
1. Lade den NVM-Installer über folgenden Link herunter: <https://github.com/coreybutler/nvm-windows/releases>
2. Installiere NVM über den [Installer](https://github.com/coreybutler/nvm-windows/releases/download/1.2.2/nvm-setup.zip)
3. Sollte vorher bereits NodeJS global ohne NVM installiert worden sein, wird empfohlen die vorherige NodeJS Version zu [deinstallieren](https://stackoverflow.com/a/55300310).
### Installation Mac OS
- Installiere NVM über die Konsole mit:
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.4/install.sh | bash
```
- Füge den Pfad zum NVM Ordner zur Shell-Config hinzu. (`~/.bash_profile`, `~/.zshrc`, `~/.profile`, or `~/.bashrc`).
```bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```
- Aktuelle Informationen zur Installation findet man unter folgendem Link: <https://github.com/nvm-sh/nvm>
#### Erste Schritte
Sobald NVM erfolgreich installiert wurde kann man über nvm in der Konsole eine neue Node Version mit folgendem Befehl installieren:
```bash
nvm install [NODE VERSIONSNUMMER]
```
> Hinweis: Die aktuellste Versionsnummer von NodeJS findet man am einfachsten auf der [NodeJS-Seite](https://nodejs.org/en/)
Installierte Node Versionen auflisten
```bash
nvm list
```
Node Version verwenden/wechseln
```bash
nvm use [NODE VERSIONSNUMMER]
```
Node Version als Standard einrichten
```bash
nvm alias default [NODE VERSIONSNUMMER]
```
## Node.js
### Definition
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
## Neues Projekt erstellen
- Über die Konsole in den Projektordner gehen.
Projektordner wechsel über "change directory" (cd)
```bash
cd [projektpfad]
```
- Eigene Package.json Datei generieren (nur einmalig bei einem neuen Projekt notwendig.)
```bash
npm init
```
- Module installieren, die nur für die Entwicklung benötigt werden. (devDependicies)
| Befehl | Zweck |
| ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `npm install Modul@Version` | installiere Modul in der Version Version (semantic versioning) |
| `npm install Modul@Version --save`<br>`npm install Modul@Version -S` | Modul wird in der Datei `package.json` unter dependencies hinzugefügt (Mittlerweile default) |
| `npm install Modul@Version --save-dev`<br>`npm install Modul@Version -D` | Modul wird in der Datei `package.json` unter devdependencies hinzugefügt |
| `npm install Modul@Version --global`<br>`npm install Modul@Version -g` | Modul wird global installiert. (Von jedem Ordner aus anwendbar) |
| `npm uninstall Modul@Version` | entfernt Modul aus `node_modules` |
| `npm uninstall Modul@Version --save` | entfernt Modul aus `node_modules` und aus der dependencies- Eigenschaft in der `package.json`. |
| `npm update Modul` | Aktualisiert Modul auf die neueste Version |
| `npm update Modul --save` |  Aktualisiert Modul auf die neueste Version und auch die Versionsnummer der dependencies- Eigenschaft in der `package.json`. |
| `npm init` | erstellt eine package.json-Datei (der Befehl fragt die Eigenschaften ab) |
| `npm init --yes` | erstellt eine package.json-Datei (der Befehl setzt Default-Werte ein) |
| `npm list` | listet alle installierten Module auf. |
| `npm search` | Suchbegriff sucht Module, deren Namen den Suchbegriff enthält |
# Globale Module
## SASS
### Definition
> Sass is the most mature, stable, and powerful professional grade CSS extension language in the world.
Sass ist eine CSS-Preprocessor Sprache.
```bash
npm install sass -g
```
## Liste von verwendeten Modulen
Binary file not shown.
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
@@ -0,0 +1,17 @@
## License and terms of use
© Web Professional Institute Inc. All rights reserved.
This material is provided solely for students enrolled in courses offered by Web Professional Institute Inc. By accessing or using this code, you acknowledge that it is strictly for educational use within the context of Web Professional Institute Inc. programs.
**Usage Restrictions:**
- Redistribution, sharing, or copying of this material outside the course environment is strictly prohibited.
- The content is designed to support your learning objectives and is not authorized for commercial projects, public repositories, or applications beyond the course scope.
- Unauthorized commercial use or open-source distribution is strictly prohibited and may result in expulsion from the program and legal action.
**Agreement & Rights:**
As a student, you have agreed to these terms as part of your enrollment agreement, which includes additional details on permitted uses, restrictions, and policies. The author and Web Professional Institute Inc. retain all rights to this material, including the code base and instructional content.
For any questions regarding these terms, please contact Web Professional Institute Inc. for clarification.
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Recipe Explorer Dashboard</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<h1>Recipe Explorer Dashboard</h1>
<div id="search-container">
<input
type="text"
id="search-input"
placeholder="Search for recipes by name..."
/>
<button id="search-button">Search</button>
</div>
<div id="loading">Loading...</div>
<div id="error-message"></div>
<table id="recipes-table">
<thead>
<tr>
<th>Recipe Name</th>
<th>Cuisine</th>
<th>Preparation Time (mins)</th>
</tr>
</thead>
<tbody>
<!-- Recipe data will be populated here -->
</tbody>
</table>
<!-- Modal for Recipe Details -->
<div id="recipe-modal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<h2 id="modal-title">Recipe Name</h2>
<img
id="modal-image"
src=""
alt="Recipe Image"
style="border-radius: 10px; max-height: 200px"
/>
<p><strong>Cuisine:</strong> <span id="modal-category"></span></p>
<p>
<strong>Preparation Time:</strong> <span id="modal-time"></span> mins
</p>
<p><strong>Ingredients:</strong></p>
<ul id="modal-ingredients">
<!-- Ingredients will be populated here -->
</ul>
<p><strong>Instructions:</strong></p>
<p id="modal-instructions"></p>
</div>
</div>
<script src="scripts.js"></script>
</body>
</html>
@@ -0,0 +1,122 @@
(() => {
// ===== DOM & VARIABLES =====
const RECIPES_URL = 'https://dummyjson.com/recipes';
const searchInput = document.querySelector('#search-input');
const searchButton = document.querySelector('#search-button');
const recipesTableBody = document.querySelector('#recipes-table tbody');
const loadingIndicator = document.querySelector('#loading');
const errorMessage = document.querySelector('#error-message');
const modal = document.querySelector('#recipe-modal');
const modalTitle = document.querySelector('#modal-title');
const modalImage = document.querySelector('#modal-image');
const modalCategory = document.querySelector('#modal-category');
const modalTime = document.querySelector('#modal-time');
const modalIngredients = document.querySelector('#modal-ingredients');
const modalInstructions = document.querySelector('#modal-instructions');
const closeModal = document.querySelector('.close');
let allRecipes = [];
// ===== INIT =====
const init = () => {
// TODO: Fetch and display all recipes on initial load
// Event Listeners
closeModal.addEventListener('click', closeModalEvent);
window.addEventListener('click', windowClickEvent);
};
// ===== EVENT LISTENERS =====
const searchButtonEvent = () => {
const query = searchInput.value.trim().toLowerCase();
if (query !== '') {
// TODO: Implement search functionality
} else {
// TODO: Display all recipes if search input is empty
}
};
// Close Modal Event
const closeModalEvent = () => {
modal.style.display = 'none';
};
// Close Modal when clicking outside the modal content
const windowClickEvent = (event) => {
if (event.target == modal) {
modal.style.display = 'none';
}
};
// ===== FUNCTIONS =====
// Fetches all recipes from the API and displays them.
const fetchAndDisplayRecipes = async () => {
showLoading(true);
showError(false, '');
try {
// TODO: Fetch data from API
} catch (error) {
console.error(error);
showError(true, 'An error occurred while fetching recipes.');
} finally {
showLoading(false);
}
};
// Searches for recipes by name and displays the results.
const searchRecipes = async (query) => {
showLoading(true);
showError(false, '');
try {
// TODO: Search for recipes by name
} catch (error) {
console.error(error);
showError(true, 'An error occurred while searching for recipes.');
} finally {
showLoading(false);
}
};
// Displays a list of recipes in the table.
const displayRecipes = (recipes) => {
clearTable();
// TODO: Iterate over the recipes and display them in the table
};
// Displays detailed information about a selected recipe in a modal.
const showRecipeDetails = (recipe) => {
// TODO: Calculate total preparation time
// TODO: Set image source
// TODO: Populate ingredients
// TODO: Show modal
};
// Shows or hides the loading indicator.
const showLoading = (show) => {
loadingIndicator.style.display = show ? 'block' : 'none';
};
// Displays or hides an error message.
const showError = (show, message) => {
if (show) {
errorMessage.textContent = message;
errorMessage.style.display = 'block';
} else {
errorMessage.textContent = '';
errorMessage.style.display = 'none';
}
};
// Clears the recipes table.
const clearTable = () => {
recipesTableBody.innerHTML = '';
};
// ===== CALL INIT =====
init();
})();
@@ -0,0 +1,124 @@
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
text-align: center;
color: #4d7c0f;
}
#search-container {
text-align: center;
margin-bottom: 20px;
}
#search-input {
width: 300px;
padding: 10px;
font-size: 16px;
border: 2px solid #65a30d;
border-radius: 5px;
}
#search-button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: #4d7c0f;
color: white;
border: none;
border-radius: 5px;
margin-left: 10px;
}
#search-button:hover {
background-color: #65a30d;
transition: 0.1s;
}
#recipes-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
max-width: 1000px;
margin-inline: auto;
}
#recipes-table th,
#recipes-table td {
border: 1px solid #ddd;
padding: 12px;
text-align: left;
}
#recipes-table th {
background-color: #4d7c0f;
color: white;
}
#recipes-table tr:nth-child(even) {
background-color: #f9f9f9;
}
#recipes-table tr:hover {
background-color: #ecfccb;
cursor: pointer;
}
/* Modal styling */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.4);
}
.modal-content {
background-color: #fff;
margin: auto;
padding: 20px;
border: 1px solid #888;
width: 60%;
border-radius: 10px;
position: relative;
}
.close {
color: #aaa;
position: absolute;
top: 15px;
right: 25px;
font-size: 30px;
font-weight: bold;
cursor: pointer;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
}
/* Loading Indicator */
#loading {
display: none;
text-align: center;
font-size: 18px;
color: #4d7c0f;
}
/* Error Message */
#error-message {
display: none;
text-align: center;
color: red;
font-size: 18px;
margin-bottom: 20px;
}
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
@@ -0,0 +1,17 @@
## License and terms of use
© Web Professional Institute Inc. All rights reserved.
This material is provided solely for students enrolled in courses offered by Web Professional Institute Inc. By accessing or using this code, you acknowledge that it is strictly for educational use within the context of Web Professional Institute Inc. programs.
**Usage Restrictions:**
- Redistribution, sharing, or copying of this material outside the course environment is strictly prohibited.
- The content is designed to support your learning objectives and is not authorized for commercial projects, public repositories, or applications beyond the course scope.
- Unauthorized commercial use or open-source distribution is strictly prohibited and may result in expulsion from the program and legal action.
**Agreement & Rights:**
As a student, you have agreed to these terms as part of your enrollment agreement, which includes additional details on permitted uses, restrictions, and policies. The author and Web Professional Institute Inc. retain all rights to this material, including the code base and instructional content.
For any questions regarding these terms, please contact Web Professional Institute Inc. for clarification.
@@ -0,0 +1,76 @@
'use strict';
const menu = [
{
category: 'Beverages',
items: [
{ name: 'Coffee', price: 3.5 },
{ name: 'Tea', price: 2.5 },
{ name: 'Juice', price: 4 },
],
},
{
category: 'Pastries',
items: [
{ name: 'Croissant', price: 2.75 },
{ name: 'Muffin', price: 2.5 },
{ name: 'Bagel', price: 2.25 },
],
},
{
category: 'Sandwiches',
items: [
{ name: 'Ham Sandwich', price: 5.5 },
{ name: 'Veggie Sandwich', price: 5 },
{ name: 'Turkey Sandwich', price: 6 },
],
},
];
// ADD YOUR CODE BELOW
const listMenuItems = (menu) => {};
const calculateAveragePrice = (menu) => {};
const findItemsByCategory = (menu, categoryName) => {};
// ===== TEST CASES (DO NOT MODIFY) =====
// 1. List All Menu Items
const menuItems = listMenuItems(menu);
console.log('All Menu Items:\n', menuItems);
// 2. Calculate Average Price
const averagePrice = calculateAveragePrice(menu);
console.log('Average Price of All Items:', averagePrice);
// 3. Find Items by Category
const searchCategory = 'Pastries';
const pastries = findItemsByCategory(menu, searchCategory);
console.log(`Items in "${searchCategory}" \nItems:`, pastries);
/*
===== EXPECTED OUTPUT =====
All Menu Items:
[
'Coffee',
'Tea',
'Juice',
'Croissant',
'Muffin',
'Bagel',
'Ham Sandwich',
'Veggie Sandwich',
'Turkey Sandwich'
]
Average Price of All Items: 3.78
Items in "Pastries"
Items: [
{ name: 'Croissant', price: 2.75 },
{ name: 'Muffin', price: 2.5 },
{ name: 'Bagel', price: 2.25 }
]
*/
@@ -0,0 +1,100 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GeoLocation API auslesen</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5">
<h1>GeoLocation API auslesen</h1>
</div>
</main>
<script>
'use strict';
(() => {
// === DOM & VARS =======
const DOM = {};
// === INIT =============
const init = () => {
getGeoLocation().then((dataGeolocation) => {
// console.log('Geo Location:' + dataGeolocation);
console.log(setGeoLocation(dataGeolocation));
// getWeather().then((data) => {
// console.log('Weather Data:' + data);
// setWeather(data);
// });
});
getCoordinates().then((data) => {
console.log(data);
});
};
// === EVENTHANDLER =====
// === XHR/FETCH ========
// === FUNCTIONS ========
const setGeoLocation = (data) => {
const { longitude, latitude } = data;
console.log(`LON: ${data.longitude} LAT: ${data.latitude}`);
return { longitude, latitude };
};
const getGeoLocation = async () => {
try {
const res = await fetch('https://myiprightnow.com/api/ip');
if (!res.ok) {
throw Error('Fetch Error Geolocation');
}
const data = await res.json();
console.log(data);
return data;
} catch (error) {
console.error(error);
throw error;
}
};
const getCoordinates = () => {
return new Promise((resolve, reject) => {
// Prüfen, ob der Browser Geolocation unterstützt
if (!navigator.geolocation) {
reject(new Error('Geolocation wird von diesem Browser nicht unterstützt.'));
return;
}
// Optionen für die Abfrage (optional)
const options = {
enableHighAccuracy: true, // Bestmögliche Genauigkeit erzwingen
timeout: 5000, // Max. Wartezeit in Millisekunden
maximumAge: 0, // Kein Cache, frische Daten anfordern
};
// Erfolg-Callback
const success = (position) => {
const { latitude, longitude } = position.coords;
resolve({ latitude, longitude });
};
// Fehler-Callback
const error = (err) => {
reject(new Error(`Standortabfrage fehlgeschlagen: ${err.message}`));
};
// API-Aufruf starten
// https://developer.mozilla.org/de/docs/Web/API/Geolocation/getCurrentPosition
navigator.geolocation.getCurrentPosition(success, error, options);
});
};
init();
})();
</script>
</body>
</html>
@@ -0,0 +1,62 @@
// Übung 25
const quotedCSV = '"very big, soft computer mouse","the cutest peripheral ever","10","39.90"';
// Übung 26
// In der Praxis finden sich auch CSV-Datensätze, in denen manche Felder mit Anführungszeichen umgeben sind und manche nicht.
// Schreibe ein Programm, das auch mit diesen Fällen zurechtkommt. Folgender Datensatz soll korrekt zerlegt werden:
const mixedCSV = '"very big, soft computer mouse","the cutest peripheral ever",10,39.90';
const parseCSVRecord = (record) => {
const fields = [];
let field = '';
let inQuotes = false;
for (const character of record) {
if (character === '"') {
inQuotes = !inQuotes;
} else if (character === ',' && !inQuotes) {
fields.push(field);
field = '';
} else {
field += character;
}
}
fields.push(field);
return fields;
};
console.log(parseCSVRecord(quotedCSV));
console.log(parseCSVRecord(mixedCSV));
/*
Übung 25: CSV-Datensätze mit Anführungszeichen
Bisher haben wir die Felder in einem CSV-Datensatz einfach mit der Anweisung:
record.split(',')
​
in einzelne Felder zerlegt. In der Praxis kann es aber vorkommen, dass ein einzelnes Feld ein Komma enthält. Das Problem wird üblicherweise gelöst, indem die einzelnen Felder noch mit Anführungszeichen umgeben werden. Hier ist ein Beispiel:
'very big, soft computer mouse', 'the cutest peripheral ever', '10', '39.90'
​
Das erste Feld enthält ein Komma (very big, soft computer mouse), trotzdem ist die Unterteilung eindeutig. Schreibe ein kurzes Programm, das diesen Datensatz korrekt zerlegt und die einzelnen Felder ausgibt:
const quotedCSV =
'"very big, soft computer mouse","the cutest peripheral ever","10","39.90"'
*/
/*
Übung 26: CSV-Datensätze mit Anführungszeichen — Teil 2
In der Praxis finden sich auch CSV-Datensätze, in denen manche Felder mit Anführungszeichen umgeben sind und manche nicht.
Schreibe ein Programm, das auch mit diesen Fällen zurechtkommt. Folgender Datensatz soll korrekt zerlegt werden:
const mixedCSV =
'"very big, soft computer mouse","the cutest peripheral ever",10,39.90'
*/
@@ -0,0 +1,51 @@
# Regex Beispiel
Am besten löst man das mit einem regulären Ausdruck, der entweder nach **Inhalten in Anführungszeichen** sucht _oder_ nach **Inhalten ohne Kommas**.
Hier ist der passende Reguläre Ausdruck:
`/"([^"\\]*(?:\\.[^"\\]*)*)"|([^,]+)/g`
---
### Wie der Regex funktioniert
Der Ausdruck nutzt das **ODER-Prinzip (`|`)**, um zwei Szenarien zu matchen:
1. **`"([^"\\]*(?:\\.[^"\\]*)*)"` (Gruppe 1):** Matcht alles, was in doppelten Anführungszeichen steht. Er erlaubt sogar escaped Anführungszeichen (`\"`) im Text.
2. **`([^,]+)` (Gruppe 2):** Wenn keine Anführungszeichen da sind, matcht er alles bis zum nächsten Komma.
---
### Anwendung in JavaScript (Beispiel)
Da du das Ergebnis sicherlich in einem Array von einzelnen Werten brauchst, kannst du den Regex wie folgt anwenden. Hierbei nutzen wir `matchAll`, um die Treffer sauber zu trennen und die Anführungszeichen direkt zu entfernen:
```javascript
const input = '"very big, soft computer mouse","the cutest peripheral ever",10,39.90';
const regex = /"([^"\\]*(?:\\.[^"\\]*)*)"|([^,]+)/g;
const matches = [...input.matchAll(regex)];
const result = matches.map((match) => {
// Wenn Gruppe 1 existiert, war es ein String in Anführungszeichen
// Wenn Gruppe 2 existiert, war es ein unberührter Wert (Zahl)
const value = match[1] !== undefined ? match[1] : match[2].trim();
// Optional: Datentypen konvertieren
if (!isNaN(value) && value !== '') {
return Number(value);
}
return value;
});
console.log(result);
```
### Das Ergebnis (Output)
Nach dem Parsen erhältst du ein sauberes Array, bei dem die Kommas innerhalb der Strings ignoriert wurden und die Zahlen einsatzbereit sind:
```json
["very big, soft computer mouse", "the cutest peripheral ever", 10, 39.9]
```
@@ -0,0 +1 @@
"very big, soft computer mouse","the cutest peripheral ever",10,39.90
1 very big, soft computer mouse the cutest peripheral ever 10 39.90
@@ -0,0 +1,11 @@
Code,Short Description,Tagline,Quantity,Price
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
1 Code Short Description Tagline Quantity Price
2 MUG0007 coffee mug with LCD level indicator never again reach for the empty mug 20 49.90
3 MUG0013 coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling put the smart into coffee reading 20 99.90
4 OFF3145 pen with pre-warmed ink (tested on the South Pole) the pen is mightier than the cold 50 29.90
5 COM1001 ambidextrous computer mouse end the dictate of left and right 10 19.90
6 COM0404 Easter egg themed webcam for your monitor put an Easter egg on hardware too 20 149.90
7 COM0001 Vulcan language vi cheatsheet learn vi and Vulcan at the same time 3 9.90
8 COM1536 Klingon language emacs cheatsheet learn emacs and Klingon at the same time 50 9.90
9 MOB0555 smartphone case with built-in screen never miss a message 20 39.90
Binary file not shown.
+57
View File
@@ -0,0 +1,57 @@
import fs from 'node:fs';
import zlib from 'node:zlib';
import color from 'chalk';
const data = fs.readFileSync('data/products.csv', 'utf-8');
const products = data.split('\n');
const header = products.shift().split(',');
// console.log('header', header); // => Code,Short Description,Tagline,Quantity,Price
const convertCsvToJson = (productRow) => {
// console.log('products', products);
// console.log('ar', ar);
const cols = productRow.split(/\s*,\s*/);
// console.log(product);
// let obj = {};
// for (let i = 0; i < header.length; i++) {
// obj[header[i]] = cols[i];
// }
const product = header.reduce((obj, str, idx) => {
obj[str] = cols[idx];
return obj;
}, {});
return product;
};
const entries = products
.filter((row) => row !== '') //
.map(convertCsvToJson);
console.log(entries);
// fs.writeFile('a.json', JSON.stringify(entries), 'UTF-8', (err) => {
// console.warn(err);
// });
const compressedData = zlib.gzipSync(JSON.stringify(entries));
try {
fs.writeFileSync('data/products.json.gz', compressedData);
console.log('compressed file');
} catch (err) {
console.error(err);
}
/*
Übung 27: Ohne Umwege
Die Datei products.csv soll in eine products.json umgewandelt werden und in products.json.gz komprimiert werden.
*/
/*
Übung 27: Ohne Umwege
Die Datei products.csv soll in eine products.json umgewandelt werden und in products.json.gz komprimiert werden.
*/
+28
View File
@@ -0,0 +1,28 @@
{
"name": "u27_zlib",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "u27_zlib",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"chalk": "^6.0.1"
}
},
"node_modules/chalk": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
"license": "MIT",
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
}
}
}
@@ -0,0 +1,16 @@
{
"name": "u27_zlib",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"chalk": "^6.0.1"
}
}
@@ -0,0 +1,39 @@
// const crypto = require('node:crypto');
import crypto from 'node:crypto';
import _ from 'lodash';
const PASSWORD_LENGTH = 10;
const s = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ!.,;#$%/+*';
const buf = crypto.randomBytes(PASSWORD_LENGTH);
console.log('s.length:', s.length); // => 64
console.log('buf:', buf); // => <Buffer 9a 28 4f d6 32 7a 6d 44 f0 3e>
console.log('Array:', Array.from(buf)); // => [ 17, 181, 126, 182, 190, 212, 137, 233, 140, 75]
const password = Array.from(buf)
.map((byte) => s.charAt(byte % s.length)) // => kZ+!+pbMed
.join('');
console.log(password);
const generatePassword = (length) => {
const chars = '23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ!.,;#$%/+*'.split('');
return _.shuffle(chars)
.slice(0, length + 1)
.join('');
};
const pwd = generatePassword(10);
console.log('Password: ', pwd);
// Übung 28: Passwortgenerator
// Was macht der folgende Code?
// OK: Der Titel verrät es schon. Versuche dennoch, das Programm zu verstehen! Benutze die Dokumentation der Standardbibliothek, um nachzuschlagen, was crypto.randomBytes(…) genau macht!
// Bonusfrage: Warum sind in den Zeichen «1», «i» und «l» nicht enthalten, genau so wenig wie «0» und «o»?
// const asciiLetters = Array.from({ length: 26 }, (_, i) =>
// String.fromCharCode(65 + i) + String.fromCharCode(97 + i)
// ).join(''); // "AaBbCc..." oder getrennt sortieren
@@ -0,0 +1,21 @@
{
"name": "u28_password-generator",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "u28_password-generator",
"version": "1.0.0",
"dependencies": {
"lodash": "^4.18.1"
}
},
"node_modules/lodash": {
"version": "4.18.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
"license": "MIT"
}
}
}
@@ -0,0 +1,14 @@
{
"name": "u28_password-generator",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module",
"dependencies": {
"lodash": "^4.18.1"
}
}
File diff suppressed because it is too large Load Diff
+37
View File
@@ -0,0 +1,37 @@
// const fs = require('node:fs');
// const zlib = require('node:zlib');
import fs from 'node:fs';
import zlib from 'node:zlib';
const gzipCompressor = zlib.createGzip();
const inputStream = fs.createReadStream('data/products.html');
const outputStream = fs.createWriteStream('data/products.html.gz');
inputStream.on('data', (chunk) => {
console.log('Pakete (data chunks) werden geladen: ', chunk.length);
// outputStream.write(zlib.gzipSync(data));
});
outputStream.on('finish', () => {
console.log('Process finished');
});
inputStream.pipe(gzipCompressor).pipe(outputStream);
// Übung 29: Datenströme
// Schreibe Codebeispiel 239 um, ohne die Funktion pipe(…) zu verwenden!
// TIPP: Um eine Datei päckchenweise lesen- und schreiben zu können, gibt es für das fs Modul die Methoden createReadStream und createWriteStream.
// ÜBUNG BEREITS GELÖST!!!
// Die wichtigsten WritableStream-Events im Überblick
// - 'finish': Feuert, nachdem stream.end() aufgerufen wurde und alle gepufferten Daten erfolgreich auf das Ziellaufwerk geschrieben wurden.
// - 'close': Feuert, wenn der zugrundeliegende File Descriptor / die Ressource vollständig geschlossen wurde.
// - 'drain': Feuert, wenn der interne Puffer voll war (write() gab false zurück) und nun wieder bereit für neue Daten ist.
// - 'error': Feuert, wenn beim Schreiben ein Fehler auftritt (z. B. fehlende Schreibrechte oder volle Festplatte).
@@ -0,0 +1,13 @@
{
"name": "03_stream",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module"
}
+67
View File
@@ -0,0 +1,67 @@
import os from 'node:os';
console.log(os.platform());
console.log(os.cpus().length);
console.log(`I am running on a machine with ${os.platform()} and ${os.cpus().length} cores.`);
console.log(`I am running on a machine with ${os.type()} and ${os.cpus().length} cores.`);
console.log(`I am running on a machine with ${os.version()} and ${os.cpus().length} cores.`);
// Weitere Informationen zum Betriebssystem
console.log('\n--- Betriebssystem ---');
console.log('Systemtyp:', os.type());
console.log('Systemversion:', os.release());
console.log('Architektur von Node.js:', os.arch());
console.log('Computername:', os.hostname());
// os.cpus() liefert Informationen zu den logischen CPU-Kernen.
const cpus = os.cpus();
console.log('\n--- Prozessor ---');
console.log('Logische CPU-Kerne:', cpus.length);
console.log('CPU-Modell:', cpus[0]?.model ?? 'Unbekannt');
// Die Speicherangaben kommen in Bytes. 1024 ** 3 Bytes entsprechen einem GiB.
const totalMemory = os.totalmem();
const freeMemory = os.freemem();
const usedMemory = totalMemory - freeMemory;
function formatMemory(bytes) {
return `${(bytes / 1024 ** 3).toFixed(2)} GiB`;
}
console.log('\n--- Arbeitsspeicher ---');
console.log('Gesamt:', formatMemory(totalMemory));
console.log('Frei:', formatMemory(freeMemory));
console.log('Belegt:', formatMemory(usedMemory));
// os.uptime() gibt die Laufzeit des Betriebssystems in Sekunden zurück.
const uptime = os.uptime();
const hours = Math.floor(uptime / 3600);
const minutes = Math.floor((uptime % 3600) / 60);
console.log(`\nSystemlaufzeit: ${hours} Stunden und ${minutes} Minuten`);
console.log('\n--- Benutzer und Verzeichnisse ---');
console.log('Benutzername:', os.userInfo().username);
console.log('Home-Verzeichnis:', os.homedir());
console.log('Temporäres Verzeichnis:', os.tmpdir());
// Jede Netzwerkschnittstelle kann mehrere IPv4- und IPv6-Adressen haben.
console.log('\n--- Netzwerkschnittstellen ---');
for (const [name, addresses] of Object.entries(os.networkInterfaces())) {
for (const address of addresses ?? []) {
console.log(`${name}: ${address.address} (${address.family}${address.internal ? ', intern' : ''})`);
}
}
// Übung 32: Information zum Betriebssystem und der Anzahl der vorhandenen CPUs
// Im Kontext einer Monitoring-Lösung benötigt ein Kunde eine kleine CLI (Command Line Interface)-Anwendung, die es erlaubt, das aktuelle Betriebssystem und die Anzahl der CPUs auf dem jeweiligen Rechner zu ermitteln.
// Vorgehensweise
// 1.Schau dir die Online-Dokumentation zum os-Modul der Standardbibliothek an.
// 2.Erstelle dann ein kurzes Node.js-Programm, das ausgibt, auf welcher Plattform es gerade läuft (also etwa »linux«, »darwin« (OS X) oder »win32«) und wie viele Kerne der Rechner hat.
// Hier eine mögliche Beispielausgabe:
// I am running on a machine with linux and 2 cores.
@@ -0,0 +1,11 @@
{
"name": "u32_os-info",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module"
}
Binary file not shown.
@@ -12111,7 +12111,7 @@ blockquote {
} }
.weather-box { .weather-box {
background-color: #efefef; background-color: #fff;
padding: 1rem; padding: 1rem;
border-radius: 1rem; border-radius: 1rem;
font-family: "Source Sans 3", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; font-family: "Source Sans 3", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
@@ -12167,10 +12167,13 @@ blockquote {
text-align: center; text-align: center;
} }
.weather-box .weather-information .wind-information .icon-compass { .weather-box .weather-information .wind-information .icon-compass {
transition: all 0.8s ease-out;
transition-delay: 200ms;
font-size: 48px; font-size: 48px;
color: #777; color: #777;
width: 48px; width: 48px;
height: 48px; height: 48px;
transform: rotate(-45deg);
margin: 0 1rem 0 2rem; margin: 0 1rem 0 2rem;
} }
File diff suppressed because one or more lines are too long
@@ -40,9 +40,18 @@
} }
}; };
const setWeather = (data) => { const setWeather = (data) => {
DOM.weatherIcon.src = `https://openweathermap.org/img/wn/04d@2x.png`; const { temp_min: tempMin, temp_max: tempMax, temp } = data.main;
DOM.figcaption.textContent = data.weather[0].main; const { speed, deg } = data.wind;
DOM.description.textContent = data.weather[0].description; const { main, description, icon } = data.weather[0];
DOM.weatherIcon.src = `https://openweathermap.org/img/wn/${icon}@2x.png`;
DOM.figcaption.textContent = main;
DOM.description.textContent = description;
DOM.temp.textContent = temp;
DOM.tempMin.textContent = tempMin;
DOM.tempMax.textContent = tempMax;
DOM.speed.textContent = speed;
DOM.deg.textContent = deg;
DOM.iconCompass.style.transform = `rotate(${Number(deg) - 45}deg)`;
}; };
init(); init();
})(); })();
@@ -1,7 +1,7 @@
{ {
"version": 3, "version": 3,
"sources": ["../../dev/js/main.js"], "sources": ["../../dev/js/main.js"],
"sourcesContent": ["'use strict';\n\n(() => {\n // === DOM & VARS =======\n const DOM = {\n weatherBox: document.querySelector('.weather-box'),\n weatherIcon: document.querySelector('.weather-pic img'),\n figcaption: document.querySelector('figcaption'),\n description: document.querySelector('.description'),\n temp: document.querySelector('.temp'),\n tempMin: document.querySelector('.temp-min'),\n tempMax: document.querySelector('.temp-max'),\n iconCompass: document.querySelector('.icon-compass'),\n speed: document.querySelector('.speed'),\n deg: document.querySelector('.wind-deg'),\n };\n\n console.log(DOM);\n\n // BITTE EIGENEN API KEY VERWENDEN\n const API_KEY = 'EIGENER_KEY';\n // https//latlong.net\n const LAT = 43.720215;\n const LON = 7.352606;\n\n // https://api.openweathermap.org/data/4.0/onecall/timeline/1day?cnt=10&lat=51.5000&lon=-0.1000&start=1776596400&appid={API key}\n // === INIT =============\n const init = () => {\n getWeather().then((data) => {\n console.log(data);\n setWeather(data);\n });\n };\n\n // === EVENTHANDLER =====\n\n // === XHR/FETCH ========\n const getWeather = async () => {\n try {\n const res = await fetch(\n `https://api.openweathermap.org/data/2.5/weather?lat=${LAT}&lon=${LON}&units=metric&appid=${API_KEY}`,\n );\n if (!res.ok) {\n throw Error('Fetch Error');\n }\n const data = await res.json();\n return data; // -> Promise\n } catch (error) {\n console.error(error);\n throw error;\n }\n };\n\n // === FUNCTIONS ========\n const setWeather = (data) => {\n // https://openweathermap.org/img/wn/04d@2x.png\n DOM.weatherIcon.src = `https://openweathermap.org/img/wn/04d@2x.png`;\n\n DOM.figcaption.textContent = data.weather[0].main;\n DOM.description.textContent = data.weather[0].description;\n };\n\n init();\n})();\n"], "sourcesContent": ["'use strict';\n\n(() => {\n // === DOM & VARS =======\n const DOM = {\n weatherBox: document.querySelector('.weather-box'),\n weatherIcon: document.querySelector('.weather-pic img'),\n figcaption: document.querySelector('figcaption'),\n description: document.querySelector('.description'),\n temp: document.querySelector('.temp'),\n tempMin: document.querySelector('.temp-min'),\n tempMax: document.querySelector('.temp-max'),\n iconCompass: document.querySelector('.icon-compass'),\n speed: document.querySelector('.speed'),\n deg: document.querySelector('.wind-deg'),\n };\n\n console.log(DOM);\n\n // BITTE EIGENEN API KEY VERWENDEN\n const API_KEY = 'EIGENER_KEY';\n // https//latlong.net\n const LAT = 43.720215;\n const LON = 7.352606;\n\n // https://api.openweathermap.org/data/4.0/onecall/timeline/1day?cnt=10&lat=51.5000&lon=-0.1000&start=1776596400&appid={API key}\n // === INIT =============\n const init = () => {\n getWeather().then((data) => {\n console.log(data);\n setWeather(data);\n });\n };\n\n // === EVENTHANDLER =====\n\n // === XHR/FETCH ========\n const getWeather = async () => {\n try {\n const res = await fetch(\n `https://api.openweathermap.org/data/2.5/weather?lat=${LAT}&lon=${LON}&units=metric&appid=${API_KEY}`,\n );\n if (!res.ok) {\n throw Error('Fetch Error');\n }\n const data = await res.json();\n return data; // -> Promise\n } catch (error) {\n console.error(error);\n throw error;\n }\n };\n\n // === FUNCTIONS ========\n const setWeather = (data) => {\n const { temp_min: tempMin, temp_max: tempMax, temp } = data.main;\n const { speed, deg } = data.wind;\n const { main, description, icon } = data.weather[0];\n\n // https://openweathermap.org/img/wn/04d@2x.png\n DOM.weatherIcon.src = `https://openweathermap.org/img/wn/${icon}@2x.png`;\n\n DOM.figcaption.textContent = main;\n DOM.description.textContent = description;\n DOM.temp.textContent = temp;\n DOM.tempMin.textContent = tempMin;\n DOM.tempMax.textContent = tempMax;\n DOM.speed.textContent = speed;\n DOM.deg.textContent = deg;\n\n DOM.iconCompass.style.transform = `rotate(${Number(deg) - 45}deg)`;\n };\n\n init();\n})();\n"],
"mappings": ";;;AAEA,GAAC,MAAM;AAEL,UAAM,MAAM;AAAA,MACV,YAAY,SAAS,cAAc,cAAc;AAAA,MACjD,aAAa,SAAS,cAAc,kBAAkB;AAAA,MACtD,YAAY,SAAS,cAAc,YAAY;AAAA,MAC/C,aAAa,SAAS,cAAc,cAAc;AAAA,MAClD,MAAM,SAAS,cAAc,OAAO;AAAA,MACpC,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,aAAa,SAAS,cAAc,eAAe;AAAA,MACnD,OAAO,SAAS,cAAc,QAAQ;AAAA,MACtC,KAAK,SAAS,cAAc,WAAW;AAAA,IACzC;AAEA,YAAQ,IAAI,GAAG;AAGf,UAAM,UAAU;AAEhB,UAAM,MAAM;AACZ,UAAM,MAAM;AAIZ,UAAM,OAAO,MAAM;AACjB,iBAAW,EAAE,KAAK,CAAC,SAAS;AAC1B,gBAAQ,IAAI,IAAI;AAChB,mBAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH;AAKA,UAAM,aAAa,YAAY;AAC7B,UAAI;AACF,cAAM,MAAM,MAAM;AAAA,UAChB,uDAAuD,GAAG,QAAQ,GAAG,uBAAuB,OAAO;AAAA,QACrG;AACA,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,MAAM,aAAa;AAAA,QAC3B;AACA,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,eAAO;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ,MAAM,KAAK;AACnB,cAAM;AAAA,MACR;AAAA,IACF;AAGA,UAAM,aAAa,CAAC,SAAS;AAE3B,UAAI,YAAY,MAAM;AAEtB,UAAI,WAAW,cAAc,KAAK,QAAQ,CAAC,EAAE;AAC7C,UAAI,YAAY,cAAc,KAAK,QAAQ,CAAC,EAAE;AAAA,IAChD;AAEA,SAAK;AAAA,EACP,GAAG;", "mappings": ";;;AAEA,GAAC,MAAM;AAEL,UAAM,MAAM;AAAA,MACV,YAAY,SAAS,cAAc,cAAc;AAAA,MACjD,aAAa,SAAS,cAAc,kBAAkB;AAAA,MACtD,YAAY,SAAS,cAAc,YAAY;AAAA,MAC/C,aAAa,SAAS,cAAc,cAAc;AAAA,MAClD,MAAM,SAAS,cAAc,OAAO;AAAA,MACpC,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,SAAS,SAAS,cAAc,WAAW;AAAA,MAC3C,aAAa,SAAS,cAAc,eAAe;AAAA,MACnD,OAAO,SAAS,cAAc,QAAQ;AAAA,MACtC,KAAK,SAAS,cAAc,WAAW;AAAA,IACzC;AAEA,YAAQ,IAAI,GAAG;AAGf,UAAM,UAAU;AAEhB,UAAM,MAAM;AACZ,UAAM,MAAM;AAIZ,UAAM,OAAO,MAAM;AACjB,iBAAW,EAAE,KAAK,CAAC,SAAS;AAC1B,gBAAQ,IAAI,IAAI;AAChB,mBAAW,IAAI;AAAA,MACjB,CAAC;AAAA,IACH;AAKA,UAAM,aAAa,YAAY;AAC7B,UAAI;AACF,cAAM,MAAM,MAAM;AAAA,UAChB,uDAAuD,GAAG,QAAQ,GAAG,uBAAuB,OAAO;AAAA,QACrG;AACA,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,MAAM,aAAa;AAAA,QAC3B;AACA,cAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,eAAO;AAAA,MACT,SAAS,OAAO;AACd,gBAAQ,MAAM,KAAK;AACnB,cAAM;AAAA,MACR;AAAA,IACF;AAGA,UAAM,aAAa,CAAC,SAAS;AAC3B,YAAM,EAAE,UAAU,SAAS,UAAU,SAAS,KAAK,IAAI,KAAK;AAC5D,YAAM,EAAE,OAAO,IAAI,IAAI,KAAK;AAC5B,YAAM,EAAE,MAAM,aAAa,KAAK,IAAI,KAAK,QAAQ,CAAC;AAGlD,UAAI,YAAY,MAAM,qCAAqC,IAAI;AAE/D,UAAI,WAAW,cAAc;AAC7B,UAAI,YAAY,cAAc;AAC9B,UAAI,KAAK,cAAc;AACvB,UAAI,QAAQ,cAAc;AAC1B,UAAI,QAAQ,cAAc;AAC1B,UAAI,MAAM,cAAc;AACxB,UAAI,IAAI,cAAc;AAEtB,UAAI,YAAY,MAAM,YAAY,UAAU,OAAO,GAAG,IAAI,EAAE;AAAA,IAC9D;AAEA,SAAK;AAAA,EACP,GAAG;",
"names": [] "names": []
} }
@@ -53,11 +53,22 @@
// === FUNCTIONS ======== // === FUNCTIONS ========
const setWeather = (data) => { const setWeather = (data) => {
// https://openweathermap.org/img/wn/04d@2x.png const { temp_min: tempMin, temp_max: tempMax, temp } = data.main;
DOM.weatherIcon.src = `https://openweathermap.org/img/wn/04d@2x.png`; const { speed, deg } = data.wind;
const { main, description, icon } = data.weather[0];
DOM.figcaption.textContent = data.weather[0].main; // https://openweathermap.org/img/wn/04d@2x.png
DOM.description.textContent = data.weather[0].description; DOM.weatherIcon.src = `https://openweathermap.org/img/wn/${icon}@2x.png`;
DOM.figcaption.textContent = main;
DOM.description.textContent = description;
DOM.temp.textContent = temp;
DOM.tempMin.textContent = tempMin;
DOM.tempMax.textContent = tempMax;
DOM.speed.textContent = speed;
DOM.deg.textContent = deg;
DOM.iconCompass.style.transform = `rotate(${Number(deg) - 45}deg)`;
}; };
init(); init();
@@ -1,7 +1,7 @@
@use 'sass:color'; @use 'sass:color';
.weather-box { .weather-box {
background-color: #efefef; background-color: #fff;
padding: 1rem; padding: 1rem;
border-radius: 1rem; border-radius: 1rem;
font-family: $font-copy; font-family: $font-copy;
@@ -61,11 +61,13 @@
display: flex; display: flex;
text-align: center; text-align: center;
.icon-compass { .icon-compass {
transition: all 0.8s ease-out;
transition-delay: 200ms;
font-size: 48px; font-size: 48px;
color: #777; color: #777;
width: 48px; width: 48px;
height: 48px; height: 48px;
// transform: rotate(-45deg); transform: rotate(-45deg);
margin: 0 1rem 0 2rem; margin: 0 1rem 0 2rem;
} }
} }
@@ -0,0 +1,9 @@
Code,Short Description,Tagline,Quantity,Price
MUG0007,coffee mug with LCD level indicator,never again reach for the empty mug,20,49.90
MUG0013,coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling,put the smart into coffee reading,20,99.90
OFF3145,pen with pre-warmed ink (tested on the South Pole),the pen is mightier than the cold,50,29.90
COM1001,ambidextrous computer mouse,end the dictate of left and right,10,19.90
COM0404,Easter egg themed webcam for your monitor,put an Easter egg on hardware too,20,149.90
COM0001,Vulcan language vi cheatsheet,learn vi and Vulcan at the same time,3,9.90
COM1536,Klingon language emacs cheatsheet,learn emacs and Klingon at the same time,50,9.90
MOB0555,smartphone case with built-in screen,never miss a message,20,39.90
1 Code Short Description Tagline Quantity Price
2 MUG0007 coffee mug with LCD level indicator never again reach for the empty mug 20 49.90
3 MUG0013 coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling put the smart into coffee reading 20 99.90
4 OFF3145 pen with pre-warmed ink (tested on the South Pole) the pen is mightier than the cold 50 29.90
5 COM1001 ambidextrous computer mouse end the dictate of left and right 10 19.90
6 COM0404 Easter egg themed webcam for your monitor put an Easter egg on hardware too 20 149.90
7 COM0001 Vulcan language vi cheatsheet learn vi and Vulcan at the same time 3 9.90
8 COM1536 Klingon language emacs cheatsheet learn emacs and Klingon at the same time 50 9.90
9 MOB0555 smartphone case with built-in screen never miss a message 20 39.90
@@ -0,0 +1,77 @@
// const fs = require('node:fs'); // commonjs
import fs from 'node:fs'; // module - esm
import color from 'chalk';
// VARS =========
const STOCK_WARN_AMOUNT = 5;
let data = '';
try {
data = fs.readFileSync('data/products.csv', 'utf-8');
} catch (error) {
console.log(color.red(error));
// Beendet den Prozess erfolgreich (Code 0)
process.exit(0);
}
const products = data.split('\n');
const headerAr = products.shift().split(/\s*,\s*/); // => [ 'Code', 'Short Description', 'Tagline', 'Quantity', 'Price' ]
// Functions ======
const recordToHtml = (row) => {
const fields = row.split(/\s*,\s*/); // ["MUG0007", "coffee mug with LCD level indicator", "never again reach for the empty mug","20","49.90" ]
// Destructuring von fields-Array
const [code, shortDescription, tagline, quantity, price] = fields;
let html = '<li class="list-group-item">';
html += `<h2>${shortDescription}</h2>`;
html += `<p>${tagline}</p>`;
html += `<p><strong>Price:</strong> ${Number(price).toFixed(2)}</p>`;
if (quantity < STOCK_WARN_AMOUNT) {
html += `<p class="alert alert-warning">Nur noch wenige Example verfügbar! (${quantity})</p>`;
}
html += '</li>';
return html;
};
const writeHtmlDocument = (content = '') => {
const headerStr = `<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Products</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5">`;
const footerStr = `</div>
</main>
</body>
</html>`;
const htmlDocument = `${headerStr}${content}${footerStr}`;
fs.writeFile('products.html', htmlDocument, 'utf-8', (err) => {
if (err) console.log(color.red(err));
console.log(color.green('File created!'));
});
};
const listItems = products
.filter((row) => row !== '') // leere String Einträge rausfiltern
.map(recordToHtml); // Funktionsreferenz
const htmlList = `<ul class="list-group">${listItems.join('')}</ul>`;
// Output ===========
writeHtmlDocument(htmlList);
@@ -0,0 +1,27 @@
{
"name": "01_csv-to-html",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "01_csv-to-html",
"version": "1.0.0",
"dependencies": {
"chalk": "^6.0.1"
}
},
"node_modules/chalk": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
"license": "MIT",
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
}
}
}
@@ -0,0 +1,14 @@
{
"name": "01_csv-to-html",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module",
"dependencies": {
"chalk": "^6.0.1"
}
}
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Products</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5"><ul class="list-group"><li class="list-group-item"><h2>coffee mug with LCD level indicator</h2><p>never again reach for the empty mug</p><p><strong>Price:</strong> 49.90</p></li><li class="list-group-item"><h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2><p>put the smart into coffee reading</p><p><strong>Price:</strong> 99.90</p></li><li class="list-group-item"><h2>pen with pre-warmed ink (tested on the South Pole)</h2><p>the pen is mightier than the cold</p><p><strong>Price:</strong> 29.90</p></li><li class="list-group-item"><h2>ambidextrous computer mouse</h2><p>end the dictate of left and right</p><p><strong>Price:</strong> 19.90</p></li><li class="list-group-item"><h2>Easter egg themed webcam for your monitor</h2><p>put an Easter egg on hardware too</p><p><strong>Price:</strong> 149.90</p></li><li class="list-group-item"><h2>Vulcan language vi cheatsheet</h2><p>learn vi and Vulcan at the same time</p><p><strong>Price:</strong> 9.90</p><p class="alert alert-warning">Nur noch wenige Example verfügbar! (3)</p></li><li class="list-group-item"><h2>Klingon language emacs cheatsheet</h2><p>learn emacs and Klingon at the same time</p><p><strong>Price:</strong> 9.90</p></li><li class="list-group-item"><h2>smartphone case with built-in screen</h2><p>never miss a message</p><p><strong>Price:</strong> 39.90</p></li></ul></div>
</main>
</body>
</html>
@@ -0,0 +1 @@
Code,Short Description,Tagline,Quantity,Price
1 Code Short Description Tagline Quantity Price
@@ -0,0 +1,13 @@
import fs from 'node:fs';
import color from 'chalk';
// async process
fs.readFile('data/products.csv', 'UTF8', (error, data) => {
console.log(color.yellow(data)); // 2 output
});
for (let i = 0; i < 2000000000; i++) {
// be busy for a few seconds
}
console.log(color.green('ready')); // 1 output
@@ -0,0 +1,27 @@
{
"name": "02_async-vs-multithread",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "02_async-vs-multithread",
"version": "1.0.0",
"dependencies": {
"chalk": "^6.0.1"
}
},
"node_modules/chalk": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
"license": "MIT",
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
}
}
}
@@ -0,0 +1,14 @@
{
"name": "02_async-vs-multithread",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module",
"dependencies": {
"chalk": "^6.0.1"
}
}
@@ -0,0 +1 @@
hello World
@@ -0,0 +1,54 @@
import fs from 'fs'; // Modul aus der Standardbibliothek
let data;
fs.writeFileSync('hello.txt', 'hello World', 'utf8');
// fs.readFileSync(…)
// liest eine Datei ein (blockierende Variante)
data = fs.readFileSync('hello.txt', 'utf8');
console.log(data);
// fs.readFile(…)
// liest eine Datei ein (asynchrone Variante)
fs.readFile('hello.txt', 'utf8', (error, data) => {
console.log(data);
});
// fs.writeFileSync(…)
// schreibt Daten in eine Datei; bereits vorhandene Daten werden überschrieben (blockierende Variante)
fs.writeFileSync('hello.txt', data, 'utf8');
console.log(data);
// fs.writeFile(…)
// schreibt Daten in eine Datei; bereits vorhandene Daten werden überschrieben (asynchrone Variante)
fs.writeFile('hello.txt', data, 'UTF8', (error) => {
if (error) console.log('Error: ' + error);
});
// fs.statSync(…)
// ermittelt Infos zur Datei (blockierende Variante)
const stats = fs.statSync('hello.txt');
// console.log('File Stats: ', stats);
console.log('File size: ', stats.size); // => size in bytes
console.log('File birthdate: ', stats.birthtime); // => enstehungsdatum der Datei
// fs.stat(…)
// ermittelt Infos zur Datei (asynchrone Variante)
fs.stat('hello.txt', (error, stats) => console.log(stats.size)); // => size in bytes
// fs.unlinkSync(…)
// löscht eine Datei (blockierende Variante)
fs.unlinkSync('hello.txt');
fs.writeFileSync('hello.txt', 'hello World', 'utf8');
// fs.unlink(…)
// löscht eine Datei (asynchrone Variante)
// fs.unlink('hello.txt', 'utf-8', (error) => {
// if (error) console.log('Error: ' + error);
// });
@@ -0,0 +1,13 @@
{
"name": "01_fs-methoden",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module"
}
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Products</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<main>
<div class="container py-5"><ul class="list-group"><li class="list-group-item"><h2>coffee mug with LCD level indicator</h2><p>never again reach for the empty mug</p><p><strong>Price:</strong> 49.90</p></li><li class="list-group-item"><h2>coffee mug with bluetooth-connected coffee grounds scanner for automatized fortune telling</h2><p>put the smart into coffee reading</p><p><strong>Price:</strong> 99.90</p></li><li class="list-group-item"><h2>pen with pre-warmed ink (tested on the South Pole)</h2><p>the pen is mightier than the cold</p><p><strong>Price:</strong> 29.90</p></li><li class="list-group-item"><h2>ambidextrous computer mouse</h2><p>end the dictate of left and right</p><p><strong>Price:</strong> 19.90</p></li><li class="list-group-item"><h2>Easter egg themed webcam for your monitor</h2><p>put an Easter egg on hardware too</p><p><strong>Price:</strong> 149.90</p></li><li class="list-group-item"><h2>Vulcan language vi cheatsheet</h2><p>learn vi and Vulcan at the same time</p><p><strong>Price:</strong> 9.90</p><p class="alert alert-warning">Nur noch wenige Example verfügbar! (3)</p></li><li class="list-group-item"><h2>Klingon language emacs cheatsheet</h2><p>learn emacs and Klingon at the same time</p><p><strong>Price:</strong> 9.90</p></li><li class="list-group-item"><h2>smartphone case with built-in screen</h2><p>never miss a message</p><p><strong>Price:</strong> 39.90</p></li></ul></div>
</main>
</body>
</html>
@@ -0,0 +1,15 @@
import fs from 'node:fs';
import zlib from 'node:zlib';
const data = fs.readFileSync('data/products.html', 'utf-8');
const compressedData = zlib.gzipSync(data); // => <Buffer 1f 8b 08 00 00 00 00 00 00 13 9d 95 c1 8e dc 36 0c 86 ef 79 0a c6 a7 04 a8 c7 c9 6e 03 64 03 8d 51 20 d9 5e 5a b4 0b 34 2d 90 23 47 e2 58 6c 25 ca 90 ... 688 more bytes>
console.log(compressedData);
try {
fs.writeFileSync('data/products.html.gz', compressedData);
console.log('compressed file!');
} catch (error) {
console.log(error);
}
@@ -0,0 +1,11 @@
{
"name": "04_zlib",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module"
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,16 @@
import fs from 'node:fs';
import zlib from 'node:zlib';
const data = fs.readFileSync('data/products.html', 'utf-8');
const gzipCompressor = zlib.createGzip();
const inputStream = fs.createReadStream('data/products.html');
const outputStream = fs.createWriteStream('data/products.html.gz');
inputStream.on('data', (data) => {
console.log('Pakete (data chunks) werden geladen:', data.length);
// outputStream.write(zlib.gzipSync(data)) // ohne pipe-Methode - Datenchunks geschrieben
});
inputStream.pipe(gzipCompressor).pipe(outputStream);
@@ -0,0 +1,11 @@
{
"name": "04_zlib",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module"
}
@@ -0,0 +1,6 @@
import crypto from 'node:crypto';
const data = 'Ich werde verschüsselt!';
const hash = crypto.createHash('sha256').update(data).digest('hex'); // 256-bit SHA-2 hash algorithm
console.log(hash); // 59e9f3b7c10a8c5c9e099d60bebb142eaa7560b375bb41e3def6bc34708ce6ae
@@ -0,0 +1,11 @@
{
"name": "06_crypto",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "module"
}
@@ -0,0 +1,10 @@
const fs = require('node:fs'); // commonjs
if (true) {
// in code Blöcken ({..}) kann require (commonjs) verwendet werden.
const dns = require('node:dns');
dns.lookup('www.google.de', 4, (err, data) => {
if (err) console.log(err);
console.log(data); // => 142.251.208.227
});
}
@@ -0,0 +1,13 @@
import fs from 'node:fs'; // module - esm Schreibweise
if (true) {
// import STATEMENT kann NICHT in Konditionen oder Code-Blöcken ({}) verwendet werden.
// import dns from 'node:dns'; // An import declaration can only be used at the top level of a module.
// seit 2020 import "dynamic" Funktion innerhalb von Code-Blöcken ({}) verwendet werden.
import('node:dns').then((dns) => {
dns.lookup('www.google.de', 4, (err, data) => {
if (err) console.log(err);
console.log(data); // => 142.251.208.227
});
});
}
@@ -0,0 +1,902 @@
{
"name": "08_npm-befehle",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "08_npm-befehle",
"version": "1.0.0",
"dependencies": {
"chalk": "^6.0.1",
"express": "^5.2.1"
}
},
"node_modules/accepts": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
"integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
"license": "MIT",
"dependencies": {
"mime-types": "^3.0.0",
"negotiator": "^1.0.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/body-parser": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
"integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
"license": "MIT",
"dependencies": {
"bytes": "^3.1.2",
"content-type": "^2.0.0",
"debug": "^4.4.3",
"http-errors": "^2.0.1",
"iconv-lite": "^0.7.2",
"on-finished": "^2.4.1",
"qs": "^6.15.2",
"raw-body": "^3.0.2",
"type-is": "^2.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/body-parser/node_modules/content-type": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/chalk": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-6.0.1.tgz",
"integrity": "sha512-/Ce6KNm3vIbWdMlNna6RVIZ/ICQxnJxCicet5LBKK9ZffBkqzDw0xh9EiKSljdRtiIQ1S1z4YgcscUUGzNCWrA==",
"license": "MIT",
"engines": {
"node": ">=22"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/content-disposition": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
"integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie": {
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
"integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
"license": "MIT",
"engines": {
"node": ">=6.6.0"
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
"integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
"license": "MIT",
"dependencies": {
"accepts": "^2.0.0",
"body-parser": "^2.2.1",
"content-disposition": "^1.0.0",
"content-type": "^1.0.5",
"cookie": "^0.7.1",
"cookie-signature": "^1.2.1",
"debug": "^4.4.0",
"depd": "^2.0.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"finalhandler": "^2.1.0",
"fresh": "^2.0.0",
"http-errors": "^2.0.0",
"merge-descriptors": "^2.0.0",
"mime-types": "^3.0.0",
"on-finished": "^2.4.1",
"once": "^1.4.0",
"parseurl": "^1.3.3",
"proxy-addr": "^2.0.7",
"qs": "^6.14.0",
"range-parser": "^1.2.1",
"router": "^2.2.0",
"send": "^1.1.0",
"serve-static": "^2.2.0",
"statuses": "^2.0.1",
"type-is": "^2.0.1",
"vary": "^1.1.2"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/finalhandler": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"on-finished": "^2.4.1",
"parseurl": "^1.3.3",
"statuses": "^2.0.1"
},
"engines": {
"node": ">= 18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-errors": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
"license": "MIT",
"dependencies": {
"depd": "~2.0.0",
"inherits": "~2.0.4",
"setprototypeof": "~1.2.0",
"statuses": "~2.0.2",
"toidentifier": "~1.0.1"
},
"engines": {
"node": ">= 0.8"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/iconv-lite": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
"integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/is-promise": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
"license": "MIT"
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/media-typer": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz",
"integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/merge-descriptors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
"integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/mime-db": {
"version": "1.54.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
"license": "MIT",
"dependencies": {
"mime-db": "^1.54.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/negotiator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz",
"integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==",
"license": "MIT",
"dependencies": {
"content-type": "^2.1.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/negotiator/node_modules/content-type": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-to-regexp": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/proxy-addr": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.8.tgz",
"integrity": "sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==",
"license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
"node": ">= 0.10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/qs": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz",
"integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==",
"license": "BSD-3-Clause",
"dependencies": {
"es-define-property": "^1.0.1",
"side-channel": "^1.1.1"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/range-parser": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz",
"integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/raw-body": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
"integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
"license": "MIT",
"dependencies": {
"bytes": "~3.1.2",
"http-errors": "~2.0.1",
"iconv-lite": "~0.7.0",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/router": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
"integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"depd": "^2.0.0",
"is-promise": "^4.0.0",
"parseurl": "^1.3.3",
"path-to-regexp": "^8.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/send": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
"integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.4.3",
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"etag": "^1.8.1",
"fresh": "^2.0.0",
"http-errors": "^2.0.1",
"mime-types": "^3.0.2",
"ms": "^2.1.3",
"on-finished": "^2.4.1",
"range-parser": "^1.2.1",
"statuses": "^2.0.2"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/serve-static": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
"integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
"license": "MIT",
"dependencies": {
"encodeurl": "^2.0.0",
"escape-html": "^1.0.3",
"parseurl": "^1.3.3",
"send": "^1.2.0"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
"node_modules/side-channel": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
"integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.4",
"side-channel-list": "^1.0.1",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz",
"integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.4"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/statuses": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"node_modules/type-is": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
"license": "MIT",
"dependencies": {
"content-type": "^2.0.0",
"media-typer": "^1.1.0",
"mime-types": "^3.0.0"
},
"engines": {
"node": ">= 18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/type-is/node_modules/content-type": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
}
}
}
@@ -0,0 +1,15 @@
{
"name": "08_npm-befehle",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"type": "commonjs",
"dependencies": {
"chalk": "^6.0.1",
"express": "^5.2.1"
}
}
+15
View File
@@ -0,0 +1,15 @@
{
"recommendations": [
"kamikillerto.vscode-colorize",
"sleistner.vscode-fileutils",
"bierner.github-markdown-preview",
"bradgashler.htmltagwrap",
"zhuangtongfa.material-theme",
"techer.open-in-browser",
"esbenp.prettier-vscode",
"pdconsec.vscode-print",
"vscode-icons-team.vscode-icons",
"formulahendry.auto-rename-tag",
"tomoki1207.pdf"
]
}
+332
View File
@@ -0,0 +1,332 @@
/* @theme marp-theme */
@charset "UTF-8";
/*!
* Marp Dracula theme.
* @theme marp-theme
* @author Daniel Nicolas Gisolfi & modified by Philippe Botzek
*
* @auto-scaling true
* @size 4:3 960px 720px
* @size 16:9 1280px 720px
*/
@import url('https://fonts.googleapis.com/css?family=Lato:400,900|IBM+Plex+Sans:400,700');
:root {
--dracula-background: #282a36;
--dracula-current-line: #44475a;
--dracula-foreground: #f8f8f2;
--dracula-comment: #6272a4;
--dracula-cyan: #8be9fd;
--dracula-green: #50fa7b;
--dracula-orange: #ffb86c;
--dracula-pink: #ff79c6;
--dracula-purple: #bd93f9;
--dracula-red: #ff5555;
--dracula-yellow: #f1fa8c;
}
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: var(--dracula-background);
}
/* Dracula Foreground */
.hljs,
.hljs-subst,
.hljs-typing,
.hljs-variable,
.hljs-template-variable {
color: var(--dracula-foreground);
}
/* Dracula Comment */
.hljs-comment,
.hljs-quote,
.hljs-deletion {
color: var(--dracula-comment);
}
/* Dracula Cyan */
.hljs-meta .hljs-doctag,
.hljs-built_in,
.hljs-selector-tag,
.hljs-section,
.hljs-link,
.hljs-class {
color: var(--dracula-cyan);
}
/* Dracula Green */
.hljs-title {
color: var(--dracula-green);
}
/* Dracula Orange */
.hljs-params {
color: var(--dracula-orange);
}
/* Dracula Pink */
.hljs-keyword {
color: var(--dracula-pink);
}
/* Dracula Purple */
.hljs-literal,
.hljs-number {
color: var(--dracula-purple);
}
/* Dracula Red */
.hljs-regexp {
color: var(--dracula-red);
}
/* Dracula Yellow */
.hljs-string,
.hljs-name,
.hljs-type,
.hljs-attr,
.hljs-symbol,
.hljs-bullet,
.hljs-addition,
.hljs-template-tag {
color: var(--dracula-yellow);
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-title,
.hljs-section,
.hljs-doctag,
.hljs-type,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-params,
.hljs-emphasis {
font-style: italic;
}
svg[data-marp-fitting='svg'] {
max-height: 580px;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0.5em 0 0 0;
color: var(--dracula-pink);
}
h1 strong,
h2 strong,
h3 strong,
h4 strong,
h5 strong,
h6 strong {
font-weight: inherit;
}
h1 {
font-size: 1.8em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.3em;
}
h4 {
font-size: 1.1em;
}
h5 {
font-size: 1em;
}
h6 {
font-size: 0.9em;
}
p,
blockquote {
margin: 1em 0 0 0;
}
ul > li,
ol > li {
margin: 0.3em 0 0 0;
color: var(--dracula-cyan);
}
ul > li > p,
ol > li > p {
margin: 0.6em 0 0 0;
}
code {
display: inline-block;
font-family: 'IBM Plex Mono', monospace;
font-size: 0.8em;
letter-spacing: 0;
margin: -0.1em 0.15em;
padding: 0.1em 0.2em;
vertical-align: baseline;
color: var(--dracula-green);
}
pre {
display: block;
margin: 1em 0 0 0;
min-height: 1em;
overflow: visible;
}
pre code {
box-sizing: border-box;
margin: 0;
min-width: 100%;
padding: 0.5em;
font-size: 0.7em;
}
pre code svg[data-marp-fitting='svg'] {
max-height: calc(580px - 1em);
}
blockquote {
margin: 1em 0 0 0;
padding: 0 1em;
position: relative;
color: var(--dracula-orange);
}
blockquote::after,
blockquote::before {
content: '“';
display: block;
font-family: 'Times New Roman', serif;
font-weight: bold;
position: absolute;
color: var(--dracula-green);
}
blockquote::before {
top: 0;
left: 0;
}
blockquote::after {
right: 0;
bottom: 0;
transform: rotate(180deg);
}
blockquote > *:first-child {
margin-top: 0;
}
mark {
background: transparent;
}
table {
border-spacing: 0;
border-collapse: collapse;
margin: 1em 0 0 0;
}
table th,
table td {
padding: 0.2em 0.4em;
border-width: 1px;
border-style: solid;
}
section {
font-size: 35px;
font-family: 'IBM Plex Sans';
line-height: 1.35;
letter-spacing: 1.25px;
padding: 70px;
color: var(--dracula-foreground);
background-color: var(--dracula-background);
}
section > *:first-child,
section > header:first-child + * {
margin-top: 0;
}
section a,
section mark {
color: var(--dracula-red);
}
section code {
background: var(--dracula-current-line);
color: var(--dracula-current-green);
}
section h1 strong,
section h2 strong,
section h3 strong,
section h4 strong,
section h5 strong,
section h6 strong {
color: var(--dracula-current-line);
}
section pre > code {
background: var(--dracula-current-line);
}
section header,
section footer,
section section::after,
section blockquote::before,
section blockquote::after {
color: var(--dracula-comment);
}
section table th,
section table td {
border-color: var(--dracula-current-line);
}
section table thead th {
background: var(--dracula-current-line);
color: var(--dracula-yellow);
}
section table tbody > tr:nth-child(even) td,
section table tbody > tr:nth-child(even) th {
background: var(--dracula-current-line);
}
header,
footer,
section::after {
box-sizing: border-box;
font-size: 66%;
height: 70px;
line-height: 50px;
overflow: hidden;
padding: 10px 25px;
position: absolute;
color: var(--dracula-comment);
}
header {
left: 0;
right: 0;
top: 0;
}
footer {
left: 0;
right: 0;
bottom: 0;
}
section::after {
right: 0;
bottom: 0;
font-size: 80%;
}
+33
View File
@@ -0,0 +1,33 @@
{
"terminal.explorerKind": "external",
"terminal.external.osxExec": "iTerm.app",
"terminal.external.windowsExec": "wt.exe",
"workbench.iconTheme": "vscode-icons",
"workbench.colorTheme": "One Dark Pro",
"prettier.printWidth": 120,
"prettier.singleQuote": true,
"editor.hover.enabled": "on",
"editor.wordWrap": "on",
"explorer.confirmDelete": false,
"explorer.confirmDragAndDrop": false,
"editor.quickSuggestionsDelay": 600,
"editor.tabSize": 2,
"editor.formatOnSave": true,
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"ejs": "html"
},
"html.format.unformatted": "wbr,%",
"files.associations": {
"*.ejs": "html"
},
"editor.fontFamily": "'MesloLGS NF', Hack, Consolas, 'Courier New', monospace",
"oneDarkPro.markdownStyle": false,
"explorer.compactFolders": false,
"workbench.editor.labelFormat": "short",
"editor.hover.delay": 800,
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": "active",
"markdown.marp.themes": ["./.vscode/marp-theme.css"],
"markdown-preview-github-styles.colorTheme": "light"
}
+73
View File
@@ -0,0 +1,73 @@
{
"Output HTML Element": {
"scope": "html",
"prefix": "output",
"body": ["<div class=\"output alert alert-secondary my-3\"></div>"],
"description": "generate a div Element with output alert and alert secondary class"
},
"Bootstrap html": {
"scope": "html",
"prefix": "!bs",
"body": [
"<!DOCTYPE html>",
"<html lang=\"de\">",
"\t<head>",
"\t\t<meta charset=\"UTF-8\" />",
"\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />",
"\t\t<title>$0</title>",
"\t\t<link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css\" rel=\"stylesheet\" />",
"\t</head>",
"\t<body>",
"\t\t<main>",
"\t\t\t<div class=\"container py-5\">",
"\t\t\t\t<h1>$0</h1>",
"\t\t\t</div>",
"\t\t</main>",
"\t\t<script>",
"\t\t\t'use strict';",
"\t\t\t",
"\t\t</script>",
"\t</body>",
"</html>"
],
"description": "Generate HTML with Bootstrap CDN and script-tag"
},
"$ und $$ helper function": {
"scope": "javascript,typescript",
"prefix": "$$$",
"body": [
"const $ = (qs) => document.querySelector(qs);",
"const $$ = (qs) => Array.from(document.querySelectorAll(qs));"
],
"description": "$ and $$ shorthand helper function"
},
"JavaScript Dateivorlage": {
"scope": "javascript,typescript",
"prefix": "vjs",
"body": [
"'use strict';",
"",
"(() => {",
"",
"\t// === DOM & VARS =======",
"\tconst DOM = {};",
"",
"\t// === INIT =============",
"\tconst init = () => {",
"",
"\t}",
"",
"\t// === EVENTHANDLER =====",
"",
"\t// === XHR/FETCH ========",
"",
"\t// === FUNCTIONS ========",
"",
"\tinit();",
"",
"})();"
],
"description": "JavaScript Dateivorlage"
}
}
+505
View File
@@ -0,0 +1,505 @@
---
marp: true
theme: default
---
## JavaScript Grundlagen Teil 1.
---
#### Tag 01
**Inhalt:**
- Vorstellungsrunde
- Einrichtung der IDE
- Tools für die Webentwicklung (Emmet, Markdown, VS-Code, Co-Pilot)
- Arbeiten mit VSCode
- Konsolenausgaben mit `console.log()`
**Übungen:**
- Übungen: 1 - 3, Content Factory
---
#### Tag 02
**Inhalt:**
- Dialogfenster in JS `prompt()`, `alert()`, `confirm()`
- Kommentare in JS
- Rechnen in JS
- Datentyp String, Number, Boolean
- literal und typeof
- Prioritätsreihenfolge
**Übungen:**
Übung 3 - 6 (Content-Factory bis 1.3.3)
---
#### Tag 03
**Inhalt:**
- Variablen und Konstanten in JS
- Zusammengesetzte Zuweisungsoperatoren
- Increment & Decrement
- Strings verketten mit +
- Escape-Notation
- Implizite und explizite Typkonvertierung
**Übungen:**
Übung 7 - 12
---
#### Tag 04
**Inhalt:**
- Escape-Notation
- Implizite und explizite Typkonvertierung
- NaN - Paradoxon
- Math Object
- Number.toFixed()
- isNaN
- Lexikographische Vergleiche
**Übungen:**
Übung 14 - 18
---
#### Tag 05
**Inhalt:**
- Repetition der Inhalte
- Relationale Operatoren & Vergleichoperatoren
- **Exkurs: Webseitenstruktur + SASS HTML-Formularfelder**
- 1:1 Meeting
**Übungen:**
Übung Kontaktformular mit HTML und BS,
Lektion 10 erarbeiten
---
#### Tag 06
**Inhalt:**
- **Exkurs: HTML Formularfelder mit BS**
- if else Verzweigung und ternärer Operator
**Übungen:**
Übung 19 - 21 + Kontaktformular
---
#### Tag 07
**Inhalt:**
- logische Operatoren UND und ODER
- unärer Operator (!)
- String Methoden
- Funktionen in JS + mit Übergabeparameter + mit Rückgabewerten
**Übungen:**
Übung 22 - 31
---
#### Tag 08
**Inhalt:**
- Funktionen mit Rückgabewerten
- Guards, Restparameter, Defaulparameter
- Array Part 1
**Übungen:**
Übung 32 - 38
---
#### Tag 09
**Inhalt:**
- Array Methoden toSorted, toReversed, toSpliced
- toSorted, toReversed
- Array sort mit "compare function"
- Array: Higher Order Funktionen Part (sort map, forEach, reduce, some, every)
**Übungen:**
Übung 39 - 45 + optionale Übung
---
#### Tag 10
**Inhalt:**
- Array.find und Array.findIndex
- Alle Array Higher Order Funktionen im Überblick
- local scoping
- Git SCM und Windows Terminal einrichten
**Übungen:**
Übung 46 - 48
---
## JavaScript für Fortgeschrittene
---
#### Tag 11
**Inhalt:**
- **Exkurs: Schleifen**
- Einführung in JS für Fortgeschrittene
- Objekte in JS
**Übungen:**
Projektarbeit
Abschlussquiz - JS Grundlagen
---
#### Tag 12
**Inhalt:**
- Destructuring von Objekten und Arrays
- Rekursion
**Übungen:**
Übung 01 - 09
---
#### Tag 13
**Inhalt:**
- Promises
- Callback-Hell
- Promise Aufbau
- Promise in Funktionen
- File System von Node
- commonjs vs esm
**Übungen:**
Übung 10 - 11
---
#### Tag 14
**Inhalt:**
- util promisify
- Promise.all()
- async await
- Mehrdimensionale Arrays
- Chess-Beispiel
**Übungen:**
Übung 12 - 19
---
#### Tag 15
**Inhalt:**
- Wiederholung der Inhalte
- Arbeiten mit Fetch API
- **Exkurs: Switch Case Abfragen**
- **Exkurs: Statische Webseite mit Sass und HTML**
- **Exkurs: Versionierung mit Github Part (SSH)**
- 1:1 Meeting
**Übungen:**
Übung 20 - 24
---
#### Tag 15
**Inhalt:**
- Wiederholung der Inhalte
- Promise.all()
- **Exkurs: Switch Case Abfragen**
- **Exkurs: Statische Webseite mit Sass und HTML**
- 1:1 Meeting
**Übungen:**
Übung 20 - 24
---
#### Tag 16
**Inhalt:**
- **Exkurs: Statische Webseite mit Sass und HTML Part II**
- Node Module: HTTP-Server, npm-run-all und SVGO
**Übungen:**
Projektarbeit + Wetter API Key besorgen
---
#### Tag 17
**Inhalt:**
- XML-HttpRequest und AJAX mit jQuery
- Node Module für die Projekt-Entwicklungsumgebung
- Wetter API auslesen
- fetch in der Praxis: Joke API auslesen
- Was ist Node.js? (Wiederholung)
**Übungen:**
Projektarbeit
Übungen Public API auslesen
---
#### Tag 18
**Inhalt:**
- Node Standardbib (fs, zlib (stream), Crypto)
- Import vs. require (Teil II)
- NPM Befehle
- Abschluss von JS für Fortgeschrittene
- Projektvorstellung 1 + 2 JS Advanced
**Übungen:**
Übungen 25 - 31
---
# JavaScript und das Document Object Model (DOM)
---
#### Tag 19
- Einführung in JS DOM
- DOM Selection (querySelector, querySelectorAll, $ & $$ Helper)
- CSS Selektoren
- Typ-, Attribut-, Kombinator- und Pseudoklassen - Selektoren
**Übungen:**
Übungen 01 - 05
---
#### Tag 20
**Inhalt:**
- Chat Gestaltung (DOMTokenList Objekt)
- Defer & Async
- JS Dateien auslagern
- Optimierung von Projektstruktur
- **Exkurs: Projektstruktur mit Gulp**
**Übungen:**
Übung 06 - 07
---
#### Tag 21
**Inhalt:**
- **Exkurs: Projektstruktur mit Gulp Part II**
- Events in JS MouseEvent, KeyboardEvent
- Projekt: Newsboard
**Übungen:**
Übung 08 - 9
---
#### Tag 22
**Inhalt:**
- HTML Element Progress
- IDL-Attribut vs. Content-Attribut
- HTML Attribute mit boolescher Zuweisung
- Tooltip: HTML erweitern mit Data-Attribut
- Dataset Attribut, DOMStringMap Objekt
- getComputedStyle, Attribute mit boolscher Zuweisung
**Übungen:**
Übung 10 - 14
---
#### Tag 23
**Inhalt:**
- DOM Creation - Elemente erstellen
- createElement() & appendChild()
- Projekt: Produktmanager Part I
- DOM Creation Befehle
- Entfernen von Elementen
**Übungen:**
Übung 15 - 17
**Projektarbeit / Content Factory**
---
#### Tag 24
**Inhalt:**
- Import von Modulen in JS (Browserseitig)
- Separation of Concerns
- Projekt: Produktmanager final
- DOM Traversal Befehle & alle DOM Bereiche
- insertBefore(), appendChild(), append(), prepend(), before(), after()
- Refactoring von Produktmanager mit Template
- JS DOM Projektvorstellung
**Übungen:**
Übung 18 + optionale Übungen
**Projektarbeit / Content Factory**
---
#### Tag 25
**Inhalt:**
- **Exkurs: Weitere Events: Drag and Drop**
- **Rest API erstellen mit Express**
- **Exkurs: DOM Inhalte über REST API mit Express Part I**
- CRUD - Create - (Read) - Update - Delete
- **Routing in JS**
- Abschlussquiz JS DOM
- **1:1 Meeting**
**Übungen:**
Projekte
---
## BROWSER API
---
#### Tag 26
**Inhalt:**
- **Exkurs: DOM Inhalte über mit REST API Express**
- **Erweiterung Frontend um REST API**
- CRUD - (Create - Read) - Update - Delete
- BREAD - Browse - Read - Edit - Add - Delete
- Verwendung von Modulen (Modal von BS, Toastify, Splide)
**Übungen**
Projekte & optionale Übungen
---
#### Tag 27
- **Exkurs: Vite vs Gulp**
- **SASS 7 on 1 mit Bootstrap 6**
- **Projektfinalisierung Express + REST API**
- Einführung in Typescript
---
### Tag 28
**Inhalt:**
- Typescript Grundlagen
- Typescript Annotationen
- Typescript "more Types"
**Übungen:**
Übungen 1 - 5
---
### Tag 29
**Inhalt:**
- Typescript Annotationen
- Primitive Types, Object, Union Types
- type statement vs interface
- Type Assertion with as and <>
- Typescript "more Types"
**Übungen:**
Übungen 4 - 9
---
### Tag 30
**Inhalt:**
- Typescript "more Types"
- Interface, as statement, literale
- Typescript Narrowing with Guards
- truthiness, equality, in-operator, type-predicate
- TS Funktionen und Objekte
**Übungen:**
Übungen 10 - 19
+91
View File
@@ -0,0 +1,91 @@
# Velinkungsproblem von globalen Modulen
Bei **nvm-windows** liegt das Problem an einem bekannten Mechanismus:
`nvm-windows` verwaltet Node-Versionen über einen **Symlink** (standardmäßig `C:\Program Files\nodejs`). Dieser Symlink zeigt dynamisch auf die gerade aktive Node-Version unter `%APPDATA%\nvm\v<version>`.
Wenn du `npm install -g <package>` ausführst, gibt es zwei typische Szenarien, warum das Binary nicht mehr im `PATH` landet:
1. **Ein abweichendes oder altes globales `prefix` in der `.npmrc`:** Wenn dort noch ein hartkodierter Pfad (wie `%APPDATA%\npm`) hinterlegt ist, legt npm die `.cmd`-Dateien dort ab, aber nvm-windows bindet diesen Pfad **nicht** in den `PATH` ein – nvm erwartet globale Pakete direkt im Symlink-Verzeichnis der jeweiligen Node-Version.
2. **Fehlende Berechtigungen im Node-Symlink:** Liegt Node unter `C:\Program Files\nodejs`, kann npm ohne Admin-Rechte dort keine `.cmd`-Dateien anlegen und weicht stillschweigend aus.
---
### Schritt 1: Prüfen, wo npm globale Pakete aktuell ablegt
Führe in der PowerShell aus:
```powershell
npm config get prefix
```
* **Fall A (Standard bei nvm-windows):** Der Pfad zeigt auf das aktive Symlink-Verzeichnis (z. B. `C:\Program Files\nodejs`). Hier müssten die `.cmd`-Dateien liegen.
* **Fall B (Häufige Ursache):** Der Pfad zeigt auf `C:\Users\<Name>\AppData\Roaming\npm`. In diesem Fall findet Windows die Befehle nicht, weil dieser Ordner bei nvm-windows **nicht** im `PATH` steht.
---
### Lösungsweg 1: Den dedizierten npm-Ordner nutzen (Empfohlen & Best Practice)
Damit globale Pakete auch bei einem Node-Versionswechsel über `nvm use` erhalten bleiben und keine Admin-Rechte im Programmverzeichnis nötig sind, bindet man den globalen npm-Pfad fest ein.
1. **Globales Prefix in npm festlegen:**
```powershell
npm config set prefix "$env:APPDATA\npm"
```
2. **Diesen Ordner dauerhaft in den Benutzer-`PATH` eintragen:**
```powershell
[Environment]::SetEnvironmentVariable(
"Path",
[Environment]::GetEnvironmentVariable("Path", "User") + ";$env:APPDATA\npm",
"User"
)
```
3. **Paket nochmals global installieren:**
```powershell
npm install -g gulp-cli
```
4. **Terminal neu starten** (Windows Terminal / PowerShell schließen und neu öffnen), danach testen:
```powershell
gulp -v
```
---
### Lösungsweg 2: Den nvm-Standard wiederherstellen
Falls du möchtest, dass nvm-windows globale Pakete strikt pro Node-Version im jeweiligen Versionsordner verwaltet:
1. **Globales Prefix zurücksetzen:**
```powershell
npm config delete prefix
```
2. **Prüfen, ob der nvm-Symlink im `PATH` vorhanden ist:**
```powershell
$env:PATH -split ';' | Select-String "nodejs"
```
Hier muss der nvm-Symlink (`C:\Program Files\nodejs` oder dein benutzerdefinierter Pfad) auftauchen.
3. **Installieren:**
```powershell
npm install -g gulp-cli
```
*(Hinweis: Falls eine Fehlermeldung bezüglich `EPERM` oder fehlender Schreibrechte auftaucht, die Konsole einmalig als Administrator ausführen oder Lösungsweg 1 wählen).*
Binary file not shown.
+97
View File
@@ -0,0 +1,97 @@
# Teams über git-bash
Hier ist die schrittweise Anleitung, wie du das Skript ablegst, ausführst und bei Bedarf bei jedem Login automatisch starten lässt.
1. **Speicherort wählen:** Persistentes Verzeichnis.
Da das Notebook regelmäßig neu aufgesetzt wird, muss das Skript an einem Ort liegen, der nicht gelöscht wird (z. B. auf einem USB-Stick, Netzlaufwerk oder in einem synchronisierten Ordner).
Falls dein lokales Benutzerverzeichnis überlebt, erstelle dort einen Skript-Ordner:
```bash
mkdir -p "$HOME/bin"
```
*Erfolgsprüfung:* Führe `ls -ld "$HOME/bin"` in der Git Bash aus. Das Verzeichnis wird ohne Fehler gelistet.
2. **Skriptdatei anlegen:** teams-link-fix.sh.
Erstelle die Datei `$HOME/bin/teams-link-fix.sh` und füge den folgenden Inhalt ein:
```bash
#!/usr/bin/env bash
set -e
echo "==> Prüfe Standardbrowser für HTTP..."
HTTP_PROGID=$(MSYS_NO_PATHCONV=1 reg.exe query \
"HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" \
/v "ProgId" 2>/dev/null | tr -d '\r' | awk '/ProgId/ {print $NF}')
if [[ "$HTTP_PROGID" =~ [Ff]irefox ]]; then
echo "✔ Firefox ist als Standardbrowser gesetzt ($HTTP_PROGID)."
else
echo "⚠ Firefox ist aktuell NICHT der Standardbrowser (aktuell: '${HTTP_PROGID:-Unbekannt}')."
echo "==> Versuche Firefox als Standardbrowser anzutriggern..."
FF_BIN=""
for candidate in \
"/c/Program Files/Mozilla Firefox/firefox.exe" \
"/c/Program Files (x86)/Mozilla Firefox/firefox.exe" \
"$LOCALAPPDATA/Mozilla Firefox/firefox.exe"; do
if [ -f "$candidate" ]; then
FF_BIN="$candidate"
break
fi
done
if [ -n "$FF_BIN" ]; then
"$FF_BIN" -setDefaultBrowser >/dev/null 2>&1 || true
fi
fi
echo "==> Setze Teams Link-Handler auf Standardbrowser..."
MSYS_NO_PATHCONV=1 reg.exe add "HKCU\Software\Microsoft\Office\16.0\Common\Links" \
/v "BrowserSelection" \
/t REG_DWORD \
/d 0 \
/f >/dev/null
echo "✔ Registry aktualisiert (BrowserSelection = 0)."
echo "==> Starte Teams neu..."
taskkill.exe //F //IM ms-teams.exe 2>/dev/null || true
taskkill.exe //F //IM Teams.exe 2>/dev/null || true
sleep 1
explorer.exe 'shell:AppsFolder\MSTeams_8wekyb3d8bbwe!MSTeams'
echo "✔ Fertig!"
```
*Erfolgsprüfung:* Mache das Skript ausführbar mit `chmod +x "$HOME/bin/teams-link-fix.sh"`.
3. **Skript manuell testen:** Git Bash.
Führe das Skript einmal direkt aus, um zu prüfen, ob die Registry ohne Fehlermeldung beschrieben wird:
```bash
~/bin/teams-link-fix.sh
```
*Erfolgsprüfung:* Die Ausgabe endet mit `✔ Fertig!` und Teams startet neu. Ein Klick auf einen Web-Link in einem Teams-Chat öffnet sich direkt in Firefox statt Microsoft Edge.
4. **Optional: Autostart nach täglichem Re-Image:** Windows Autostart.
Wenn du nach dem Neuaufsetzen nicht jedes Mal die Bash öffnen möchtest, lege eine kleine Starter-Verknüpfung im Windows-Autostart-Ordner an:
1. Drücke `Win + R`, tippe `shell:startup` ein und drücke **Enter**.
2. Erstelle in diesem Ordner eine Textdatei namens `teams-fix.cmd` mit folgendem Inhalt (Pfad ggf. anpassen):
```bat
@echo off
"C:\Program Files\Git\bin\bash.exe" -c "~/bin/teams-link-fix.sh"
```
*Erfolgsprüfung:* Melde dich ab und wieder an. Das Konsolenfenster öffnet sich kurz und schließt sich nach erfolgreicher Ausführung automatisch.
Binary file not shown.
@@ -0,0 +1,41 @@
## Optionale Übungsaufgabe 1: Responsive Navigation mit Hamburger-Menü
### 1. HTML-Struktur & Icon-Vorbereitung
Erweitere die bestehende Navigationsstruktur im Projet `webseite-gulp` um das notwendige Markup für einen Menü-Toggle.
1. **Hamburger-Icon-Markup einfügen:** Füge innerhalb Deines `<nav>`-Elements das HTML für den Menü-Toggle ein.
- Du kannst hierfür die animierten Icons von [jonsuh.com/hamburgers/](https://jonsuh.com/hamburgers/) verwenden.
2. **Zustandsklasse definieren:** Überlege Dir eine **Kontrollklasse** (z.B. `nav-open` oder `is-active`), die Du später per JavaScript auf das `<body>`-Tag oder das `<nav>`-Element setzt, um den **geöffneten Zustand** zu signalisieren.
### 2. CSS-Styling & Media Query (Mobile First)
Stelle sicher, dass die Navigation standardmäßig für die mobile Ansicht funktioniert, und passe sie dann für größere Bildschirme an.
1. **Mobile Standard (bis $575\text{px}$):**
- Die **Hauptmenüpunkte** müssen standardmäßig **versteckt** sein (`display: none;` oder per `transform` aus dem Sichtfeld geschoben).
- Das **Hamburger-Icon** muss in dieser Ansicht **sichtbar** sein.
- Definiere die **Darstellung des geöffneten Menüs** (mithilfe Deiner Zustandsklasse, z.B. `.nav-open .menu-list`). Gestalte es als nutzerfreundliches Fullscreen-Overlay oder Sidebar für mobile Geräte.
2. **Desktop-Übergang (ab $576\text{px}$):**
- Füge die notwendige **Media Query** hinzu:
```css
@media (min-width: 576px) {
/* ... hier die Desktop-Regeln ... */
}
```
- Innerhalb dieser Media Query:
- Mache die **Hauptmenüpunkte dauerhaft sichtbar** und ordne sie im Desktop-Layout an.
- Blende das **Hamburger-Icon aus** (`display: none;`).
---
### 3. JavaScript-Interaktivität (Menü-Toggle)
Implementiere die Logik, die das Umschalten des Menüzustands steuert, wenn das Icon geklickt wird.
1. **Event-Listener:** Füge dem **Hamburger-Icon** einen `click`-Event-Listener hinzu.
2. **Klasse togglen:** Im Click-Handler **togglet** Du die **Zustandsklasse** (`nav-open` oder `is-active`) auf dem Element (z.B. dem `<body>` oder `<nav>`), das Du im CSS zur Steuerung verwendest. Ein Klick öffnet das Menü, der erneute Klick schließt es. Vergesse dabei nicht dem Menü Icon die passende Klasse zum hinzufügen des Effekts zu vergeben.
@@ -0,0 +1,24 @@
# Optionale Übungen
## 1. Tooltip als Modul verwenden
Intergriere das Plugin [`floating-ui`](https://floating-ui.com/)
in die [Webseite](../../unterricht/tag21/03_website-gulp-js/index.html) .
## 2. Integration eines weiteren Moduls
- Intergriere ein weiteres Modul deiner Wahl in die Webseite.
## 3. Formularvalidierung als Modul
Erstelle ein Modul für die Validierung von einem Formular (`FormValidator`) mit folgenden Feldern
- Vor- und Nachname
- E-Mail
- Adresse bestehend aus:
- Strasse, Hausnummer
- PLZ, Ort
- Land
- Nachricht
Die Validierung soll direkt während (`input`) oder nach der Eingabe (`blur`) der Felder stattfinden. Die Verwendung von Validierungsmodulen wie `validator` dürfen dabei verwenden werden.
@@ -0,0 +1,368 @@
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
/* ---------------- CSS-Reset ------------------- */
html,
body,
a,
div,
h1,
h2,
h3,
h4,
h5,
h6,
span,
p,
img,
strong,
ul,
li,
table,
th,
td,
tr {
margin: 0px;
padding: 0px;
border: 0px none;
font-weight: normal;
font-style: inherit;
font-family: inherit;
font-variant: inherit;
text-decoration: none;
table-layout: inherit;
}
/* ---------------- Body / HTML ------------------- */
html {
font-size: 100%;
background-color: #fffef7;
}
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 1.2em;
font-weight: normal;
color: black;
margin: 0rem auto 2rem auto;
}
/* ---------------- layout ------------------- */
header {
background: url(../img/js_header.png) left top no-repeat transparent;
background-size: cover;
height: 250px;
min-width: 850px;
}
header:after {
content: ' ';
display: block;
height: 250px;
background: rgba(255, 254, 247, 0);
background: -moz-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -webkit-gradient(
left top,
left bottom,
color-stop(0%, rgba(255, 254, 247, 0)),
color-stop(22%, rgba(255, 254, 247, 0.55)),
color-stop(42%, rgba(255, 254, 247, 0.7)),
color-stop(43%, rgba(255, 254, 247, 0.71)),
color-stop(61%, rgba(255, 254, 247, 0.78)),
color-stop(75%, rgba(255, 254, 247, 0.92)),
color-stop(87%, rgba(255, 254, 247, 1)),
color-stop(100%, rgba(255, 254, 247, 1))
);
background: -webkit-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -o-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: -ms-linear-gradient(
top,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
background: linear-gradient(
to bottom,
rgba(255, 254, 247, 0) 0%,
rgba(255, 254, 247, 0.55) 22%,
rgba(255, 254, 247, 0.7) 42%,
rgba(255, 254, 247, 0.71) 43%,
rgba(255, 254, 247, 0.78) 61%,
rgba(255, 254, 247, 0.92) 75%,
rgba(255, 254, 247, 1) 87%,
rgba(255, 254, 247, 1) 100%
);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
}
main,
footer {
width: 70%;
margin: 3rem auto;
min-width: 850px;
padding: 0 20px;
box-sizing: border-box;
}
/* ---------------- Content ------------------- */
h1 {
color: #93412b;
font-size: 3em;
margin-bottom: 20px;
font-weight: bold;
}
h2 {
color: #93412b;
font-size: 2.5em;
margin-bottom: 15px;
}
h3 {
color: #93412b;
font-size: 2em;
margin-bottom: 10px;
}
p {
line-height: 15px;
margin-bottom: 15px;
line-height: 1.7em;
}
.cited {
font-style: italic;
font-size: 0.8em;
}
.u {
text-decoration: underline;
}
.b {
font-weight: bold;
}
.i {
font-style: italic;
}
.align_right {
text-align: right;
}
.align_left {
text-align: left;
margin-right: 10px;
}
.align_center {
text-align: center;
}
.float_left {
float: left;
}
.float_right {
float: right;
}
.clear_both {
clear: both;
}
strong {
font-weight: bold;
}
.special {
color: #b7595b;
font-weight: bold;
}
.keyword {
color: #db6f50;
font-weight: bold;
font-style: italic;
}
.gray {
color: gray;
}
/* Links */
main a:link,
main a:visited {
color: #eb690b;
font-weight: bold;
}
main a:focus,
main a:hover,
main a:active {
color: #eb690b;
}
ul {
list-style-position: outside;
margin-bottom: 20px;
padding-left: 22px;
}
ol {
margin-bottom: 20px;
padding-left: 30px;
}
li {
line-height: 1.4em;
}
/* ------- Article ------- */
h1 {
color: #93412b;
font-size: 2.7em;
margin-bottom: 20px;
}
#buy_form input[type='button'] {
display: inline-block;
padding: 1px 20px 3px 20px;
background-color: #93412b;
color: white;
border: 1px solid white;
font-size: 1em;
height: 32px;
}
#buy_form input[type='button']:hover {
background-color: white;
color: #93412b;
border: 1px solid #93412b;
}
#buy_form select {
display: inline-block;
font-size: 1em;
background-color: white;
color: #93412b;
border: 1px solid #93412b;
height: 32px;
}
/* ------- Chat ------- */
#chat {
width: 100%;
background-color: white;
border: 1px solid #9c352f;
height: 20rem;
position: relative;
}
#chat_window {
background-color: white;
width: 85%;
float: left;
height: 95%;
}
#chat_history {
position: absolute;
bottom: 8%;
max-height: 92%;
padding: 0px 0px 5px 7px;
}
#chat_history p {
font-size: 0.6em;
margin: 0;
}
#chat_text {
height: 8%;
position: absolute;
bottom: 0;
width: 85%;
}
#chat_text input {
width: 98%;
display: block;
margin: auto;
}
#chat_members {
list-style-type: none;
height: 100%;
width: 15%;
margin-left: 85%;
border-left: 1px solid #9c352f;
text-align: right;
box-sizing: border-box;
min-width: 100px;
font-size: 0.8em;
padding-top: 5px;
}
#chat_members li {
line-height: 1.2em;
padding: 5px 10px 2px 15px;
}
#chat_members .highlighted {
background-color: #c14d45;
color: white;
}
.chat_member {
font-weight: bold;
}
.chat_member1 {
color: #3626c8;
}
.chat_member2 {
color: #e38d0b;
}
#member_search {
position: absolute;
right: 0;
bottom: 0;
width: 15%;
height: 8%;
}
#member_search input {
width: 88%;
display: block;
margin: auto;
text-align: right;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

@@ -0,0 +1,45 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 1: Almost Famous Quotes 1</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="assets/css/styles.css" />
</head>
<body>
<header></header>
<main>
<h1>Famous Quotes</h1>
<blockquote></blockquote>
</main>
<script>
'use strict';
// 1
// Ändern Sie mit Hilfe von JS die Überschrift (h1) der HTML-Seite in Almost Famous Quotes.
const headingEl = document.querySelector('h1');
headingEl.textContent = 'Almost Famous Quotes';
// 2
// Die Seite enthält ein leeres blockquote-Element. Öffnen Sie die HTML-Seite in Chrome. Geben Sie in der Konsole eine Zeile JS-Code ein, die das Element mit folgendem Inhalt befüllt:
// <p>
// I have always wished for my computer to be as easy to use as my telephone;
// my wish has come true because I can no longer figure out how to use my
// telephone.
// </p>
// <footer>— <cite>Bjarne Stroustrup</cite></footer>
const blockquoteEl = document.querySelector('blockquote');
blockquoteEl.innerHTML = `
<p>
I have always wished for my computer to be as easy to use as my telephone;
my wish has come true because I can no longer figure out how to use my
telephone.
</p><footer>— <cite>Bjarne Stroustrup</cite></footer>
`;
</script>
</body>
</html>
@@ -0,0 +1,266 @@
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
/* ---------------- CSS-Reset ------------------- */
html, body, a, div, h1, h2, h3, h4, h5, h6, span, p, img, strong, ul, li, table, th, td, tr {
margin: 0px;
padding: 0px;
border: 0px none;
font-weight: normal;
font-style: inherit;
font-family: inherit;
font-variant: inherit;
text-decoration: none;
table-layout: inherit;
}
/* ---------------- Body / HTML ------------------- */
html {
font-size: 100%;
background-color: #fffef7;
}
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 1.2em;
font-weight: normal;
color: black;
margin: 0rem auto 2rem auto;
}
/* ---------------- layout ------------------- */
header {
background: url(../img/js_header.png) left top no-repeat transparent;
background-size: cover;
height: 250px;
min-width: 850px;
}
header:after {
content: ' ';
display: block;
height: 250px;
background: rgba(255,254,247,0);
background: -moz-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,254,247,0)), color-stop(22%, rgba(255,254,247,0.55)), color-stop(42%, rgba(255,254,247,0.7)), color-stop(43%, rgba(255,254,247,0.71)), color-stop(61%, rgba(255,254,247,0.78)), color-stop(75%, rgba(255,254,247,0.92)), color-stop(87%, rgba(255,254,247,1)), color-stop(100%, rgba(255,254,247,1)));
background: -webkit-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: -o-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: -ms-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: linear-gradient(to bottom, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
}
main,
footer {
width: 70%;
margin: 3rem auto;
min-width: 850px;
padding: 0 20px;
box-sizing: border-box;
}
/* ---------------- Content ------------------- */
h1 {
color: #93412b;
font-size: 3em;
margin-bottom: 20px;
font-weight: bold;
}
h2 {
color: #93412b;
font-size: 2.5em;
margin-bottom: 15px;
}
h3 {
color: #93412b;
font-size: 2em;
margin-bottom: 10px;
}
p {
line-height: 15px;
margin-bottom: 15px;
line-height: 1.7em;
}
.cited {
font-style: italic;
font-size: .8em;
}
.u {text-decoration: underline;}
.b {font-weight: bold;}
.i {font-style: italic}
.align_right {text-align: right;}
.align_left {text-align: left; margin-right: 10px;}
.align_center {text-align: center;}
.float_left {float: left;}
.float_right {float: right;}
.clear_both {clear: both;}
strong {font-weight: bold;}
.special { color: #b7595b; font-weight: bold; }
.keyword { color: #db6f50; font-weight: bold; font-style: italic;}
.gray {color: gray;}
/* Links */
main a:link,
main a:visited {
color: #eb690b;
font-weight: bold;
}
main a:focus,
main a:hover,
main a:active {color: #eb690b;}
ul {
list-style-position: outside;
margin-bottom: 20px;
padding-left: 22px;
}
ol {
margin-bottom: 20px;
padding-left: 30px;
}
li {
line-height: 1.4em;
}
/* ------- Article ------- */
h1 {
color: #93412b;
font-size: 2.7em;
margin-bottom: 20px;
}
#buy_form input[type=button] {
display: inline-block;
padding: 1px 20px 3px 20px;
background-color: #93412b;
color: white;
border: 1px solid white;
font-size: 1em;
height: 32px;
}
#buy_form input[type=button]:hover {
background-color: white;
color: #93412b;
border: 1px solid #93412b;
}
#buy_form select {
display: inline-block;
font-size: 1em;
background-color: white;
color: #93412b;
border: 1px solid #93412b;
height: 32px;
}
/* ------- Chat ------- */
#chat {
width: 100%;
background-color: white;
border: 1px solid #9c352f;
height: 20rem;
position: relative;
}
#chat_window {
background-color: white;
width: 85%;
float: left;
height: 95%;
}
#chat_history {
position: absolute;
bottom: 8%;
max-height: 92%;
padding: 0px 0px 5px 7px;
}
#chat_history p {
font-size: .6em;
margin: 0;
}
#chat_text {
height: 8%;
position: absolute;
bottom: 0;
width: 85%;
}
#chat_text input {
width: 98%;
display: block;
margin: auto;
}
#chat_members {
list-style-type: none;
height: 100%;
width: 15%;
margin-left: 85%;
border-left: 1px solid #9c352f;
text-align: right;
box-sizing: border-box;
min-width: 100px;
font-size: .8em;
padding-top: 5px;
}
#chat_members li {
line-height: 1.2em;
padding: 5px 10px 2px 15px;
}
#chat_members .highlighted {
background-color: #c14d45;
color: white;
}
.chat_member {font-weight: bold;}
.chat_member1 { color: #3626c8;}
.chat_member2 { color: #e38d0b;}
#member_search {
position: absolute;
right: 0;
bottom: 0;
width: 15%;
height: 8%;
}
#member_search input {
width: 88%;
display: block;
margin: auto;
text-align: right;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@@ -0,0 +1,112 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>010010000100111101010100</title>
<meta name="description" content="JavaScript. HTML mühelos manipuliert" />
<link rel="stylesheet" href="assets/css/styles.css" type="text/css" media="screen" />
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
</head>
<body>
<header></header>
<main>
<h1 class="article">
Hot Binary Heat Changing Mug
<span class="keyword">"010010000100111101010100"</span>
</h1>
<img
alt="Hot Binary Heat Changing Mug"
src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug.gif"
class="float_left"
id="product_img" />
<h2>Description</h2>
<p>
Numbers make up
<span class="special">everything</span> in our digital world. They flow around us, invisible like the Force or
the Matrix, controlling all our many computer-y devices. Two numbers, in particular:
<span class="special">0 and 1</span>. <span class="b i">Off and On</span>. Well, we can tell you this: when
there's no coffee in our cup, we're completely OFF our game. But when our mug is full of hot coffee, we're
totally ON. And now, with the <span class="keyword">Hot Binary Heat Changing Mug</span>, there's a mug that
tells us which state our mug is in. In binary!
</p>
<p>
See, the
<span class="keyword">Hot Binary Heat Changing Mug</span>
looks like just a dark mug with binary numbers all over it. That's its OFF or cold state. Add hot coffee (or any
liquid) and a series of digits will turn white. Read them continuously from left to right, and you'll read:
<span class="keyword">010010000100111101010100</span>. That's <span class="special">in binary</span>. Of course,
your
<span class="keyword">Hot Binary Heat Changing Mug</span>
could just be paying you a compliment. Cheeky, mug.
</p>
<p>
<img alt="010010000100111101010100" src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug_grid_embed.jpg" />
</p>
<h2>Product Specifications</h2>
<ul id="product_specification">
<li class="keyword">Hot Binary Heat Changing Mug</li>
<li>
As you add hot liquids, the binary for "HOT" appears (read from left to right in one line, not two:
010010000100111101010100)
</li>
<li>A <span class="keyword">ThinkGeek</span> creation and exclusive!</li>
<li>
Care Instructions:
<span class="i b">Hand wash only. Not microwave or dishwasher safe.</span>
</li>
<li>Materials: Ceramic</li>
<li>Dimensions: approx. 3.15" diameter x 3.75" tall</li>
</ul>
<h3>You wanna buy it?</h3>
<p class="buy_info_text">If you like to buy this brilliant mug, just do the following steps:</p>
<ol class="model" data-model="LDV73C-X3">
<li>Select how many items do you want.</li>
<li>Press "buy".</li>
</ol>
<form id="buy_form">
<select>
<option>1 item</option>
<option>2 items</option>
<option>3 items</option>
<option>4 items</option>
</select>
<input type="button" value="buy" />
</form>
</main>
<footer>(C) by ThinkGeek &ndash; Produkttext mit freundlicher Genehmigung von ThinkGeek Inc.</footer>
<script>
'use strict';
(() => {
// Tippen Sie eine Abfrage in die Konsole, die:
// 1. das h1-Element findet.
// 2.das Element mit der id buy_form findet.
// 3. das Element mit der id product_img findet.
console.log(document.querySelector('h1'));
// console.log(document.getElementsByTagName('h1')[0]);
console.log(document.querySelector('#buy_form'));
console.log(document.getElementById('buy_form'));
console.log(document.querySelector('#product_img'));
console.log(document.getElementById('product_img'));
})();
</script>
</body>
</html>
@@ -0,0 +1,266 @@
/* -------------------------------------------- Haupt CSS fuer alle Seiten -------------------------------------------- */
/* ---------------- CSS-Reset ------------------- */
html, body, a, div, h1, h2, h3, h4, h5, h6, span, p, img, strong, ul, li, table, th, td, tr {
margin: 0px;
padding: 0px;
border: 0px none;
font-weight: normal;
font-style: inherit;
font-family: inherit;
font-variant: inherit;
text-decoration: none;
table-layout: inherit;
}
/* ---------------- Body / HTML ------------------- */
html {
font-size: 100%;
background-color: #fffef7;
}
body {
font-family: Helvetica, Arial, sans-serif;
font-size: 1.2em;
font-weight: normal;
color: black;
margin: 0rem auto 2rem auto;
}
/* ---------------- layout ------------------- */
header {
background: url(../img/js_header.png) left top no-repeat transparent;
background-size: cover;
height: 250px;
min-width: 850px;
}
header:after {
content: ' ';
display: block;
height: 250px;
background: rgba(255,254,247,0);
background: -moz-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(255,254,247,0)), color-stop(22%, rgba(255,254,247,0.55)), color-stop(42%, rgba(255,254,247,0.7)), color-stop(43%, rgba(255,254,247,0.71)), color-stop(61%, rgba(255,254,247,0.78)), color-stop(75%, rgba(255,254,247,0.92)), color-stop(87%, rgba(255,254,247,1)), color-stop(100%, rgba(255,254,247,1)));
background: -webkit-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: -o-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: -ms-linear-gradient(top, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
background: linear-gradient(to bottom, rgba(255,254,247,0) 0%, rgba(255,254,247,0.55) 22%, rgba(255,254,247,0.7) 42%, rgba(255,254,247,0.71) 43%, rgba(255,254,247,0.78) 61%, rgba(255,254,247,0.92) 75%, rgba(255,254,247,1) 87%, rgba(255,254,247,1) 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fffef7', endColorstr='#fffef7', GradientType=0 );
}
main,
footer {
width: 70%;
margin: 3rem auto;
min-width: 850px;
padding: 0 20px;
box-sizing: border-box;
}
/* ---------------- Content ------------------- */
h1 {
color: #93412b;
font-size: 3em;
margin-bottom: 20px;
font-weight: bold;
}
h2 {
color: #93412b;
font-size: 2.5em;
margin-bottom: 15px;
}
h3 {
color: #93412b;
font-size: 2em;
margin-bottom: 10px;
}
p {
line-height: 15px;
margin-bottom: 15px;
line-height: 1.7em;
}
.cited {
font-style: italic;
font-size: .8em;
}
.u {text-decoration: underline;}
.b {font-weight: bold;}
.i {font-style: italic}
.align_right {text-align: right;}
.align_left {text-align: left; margin-right: 10px;}
.align_center {text-align: center;}
.float_left {float: left;}
.float_right {float: right;}
.clear_both {clear: both;}
strong {font-weight: bold;}
.special { color: #b7595b; font-weight: bold; }
.keyword { color: #db6f50; font-weight: bold; font-style: italic;}
.gray {color: gray;}
/* Links */
main a:link,
main a:visited {
color: #eb690b;
font-weight: bold;
}
main a:focus,
main a:hover,
main a:active {color: #eb690b;}
ul {
list-style-position: outside;
margin-bottom: 20px;
padding-left: 22px;
}
ol {
margin-bottom: 20px;
padding-left: 30px;
}
li {
line-height: 1.4em;
}
/* ------- Article ------- */
h1 {
color: #93412b;
font-size: 2.7em;
margin-bottom: 20px;
}
#buy_form input[type=button] {
display: inline-block;
padding: 1px 20px 3px 20px;
background-color: #93412b;
color: white;
border: 1px solid white;
font-size: 1em;
height: 32px;
}
#buy_form input[type=button]:hover {
background-color: white;
color: #93412b;
border: 1px solid #93412b;
}
#buy_form select {
display: inline-block;
font-size: 1em;
background-color: white;
color: #93412b;
border: 1px solid #93412b;
height: 32px;
}
/* ------- Chat ------- */
#chat {
width: 100%;
background-color: white;
border: 1px solid #9c352f;
height: 20rem;
position: relative;
}
#chat_window {
background-color: white;
width: 85%;
float: left;
height: 95%;
}
#chat_history {
position: absolute;
bottom: 8%;
max-height: 92%;
padding: 0px 0px 5px 7px;
}
#chat_history p {
font-size: .6em;
margin: 0;
}
#chat_text {
height: 8%;
position: absolute;
bottom: 0;
width: 85%;
}
#chat_text input {
width: 98%;
display: block;
margin: auto;
}
#chat_members {
list-style-type: none;
height: 100%;
width: 15%;
margin-left: 85%;
border-left: 1px solid #9c352f;
text-align: right;
box-sizing: border-box;
min-width: 100px;
font-size: .8em;
padding-top: 5px;
}
#chat_members li {
line-height: 1.2em;
padding: 5px 10px 2px 15px;
}
#chat_members .highlighted {
background-color: #c14d45;
color: white;
}
.chat_member {font-weight: bold;}
.chat_member1 { color: #3626c8;}
.chat_member2 { color: #e38d0b;}
#member_search {
position: absolute;
right: 0;
bottom: 0;
width: 15%;
height: 8%;
}
#member_search input {
width: 88%;
display: block;
margin: auto;
text-align: right;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@@ -0,0 +1,124 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>010010000100111101010100</title>
<meta name="description" content="JavaScript. HTML mühelos manipuliert" />
<link rel="stylesheet" href="assets/css/styles.css" type="text/css" media="screen" />
<link rel="shortcut icon" href="assets/img/favicon.ico" type="image/x-icon" />
</head>
<body>
<header></header>
<main>
<h1 class="article">
Hot Binary Heat Changing Mug
<span class="keyword">"010010000100111101010100"</span>
</h1>
<img
alt="Hot Binary Heat Changing Mug"
src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug.gif"
class="float_left"
id="product_img" />
<h2>Description</h2>
<p>
Numbers make up
<span class="special">everything</span> in our digital world. They flow around us, invisible like the Force or
the Matrix, controlling all our many computer-y devices. Two numbers, in particular:
<span class="special">0 and 1</span>. <span class="b i">Off and On</span>. Well, we can tell you this: when
there's no coffee in our cup, we're completely OFF our game. But when our mug is full of hot coffee, we're
totally ON. And now, with the <span class="keyword">Hot Binary Heat Changing Mug</span>, there's a mug that
tells us which state our mug is in. In binary!
</p>
<p>
See, the
<span class="keyword">Hot Binary Heat Changing Mug</span>
looks like just a dark mug with binary numbers all over it. That's its OFF or cold state. Add hot coffee (or any
liquid) and a series of digits will turn white. Read them continuously from left to right, and you'll read:
<span class="keyword">010010000100111101010100</span>. That's <span class="special">in binary</span>. Of course,
your
<span class="keyword">Hot Binary Heat Changing Mug</span>
could just be paying you a compliment. Cheeky, mug.
</p>
<p>
<img alt="010010000100111101010100" src="assets/img/thinkgeek_2024_hot_binary_heat_change_mug_grid_embed.jpg" />
</p>
<h2>Product Specifications</h2>
<ul id="product_specification">
<li class="keyword">Hot Binary Heat Changing Mug</li>
<li>
As you add hot liquids, the binary for "HOT" appears (read from left to right in one line, not two:
010010000100111101010100)
</li>
<li>A <span class="keyword">ThinkGeek</span> creation and exclusive!</li>
<li>
Care Instructions:
<span class="i b">Hand wash only. Not microwave or dishwasher safe.</span>
</li>
<li>Materials: Ceramic</li>
<li>Dimensions: approx. 3.15" diameter x 3.75" tall</li>
</ul>
<h3>You wanna buy it?</h3>
<p class="buy_info_text">If you like to buy this brilliant mug, just do the following steps:</p>
<ol class="model" data-model="LDV73C-X3">
<li>Select how many items do you want.</li>
<li>Press "buy".</li>
</ol>
<form id="buy_form">
<select>
<option>1 item</option>
<option>2 items</option>
<option>3 items</option>
<option>4 items</option>
</select>
<input type="button" value="buy" />
</form>
</main>
<footer>(C) by ThinkGeek &ndash; Produkttext mit freundlicher Genehmigung von ThinkGeek Inc.</footer>
<script>
'use strict';
(() => {
// alle li-Elemente findet.
const listItems = document.querySelectorAll('li');
// alle h2-Elemente findet.
const levelTwoHeadings = document.querySelectorAll('h2');
// alle Elemente mit der Klasse special findet.
const specialElements = document.querySelectorAll('.special');
// alle li-Elemente mit der Klasse keyword findet.
const keywordListItems = document.querySelectorAll('li.keyword');
// alle span-Elemente mit der Klasse special findet.
const specialSpans = document.querySelectorAll('span.special');
// alle Elemente findet, die die Klassen i UND b haben.
const italicBoldElements = document.querySelectorAll('.i.b');
console.log('List items:', listItems);
console.log('Level two headings:', levelTwoHeadings);
console.log('Special elements:', specialElements);
console.log('Keyword list items:', keywordListItems);
console.log('Special spans:', specialSpans);
console.log('Italic and bold elements:', italicBoldElements);
})();
</script>
</body>
</html>

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