tasmota-webserial-esptool 7.0.1 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/struct.ts CHANGED
@@ -1,7 +1,14 @@
1
+ type DataViewGetter = (byteOffset: number, littleEndian?: boolean) => number;
2
+ type DataViewSetter = (
3
+ byteOffset: number,
4
+ value: number,
5
+ littleEndian?: boolean,
6
+ ) => void;
7
+
1
8
  interface DataType {
2
9
  [key: string]: {
3
- u: Function;
4
- p: Function;
10
+ u: DataViewGetter;
11
+ p: DataViewSetter;
5
12
  bytes: number;
6
13
  };
7
14
  }
@@ -32,20 +39,6 @@ const lut: DataType = {
32
39
  p: DataView.prototype.setUint32,
33
40
  bytes: 4,
34
41
  },
35
- q: {
36
- // @ts-ignore
37
- u: DataView.prototype.getInt64,
38
- // @ts-ignore
39
- p: DataView.prototype.setInt64,
40
- bytes: 8,
41
- },
42
- Q: {
43
- // @ts-ignore
44
- u: DataView.prototype.getUint64,
45
- // @ts-ignore
46
- p: DataView.prototype.setUint64,
47
- bytes: 8,
48
- },
49
42
  };
50
43
 
51
44
  export const pack = (format: string, ...data: number[]) => {
@@ -53,7 +46,7 @@ export const pack = (format: string, ...data: number[]) => {
53
46
  if (format.replace(/[<>]/, "").length != data.length) {
54
47
  throw "Pack format to Argument count mismatch";
55
48
  }
56
- let bytes: number[] = [];
49
+ const bytes: number[] = [];
57
50
  let littleEndian = true;
58
51
  for (let i = 0; i < format.length; i++) {
59
52
  if (format[i] == "<") {
@@ -70,9 +63,9 @@ export const pack = (format: string, ...data: number[]) => {
70
63
  if (!(formatChar in lut)) {
71
64
  throw "Unhandled character '" + formatChar + "' in pack format";
72
65
  }
73
- let dataSize = lut[formatChar].bytes;
74
- let view = new DataView(new ArrayBuffer(dataSize));
75
- let dataViewFn = lut[formatChar].p.bind(view);
66
+ const dataSize = lut[formatChar].bytes;
67
+ const view = new DataView(new ArrayBuffer(dataSize));
68
+ const dataViewFn = lut[formatChar].p.bind(view);
76
69
  dataViewFn(0, value, littleEndian);
77
70
  for (let i = 0; i < dataSize; i++) {
78
71
  bytes.push(view.getUint8(i));
@@ -84,10 +77,10 @@ export const pack = (format: string, ...data: number[]) => {
84
77
 
85
78
  export const unpack = (format: string, bytes: number[]) => {
86
79
  let pointer = 0;
87
- let data: number[] = [];
80
+ const data: number[] = [];
88
81
  let littleEndian = true;
89
82
 
90
- for (let c of format) {
83
+ for (const c of format) {
91
84
  if (c == "<") {
92
85
  littleEndian = true;
93
86
  } else if (c == ">") {
@@ -101,12 +94,12 @@ export const unpack = (format: string, bytes: number[]) => {
101
94
  if (!(formatChar in lut)) {
102
95
  throw "Unhandled character '" + formatChar + "' in unpack format";
103
96
  }
104
- let dataSize = lut[formatChar].bytes;
105
- let view = new DataView(new ArrayBuffer(dataSize));
97
+ const dataSize = lut[formatChar].bytes;
98
+ const view = new DataView(new ArrayBuffer(dataSize));
106
99
  for (let i = 0; i < dataSize; i++) {
107
100
  view.setUint8(i, bytes[pointer + i] & 0xff);
108
101
  }
109
- let dataViewFn = lut[formatChar].u.bind(view);
102
+ const dataViewFn = lut[formatChar].u.bind(view);
110
103
  data.push(dataViewFn(0, littleEndian));
111
104
  pointer += dataSize;
112
105
  }
package/src/util.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export const slipEncode = (buffer: number[]): number[] => {
7
7
  let encoded = [0xc0];
8
- for (let byte of buffer) {
8
+ for (const byte of buffer) {
9
9
  if (byte == 0xdb) {
10
10
  encoded = encoded.concat([0xdb, 0xdd]);
11
11
  } else if (byte == 0xc0) {
@@ -23,9 +23,9 @@ export const slipEncode = (buffer: number[]): number[] => {
23
23
  * Convert a string to a byte array
24
24
  */
25
25
  export const toByteArray = (str: string): number[] => {
26
- let byteArray: number[] = [];
26
+ const byteArray: number[] = [];
27
27
  for (let i = 0; i < str.length; i++) {
28
- let charcode = str.charCodeAt(i);
28
+ const charcode = str.charCodeAt(i);
29
29
  if (charcode <= 0xff) {
30
30
  byteArray.push(charcode);
31
31
  }
@@ -37,7 +37,7 @@ export const hexFormatter = (bytes: number[]) =>
37
37
  "[" + bytes.map((value) => toHex(value)).join(", ") + "]";
38
38
 
39
39
  export const toHex = (value: number, size = 2) => {
40
- let hex = value.toString(16).toUpperCase();
40
+ const hex = value.toString(16).toUpperCase();
41
41
  if (hex.startsWith("-")) {
42
42
  return "-0x" + hex.substring(1).padStart(size, "0");
43
43
  } else {
@@ -1,22 +0,0 @@
1
- // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
- // README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
3
- {
4
- "name": "Node.js & TypeScript",
5
- // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
- "image": "mcr.microsoft.com/devcontainers/typescript-node:0-20"
7
-
8
- // Features to add to the dev container. More info: https://containers.dev/features.
9
- // "features": {},
10
-
11
- // Use 'forwardPorts' to make a list of ports inside the container available locally.
12
- // "forwardPorts": [],
13
-
14
- // Use 'postCreateCommand' to run commands after the container is created.
15
- // "postCreateCommand": "yarn install",
16
-
17
- // Configure tool-specific properties.
18
- // "customizations": {},
19
-
20
- // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
21
- // "remoteUser": "root"
22
- }
@@ -1,10 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: "github-actions"
4
- directory: "/"
5
- schedule:
6
- interval: weekly
7
- - package-ecosystem: "npm"
8
- directory: "/"
9
- schedule:
10
- interval: "weekly"
@@ -1,75 +0,0 @@
1
- name: Build and upload
2
-
3
- on:
4
- push:
5
- workflow_dispatch:
6
-
7
- # Allow one concurrent deployment
8
- concurrency:
9
- group: environment-${{ github.ref }}
10
- cancel-in-progress: true
11
-
12
- jobs:
13
- build:
14
- runs-on: ubuntu-latest
15
- permissions:
16
- contents: write
17
- id-token: write # required to use OIDC
18
- steps:
19
- - uses: actions/checkout@v6
20
- - name: Remove old files and folders
21
- run: |
22
- rm -rf package-lock.json
23
- rm -rf dist
24
- rm -rf js/modules
25
- mkdir js/modules
26
- - name: install node v20
27
- uses: actions/setup-node@v6
28
- with:
29
- node-version: 20
30
- - name: Install Yarn with NPM
31
- run: npm install -g yarn
32
- - name: yarn install
33
- run: yarn install
34
- - name: Compile TypeScript
35
- run: |
36
- set -e
37
- rm -rf dist
38
- NODE_ENV=production npm exec -- tsc
39
- NODE_ENV=production npm exec -- rollup -c
40
- - name: Rename and copy build artifact
41
- run: |
42
- cp dist/web/*.js js/modules/
43
- mv js/modules/index.js js/modules/esptool.js
44
- #ls js/modules/
45
- - name: Commit Distribution Files
46
- uses: stefanzweifel/git-auto-commit-action@v7
47
- with:
48
- commit_message: "Github Action: Updated dist files"
49
- - name: Publish to NPM registry
50
- uses: JS-DevTools/npm-publish@v4
51
- with:
52
- registry: https://registry.npmjs.org/
53
- token: ${{ secrets.NPM_TOKEN }}
54
- strategy: all
55
- - name: Setup Pages
56
- uses: actions/configure-pages@v5
57
- - name: Upload artifact
58
- uses: actions/upload-pages-artifact@v4
59
- with:
60
- path: "."
61
-
62
- deploy:
63
- needs: build
64
- environment:
65
- name: github-pages
66
- url: ${{ steps.deployment.outputs.page_url }}
67
- runs-on: ubuntu-latest
68
- permissions:
69
- contents: read
70
- pages: write
71
- id-token: write
72
- steps:
73
- - name: Deploy to GitHub Pages
74
- id: deployment
75
- uses: actions/deploy-pages@v4
@@ -1,30 +0,0 @@
1
- # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
-
4
- name: CI
5
-
6
- on:
7
- push:
8
- pull_request:
9
-
10
- jobs:
11
- build:
12
- runs-on: ubuntu-latest
13
-
14
- steps:
15
- - uses: actions/checkout@v6
16
- - name: Use Node.js
17
- uses: actions/setup-node@v6
18
- with:
19
- node-version: 20
20
- - name: Remove old package-lock.json
21
- run: |
22
- rm -rf package-lock.json
23
- - run: npm install
24
- - run: npm ci
25
- - run: script/build
26
- - run: npm exec -- prettier --check src
27
- - name: Commit changed files
28
- uses: stefanzweifel/git-auto-commit-action@v7
29
- with:
30
- commit_message: "Github Action: Updated files"
package/.prettierignore DELETED
@@ -1 +0,0 @@
1
- src/stubs
@@ -1,169 +0,0 @@
1
- # Changelog: Chip Variant Support
2
-
3
- ## Änderungen in WebSerial_ESPTool
4
-
5
- ### Neue Features
6
-
7
- #### 1. `chipVariant` Feld in ESPLoader
8
- - Neues öffentliches Feld: `chipVariant: string | null`
9
- - Wird automatisch bei der Chip-Erkennung gesetzt
10
- - Für ESP32-P4: `"rev0"` (Revision < 300) oder `"rev300"` (Revision >= 300)
11
- - Für alle anderen Chips: `null`
12
-
13
- #### 2. Erweiterte ESP32-P4 Erkennung
14
- - Revision wird aus eFuses gelesen (EFUSE_BLOCK1)
15
- - Funktioniert sowohl bei IMAGE_CHIP_ID als auch Magic Value Erkennung
16
- - Logging der erkannten Variante im Debug-Modus
17
-
18
- ### Geänderte Dateien
19
-
20
- - `src/esp_loader.ts`:
21
- - Hinzugefügt: `chipVariant: string | null` Feld
22
- - Erweitert: `detectChip()` Methode setzt chipVariant für ESP32-P4
23
- - Erweitert: Logging für bessere Nachvollziehbarkeit
24
-
25
- ### API-Änderungen
26
-
27
- ```typescript
28
- // Vorher
29
- const esploader = new ESPLoader(port, logger);
30
- await esploader.initialize();
31
- console.log(esploader.chipName); // "ESP32-P4"
32
- console.log(esploader.chipRevision); // 300
33
-
34
- // Nachher (zusätzlich)
35
- console.log(esploader.chipVariant); // "rev300"
36
- ```
37
-
38
- ### Abwärtskompatibilität
39
-
40
- ✅ Vollständig abwärtskompatibel
41
- - Bestehendes Code funktioniert unverändert
42
- - Neues Feld ist optional und kann ignoriert werden
43
- - Keine Breaking Changes
44
-
45
- ## Änderungen in esp-web-tools
46
-
47
- ### Neue Features
48
-
49
- #### 1. `chipVariant` Support in Manifesten
50
- - Neues optionales Feld in `Build` Interface: `chipVariant?: string`
51
- - Ermöglicht spezifische Firmware-Builds für verschiedene Chip-Varianten
52
- - Intelligente Matching-Logik mit Fallback-Unterstützung
53
-
54
- #### 2. Erweiterte Build-Auswahl
55
- - Priorisiert Builds mit passendem `chipVariant`
56
- - Fallback auf Builds ohne `chipVariant` Angabe
57
- - Bessere Fehlermeldungen mit Varianten-Information
58
-
59
- ### Geänderte Dateien
60
-
61
- - `src/const.ts`:
62
- - Erweitert: `Build` Interface mit `chipVariant?: string`
63
- - Erweitert: `BaseFlashState` Interface mit `chipVariant?: string | null`
64
-
65
- - `src/flash.ts`:
66
- - Erweitert: Build-Matching-Logik berücksichtigt chipVariant
67
- - Erweitert: Fehlermeldungen zeigen chipVariant an
68
- - Erweitert: Initialisierungsmeldung zeigt chipVariant an
69
-
70
- - `README.md`:
71
- - Hinzugefügt: Dokumentation für Chip Variant Support
72
- - Hinzugefügt: Beispiel für P4-Varianten
73
-
74
- ### Manifest-Beispiel
75
-
76
- ```json
77
- {
78
- "name": "My Firmware",
79
- "version": "1.0.0",
80
- "builds": [
81
- {
82
- "chipFamily": "ESP32-P4",
83
- "chipVariant": "rev0",
84
- "parts": [...]
85
- },
86
- {
87
- "chipFamily": "ESP32-P4",
88
- "chipVariant": "rev300",
89
- "parts": [...]
90
- }
91
- ]
92
- }
93
- ```
94
-
95
- ### Abwärtskompatibilität
96
-
97
- ✅ Vollständig abwärtskompatibel
98
- - Bestehende Manifeste ohne `chipVariant` funktionieren weiterhin
99
- - `chipVariant` ist optional
100
- - Keine Breaking Changes
101
-
102
- ## Testing
103
-
104
- ### Build-Tests
105
- - ✅ WebSerial_ESPTool kompiliert erfolgreich
106
- - ✅ esp-web-tools kompiliert erfolgreich
107
- - ✅ Keine TypeScript-Fehler
108
- - ✅ Keine Linting-Fehler
109
-
110
- ### Funktionale Tests (empfohlen)
111
- - [ ] Test mit ESP32-P4 Rev. 0 Hardware
112
- - [ ] Test mit ESP32-P4 Rev. 300 Hardware
113
- - [ ] Test mit Manifest mit chipVariant
114
- - [ ] Test mit Manifest ohne chipVariant (Fallback)
115
- - [ ] Test mit anderen ESP32-Chips (sollte chipVariant = null sein)
116
-
117
- ## Deployment
118
-
119
- ### WebSerial_ESPTool
120
- 1. Version in `package.json` erhöhen
121
- 2. `npm run prepublishOnly` ausführen
122
- 3. `npm publish` ausführen
123
-
124
- ### esp-web-tools
125
- 1. Warten bis neue WebSerial_ESPTool Version verfügbar ist
126
- 2. `package.json` aktualisieren: `"tasmota-webserial-esptool": "^6.5.0"` (oder höher)
127
- 3. Version in `package.json` erhöhen
128
- 4. `npm install`
129
- 5. `npm run prepublishOnly` ausführen
130
- 6. `npm publish` ausführen
131
-
132
- ## Dokumentation
133
-
134
- - ✅ `CHIP_VARIANT_SUPPORT.md` - Vollständige technische Dokumentation
135
- - ✅ `manifest-example-p4-variants.json` - Beispiel-Manifest
136
- - ✅ `README.md` (esp-web-tools) - Kurze Anleitung
137
- - ✅ `CHANGELOG_CHIP_VARIANT.md` - Diese Datei
138
-
139
- ## Verwendungsbeispiele
140
-
141
- ### Szenario 1: Separate Builds für jede Variante
142
- ```json
143
- {
144
- "builds": [
145
- { "chipFamily": "ESP32-P4", "chipVariant": "rev0", "parts": [...] },
146
- { "chipFamily": "ESP32-P4", "chipVariant": "rev300", "parts": [...] }
147
- ]
148
- }
149
- ```
150
-
151
- ### Szenario 2: Ein Build für alle Varianten
152
- ```json
153
- {
154
- "builds": [
155
- { "chipFamily": "ESP32-P4", "parts": [...] }
156
- ]
157
- }
158
- ```
159
-
160
- ### Szenario 3: Spezifischer Build + Fallback
161
- ```json
162
- {
163
- "builds": [
164
- { "chipFamily": "ESP32-P4", "chipVariant": "rev300", "parts": [...] },
165
- { "chipFamily": "ESP32-P4", "parts": [...] }
166
- ]
167
- }
168
- ```
169
- Rev300 verwendet ersten Build, Rev0 verwendet zweiten Build (Fallback).
@@ -1,184 +0,0 @@
1
- # ESP32-P4 Chip Variant Support
2
-
3
- ## Übersicht
4
-
5
- Die beiden Projekte unterstützen jetzt die Unterscheidung zwischen verschiedenen ESP32-P4 Varianten über das neue `chipVariant` Feld.
6
-
7
- ## WebSerial_ESPTool
8
-
9
- ### Änderungen
10
-
11
- Das `ESPLoader` Objekt hat jetzt ein neues Feld:
12
- - `chipVariant: string | null` - Identifiziert die Chip-Variante
13
-
14
- ### ESP32-P4 Varianten
15
-
16
- Für ESP32-P4 Chips werden folgende Varianten erkannt:
17
- - `"rev0"` - ESP32-P4 Revision < 300 (ältere Versionen)
18
- - `"rev300"` - ESP32-P4 Revision >= 300 (neuere Versionen)
19
-
20
- Die Erkennung erfolgt automatisch basierend auf der Chip-Revision, die aus den eFuses gelesen wird.
21
-
22
- ### Beispiel
23
-
24
- ```typescript
25
- const esploader = new ESPLoader(port, logger);
26
- await esploader.initialize();
27
-
28
- console.log(esploader.chipName); // "ESP32-P4"
29
- console.log(esploader.chipFamily); // CHIP_FAMILY_ESP32P4
30
- console.log(esploader.chipRevision); // z.B. 0 oder 300
31
- console.log(esploader.chipVariant); // "rev0" oder "rev300"
32
- ```
33
-
34
- ## esp-web-tools
35
-
36
- ### Änderungen
37
-
38
- #### Manifest Format
39
-
40
- Das `Build` Interface unterstützt jetzt ein optionales `chipVariant` Feld:
41
-
42
- ```typescript
43
- interface Build {
44
- chipFamily: "ESP32-P4" | ...;
45
- chipVariant?: string; // NEU
46
- parts: { path: string; offset: number; }[];
47
- }
48
- ```
49
-
50
- #### Flash State
51
-
52
- Der `FlashState` enthält jetzt auch die `chipVariant` Information:
53
-
54
- ```typescript
55
- interface BaseFlashState {
56
- chipFamily?: "ESP32-P4" | ...;
57
- chipVariant?: string | null; // NEU
58
- // ...
59
- }
60
- ```
61
-
62
- ### Manifest Beispiel
63
-
64
- Hier ist ein Beispiel-Manifest, das verschiedene Firmware-Builds für die zwei P4-Varianten bereitstellt:
65
-
66
- ```json
67
- {
68
- "name": "My ESP32-P4 Firmware",
69
- "version": "1.0.0",
70
- "builds": [
71
- {
72
- "chipFamily": "ESP32-P4",
73
- "chipVariant": "rev0",
74
- "parts": [
75
- { "path": "bootloader_rev0.bin", "offset": 0 },
76
- { "path": "partition-table.bin", "offset": 32768 },
77
- { "path": "firmware_rev0.bin", "offset": 65536 }
78
- ]
79
- },
80
- {
81
- "chipFamily": "ESP32-P4",
82
- "chipVariant": "rev300",
83
- "parts": [
84
- { "path": "bootloader_rev300.bin", "offset": 0 },
85
- { "path": "partition-table.bin", "offset": 32768 },
86
- { "path": "firmware_rev300.bin", "offset": 65536 }
87
- ]
88
- },
89
- {
90
- "chipFamily": "ESP32-S3",
91
- "parts": [
92
- { "path": "bootloader_s3.bin", "offset": 0 },
93
- { "path": "partition-table.bin", "offset": 32768 },
94
- { "path": "firmware_s3.bin", "offset": 65536 }
95
- ]
96
- }
97
- ]
98
- }
99
- ```
100
-
101
- ### Matching-Logik
102
-
103
- Die Firmware-Auswahl funktioniert wie folgt:
104
-
105
- 1. **Wenn `chipVariant` im Build angegeben ist**: Der Build wird nur verwendet, wenn sowohl `chipFamily` als auch `chipVariant` übereinstimmen.
106
-
107
- 2. **Wenn `chipVariant` im Build NICHT angegeben ist**: Der Build wird für alle Varianten dieser `chipFamily` verwendet (Fallback).
108
-
109
- #### Beispiele
110
-
111
- **Szenario 1: Spezifische Builds für jede Variante**
112
- ```json
113
- {
114
- "builds": [
115
- { "chipFamily": "ESP32-P4", "chipVariant": "rev0", "parts": [...] },
116
- { "chipFamily": "ESP32-P4", "chipVariant": "rev300", "parts": [...] }
117
- ]
118
- }
119
- ```
120
- - ESP32-P4 rev0 → verwendet ersten Build
121
- - ESP32-P4 rev300 → verwendet zweiten Build
122
-
123
- **Szenario 2: Ein Build für alle Varianten**
124
- ```json
125
- {
126
- "builds": [
127
- { "chipFamily": "ESP32-P4", "parts": [...] }
128
- ]
129
- }
130
- ```
131
- - ESP32-P4 rev0 → verwendet den Build
132
- - ESP32-P4 rev300 → verwendet den Build
133
-
134
- **Szenario 3: Spezifischer Build + Fallback**
135
- ```json
136
- {
137
- "builds": [
138
- { "chipFamily": "ESP32-P4", "chipVariant": "rev300", "parts": [...] },
139
- { "chipFamily": "ESP32-P4", "parts": [...] }
140
- ]
141
- }
142
- ```
143
- - ESP32-P4 rev0 → verwendet zweiten Build (Fallback)
144
- - ESP32-P4 rev300 → verwendet ersten Build (spezifisch)
145
-
146
- ## Abwärtskompatibilität
147
-
148
- Alle Änderungen sind vollständig abwärtskompatibel:
149
-
150
- - Bestehende Manifeste ohne `chipVariant` funktionieren weiterhin
151
- - Das `chipVariant` Feld ist optional
152
- - Für alle Chips außer ESP32-P4 ist `chipVariant` `null`
153
-
154
- ## Technische Details
155
-
156
- ### Chip-Erkennung
157
-
158
- Die ESP32-P4 Revision wird aus den eFuses gelesen (EFUSE_BLOCK1):
159
- - Minor Revision: Bits [3:0]
160
- - Major Revision: Bit [23] << 2 | Bits [5:4]
161
- - Revision = Major * 100 + Minor
162
-
163
- ### Erkennungsmethoden
164
-
165
- Die Chip-Erkennung verwendet einen zweistufigen Ansatz:
166
-
167
- 1. **Primär: GET_SECURITY_INFO** (IMAGE_CHIP_ID)
168
- - Unterstützt von: ESP32-C3 (neuere ROM), ESP32-S3, ESP32-C6, ESP32-H2, ESP32-P4 Rev. 300+
169
- - Liefert direkt die Chip-ID
170
- - Wenn nicht unterstützt oder leere Antwort → Fallback zu Magic Value
171
-
172
- 2. **Fallback: Magic Value Detection**
173
- - Unterstützt von: ESP8266, ESP32, ESP32-S2, ESP32-C3 (ältere ROM), ESP32-P4 Rev. < 300
174
- - Liest Magic-Wert aus Register 0x40001000
175
- - Zuverlässige Methode für ältere Chips
176
-
177
- **Für ESP32-P4:**
178
- - Beide Methoden funktionieren
179
- - Nach Erkennung wird die Revision aus eFuses gelesen
180
- - Basierend auf Revision wird `chipVariant` gesetzt:
181
- - Rev. < 300 → `"rev0"`
182
- - Rev. >= 300 → `"rev300"`
183
-
184
- **Hinweis:** Die Debug-Meldung "GET_SECURITY_INFO failed, using magic value detection" ist normal und erwartet für ältere Chips. Der Fallback-Mechanismus stellt sicher, dass alle Chips korrekt erkannt werden.