@mxtommy/kip 3.10.0-beta.4 → 3.10.0-beta.40

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.
Files changed (48) hide show
  1. package/package.json +3 -2
  2. package/plugin/index.js +234 -26
  3. package/plugin/openApi.json +141 -0
  4. package/public/3rdpartylicenses.txt +52 -52
  5. package/public/assets/help-docs/welcome.md +2 -2
  6. package/public/assets/svg/icons.svg +5 -1
  7. package/public/chunk-27I36ZYA.js +2 -0
  8. package/public/chunk-2YGPLTEW.js +6 -0
  9. package/public/chunk-4MSEQKGR.js +2 -0
  10. package/public/chunk-5UBH6OWU.js +5 -0
  11. package/public/{chunk-Y2IB2JDT.js → chunk-CEAJKNTR.js} +10 -10
  12. package/public/chunk-DPDOUEUH.js +9 -0
  13. package/public/chunk-HO743WL4.js +3 -0
  14. package/public/chunk-I3H3XQ5E.js +1 -0
  15. package/public/{chunk-LRX3XYXK.js → chunk-I772OX6I.js} +1 -1
  16. package/public/chunk-IUCJGG6N.js +1 -0
  17. package/public/chunk-JNQX4WPI.js +1 -0
  18. package/public/chunk-JNXVWBL2.js +1 -0
  19. package/public/chunk-KNN6A4MI.js +2 -0
  20. package/public/chunk-LKF7CNOE.js +2 -0
  21. package/public/chunk-LTNAKI5X.js +1 -0
  22. package/public/chunk-MMJBKCH5.js +1 -0
  23. package/public/{chunk-GJ33QBJ6.js → chunk-MZURT7UO.js} +1 -1
  24. package/public/chunk-PB7HT3XU.js +15 -0
  25. package/public/chunk-PR5DAT3I.js +2 -0
  26. package/public/{chunk-J3WNXGAQ.js → chunk-QG3TFUUS.js} +1 -1
  27. package/public/{chunk-TDHAZ7DS.js → chunk-QXMATZB6.js} +1 -1
  28. package/public/chunk-SPUZNRYQ.js +5 -0
  29. package/public/chunk-TFULQA7J.js +3 -0
  30. package/public/{chunk-7OMETTVK.js → chunk-USU5F3L5.js} +1 -1
  31. package/public/index.html +1 -1
  32. package/public/{main-SVHIKBQ5.js → main-MAUOXZ64.js} +12 -14
  33. package/COPILOT.md +0 -362
  34. package/eslint.config.js +0 -45
  35. package/kip-plugin/src/index.ts +0 -49
  36. package/kip-plugin/tsconfig.plugin.json +0 -13
  37. package/public/chunk-BZF6OYAF.js +0 -7
  38. package/public/chunk-FW2LAMAA.js +0 -16
  39. package/public/chunk-GBHBJN24.js +0 -1
  40. package/public/chunk-GDOUBCED.js +0 -1
  41. package/public/chunk-HKUJILH7.js +0 -6
  42. package/public/chunk-JFDPDIG2.js +0 -2
  43. package/public/chunk-KJQ6X3BT.js +0 -2
  44. package/public/chunk-MXKB5Z6M.js +0 -5
  45. package/public/chunk-NL52VRFS.js +0 -1
  46. package/public/chunk-PTADMSJZ.js +0 -1
  47. package/public/chunk-T5GXSVMN.js +0 -1
  48. package/public/chunk-VSGAZDLP.js +0 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mxtommy/kip",
3
- "version": "3.10.0-beta.4",
3
+ "version": "3.10.0-beta.40",
4
4
  "description": "An advanced and versatile marine instrumentation package to display Signal K data.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -25,6 +25,7 @@
25
25
  "keywords": [
26
26
  "signalk-webapp",
27
27
  "signalk-category-instruments",
28
+ "signalk-category-notifications",
28
29
  "signalk-node-server-plugin",
29
30
  "signal k",
30
31
  "signalk",
@@ -46,7 +47,7 @@
46
47
  "build:plugin": "tsc -p ./kip-plugin/tsconfig.plugin.json",
47
48
  "build:dev": "ng build --configuration=dev",
48
49
  "build:prod": "ng build --configuration=production",
49
- "build:all": "npm run build:prod && npm run build:plugin",
50
+ "build:all": "npm run build:plugin && npm run build:prod",
50
51
  "e2e": "ng e2e"
51
52
  },
52
53
  "devDependencies": {
package/plugin/index.js CHANGED
@@ -1,47 +1,255 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = (app) => {
36
+ const server_api_1 = require("@signalk/server-api");
37
+ const openapi = __importStar(require("./openApi.json"));
38
+ exports.default = (server) => {
39
+ const API_PATHS = {
40
+ DISPLAYS: `/displays`,
41
+ INSTANCE: `/displays/:displayId`,
42
+ ACTIVE_SCREEN: `/displays/:displayId/activeScreen`
43
+ };
44
+ // Helpers
45
+ function getDisplaySelfPath(displayId, suffix) {
46
+ const tail = suffix ? `.${suffix}` : '';
47
+ const want = `displays.${displayId}${tail}`;
48
+ const full = server.getSelfPath(want);
49
+ server.debug(`getDisplaySelfPath: displayId: ${displayId}, suffix: ${suffix}, want=${want}, fullPath=${full}`);
50
+ return full;
51
+ }
52
+ function getAvailableDisplays() {
53
+ const fullPath = server.getSelfPath('displays');
54
+ server.debug(`getAvailableDisplays: fullPath=${JSON.stringify(fullPath)}`);
55
+ return server.getPath('vessels.self.displays');
56
+ }
57
+ function pathToDotNotation(path) {
58
+ const dottedPath = path.replace(/\//g, '.').replace(/^\./, '');
59
+ server.debug(`pathToDotNotation: input path=${path}, dottedPath=${dottedPath}`);
60
+ return dottedPath;
61
+ }
62
+ function sendOk(res, body) {
63
+ if (body === undefined)
64
+ return res.status(204).end();
65
+ return res.status(200).json(body);
66
+ }
67
+ function sendFail(res, statusCode, message) {
68
+ return res.status(statusCode).json({ state: 'FAILED', statusCode, message });
69
+ }
4
70
  const plugin = {
5
71
  id: 'kip',
6
72
  name: 'KIP',
7
73
  description: 'KIP server plugin',
8
74
  start: (settings) => {
9
- app.debug(`${plugin.name}: Starting plugin with settings: ${JSON.stringify(settings)}`);
10
- app.registerPutHandler('vessels.self', 'plugins.displays.*', displayPutHandler);
75
+ server.debug(`Starting plugin with settings: ${JSON.stringify(settings)}`);
76
+ server.setPluginStatus(`Starting...`);
11
77
  },
12
78
  stop: () => {
13
- app.debug(`${plugin.name}: Stopping plugin`);
79
+ server.debug(`Stopping plugin`);
80
+ const msg = 'Stopped.';
81
+ server.setPluginStatus(msg);
14
82
  },
15
83
  schema: () => {
16
84
  return {
17
85
  type: "object",
18
86
  properties: {}
19
87
  };
20
- }
21
- };
22
- function displayPutHandler(context, path, value) {
23
- app.debug(`${plugin.name}: PUT handler called for context ${context}, path ${path}, value ${value}`);
24
- try {
25
- const delta = {
26
- updates: [
27
- {
28
- values: [
88
+ },
89
+ registerWithRouter(router) {
90
+ server.debug(`Registering plugin routes: ${API_PATHS.DISPLAYS}, ${API_PATHS.INSTANCE}, ${API_PATHS.ACTIVE_SCREEN}`);
91
+ // Validate/normalize :displayId where present
92
+ router.param('displayId', (req, res, next, displayId) => {
93
+ if (displayId == null)
94
+ return sendFail(res, 400, 'Missing displayId parameter');
95
+ try {
96
+ let id = String(displayId);
97
+ // Decode percent-encoding if present
98
+ try {
99
+ id = decodeURIComponent(id);
100
+ }
101
+ catch {
102
+ // ignore decode errors, keep original id
103
+ }
104
+ // If someone sent JSON as the path segment, try to recover {"displayId":"..."}
105
+ if (id.trim().startsWith('{')) {
106
+ try {
107
+ const parsed = JSON.parse(id);
108
+ if (parsed && typeof parsed.displayId === 'string') {
109
+ id = parsed.displayId;
110
+ }
111
+ else {
112
+ return sendFail(res, 400, 'Invalid displayId format in JSON');
113
+ }
114
+ }
115
+ catch {
116
+ return sendFail(res, 400, 'Invalid displayId JSON');
117
+ }
118
+ }
119
+ // Basic safety: allow UUID-like strings (alphanum + dash)
120
+ if (!/^[A-Za-z0-9-]+$/.test(id)) {
121
+ return sendFail(res, 400, 'Invalid displayId format');
122
+ }
123
+ req.displayId = id;
124
+ next();
125
+ }
126
+ catch {
127
+ return sendFail(res, 400, 'Missing or invalid displayId parameter');
128
+ }
129
+ });
130
+ router.put(`${API_PATHS.INSTANCE}`, async (req, res) => {
131
+ server.debug(`** PUT ${API_PATHS.INSTANCE}. Params: ${JSON.stringify(req.params)} Body: ${JSON.stringify(req.body)}`);
132
+ try {
133
+ const dottedPath = pathToDotNotation(req.path);
134
+ server.debug(`Updating SK path ${dottedPath}`);
135
+ server.handleMessage(plugin.id, {
136
+ updates: [
29
137
  {
30
- path: path,
31
- value: value
138
+ values: [
139
+ {
140
+ path: dottedPath,
141
+ value: req.body ?? null
142
+ }
143
+ ]
32
144
  }
33
145
  ]
146
+ }, server_api_1.SKVersion.v1);
147
+ return res.status(200).json({ state: 'SUCCESS', statusCode: 200 });
148
+ }
149
+ catch (error) {
150
+ const msg = `HandleMessage failed with errors!`;
151
+ server.setPluginError(msg);
152
+ server.error(`Error in HandleMessage: ${error}`);
153
+ return sendFail(res, 400, error.message);
154
+ }
155
+ });
156
+ router.put(`${API_PATHS.ACTIVE_SCREEN}`, async (req, res) => {
157
+ server.debug(`** PUT ${API_PATHS.ACTIVE_SCREEN}. Params: ${JSON.stringify(req.params)} Body: ${JSON.stringify(req.body)}`);
158
+ try {
159
+ const dottedPath = pathToDotNotation(req.path);
160
+ server.debug(`Updating SK path ${dottedPath} with body.screenIdx`);
161
+ server.handleMessage(plugin.id, {
162
+ updates: [
163
+ {
164
+ values: [
165
+ {
166
+ path: dottedPath,
167
+ value: req.body.screenIdx !== undefined ? req.body.screenIdx : null
168
+ }
169
+ ]
170
+ }
171
+ ]
172
+ }, server_api_1.SKVersion.v1);
173
+ return res.status(200).json({ state: 'SUCCESS', statusCode: 200 });
174
+ }
175
+ catch (error) {
176
+ const msg = `HandleMessage failed with errors!`;
177
+ server.setPluginError(msg);
178
+ server.error(`Error in HandleMessage: ${error}`);
179
+ return sendFail(res, 400, error.message);
180
+ }
181
+ });
182
+ router.get(API_PATHS.DISPLAYS, (req, res) => {
183
+ server.debug(`** GET ${API_PATHS.DISPLAYS}. Params: ${JSON.stringify(req.params)}`);
184
+ try {
185
+ const displays = getAvailableDisplays();
186
+ const items = displays && typeof displays === 'object'
187
+ ? Object.entries(displays)
188
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
189
+ .filter(([_, v]) => v && typeof v === 'object')
190
+ .map(([displayId, v]) => ({
191
+ displayId,
192
+ displayName: v.displayName ?? null
193
+ }))
194
+ : [];
195
+ server.debug(`getAvailableDisplays returned: ${JSON.stringify(displays)}`);
196
+ server.debug(`Found ${items.length} displays: ${JSON.stringify(items)}`);
197
+ return res.status(200).json(items);
198
+ }
199
+ catch (error) {
200
+ server.error(`Error reading displays: ${String(error.message || error)}`);
201
+ return sendFail(res, 400, error.message);
202
+ }
203
+ });
204
+ router.get(`${API_PATHS.INSTANCE}`, (req, res) => {
205
+ server.debug(`** GET ${API_PATHS.INSTANCE}. Params: ${JSON.stringify(req.params)}`);
206
+ try {
207
+ const displayId = req.displayId;
208
+ if (!displayId) {
209
+ return sendFail(res, 400, 'Missing displayId parameter');
34
210
  }
35
- ]
36
- };
37
- app.debug(`${plugin.name}: Sending message: `, JSON.stringify(delta));
38
- app.handleMessage(plugin.id, delta);
39
- return { state: "COMPLETED", statusCode: 200 };
40
- }
41
- catch (error) {
42
- app.error(`${plugin.name}: Error in PUT handler: ${error}`);
43
- return { state: "COMPLETED", statusCode: 500, message: error.message };
44
- }
45
- }
211
+ const fullPath = getDisplaySelfPath(displayId);
212
+ const value = server.getPath(fullPath);
213
+ if (value === undefined) {
214
+ return sendFail(res, 404, `Display ${displayId} not found`);
215
+ }
216
+ return sendOk(res, value);
217
+ }
218
+ catch (error) {
219
+ server.error(`Error reading display ${req.params?.displayId}: ${String(error.message || error)}`);
220
+ return sendFail(res, 400, error.message);
221
+ }
222
+ });
223
+ router.get(`${API_PATHS.ACTIVE_SCREEN}`, (req, res) => {
224
+ server.debug(`** GET ${API_PATHS.ACTIVE_SCREEN}. Params: ${JSON.stringify(req.params)}`);
225
+ try {
226
+ const displayId = req.displayId;
227
+ if (!displayId) {
228
+ return sendFail(res, 400, 'Missing displayId parameter');
229
+ }
230
+ const fullPath = getDisplaySelfPath(displayId, 'activeScreen');
231
+ const value = server.getPath(fullPath);
232
+ if (value === undefined) {
233
+ return sendFail(res, 404, `Active screen for display ${displayId} not found`);
234
+ }
235
+ return sendOk(res, value);
236
+ }
237
+ catch (error) {
238
+ server.error(`Error reading activeScreen for ${req.params?.displayId}: ${String(error.message || error)}`);
239
+ return sendFail(res, 400, error.message);
240
+ }
241
+ });
242
+ // List all registered routes for debugging
243
+ if (router.stack) {
244
+ router.stack.forEach((layer) => {
245
+ if (layer.route && layer.route.path) {
246
+ server.debug(`Registered route: ${layer.route.stack[0].method.toUpperCase()} ${layer.route.path}`);
247
+ }
248
+ });
249
+ }
250
+ server.setPluginStatus(`Providing remote display screen control`);
251
+ },
252
+ getOpenApi: () => openapi
253
+ };
46
254
  return plugin;
47
255
  };
@@ -0,0 +1,141 @@
1
+ {
2
+ "openapi": "3.0.0",
3
+ "info": {
4
+ "version": "1.0.0",
5
+ "title": "KIP Remote Displays API",
6
+ "description": "API endpoints to list KIP displays and control the active screen for a given KIP instance via Signal K self.displays tree.\n\nUsage:\n- List displays:\n curl -s http://localhost:3000/plugins/kip/displays\n- Read a display entry:\n curl -s http://localhost:3000/plugins/kip/displays/{displayId}\n- Set a display entry:\n curl -s -X PUT -H 'Content-Type: application/json' -d '{\"displayName\":\"Mast\"}' http://localhost:3000/plugins/kip/displays/{displayId}\n- Get active screen:\n curl -s http://localhost:3000/plugins/kip/displays/{displayId}/activeScreen\n- Set active screen:\n curl -s -X PUT -H 'Content-Type: application/json' -d '{\"screenIdx\":1}' http://localhost:3000/plugins/kip/displays/{displayId}/activeScreen",
7
+ "termsOfService": "http://signalk.org/terms/",
8
+ "license": {
9
+ "name": "Apache 2.0",
10
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
11
+ }
12
+ },
13
+ "externalDocs": {
14
+ "url": "http://signalk.org/specification/",
15
+ "description": "Signal K specification."
16
+ },
17
+ "servers": [
18
+ { "url": "/" }
19
+ ],
20
+ "tags": [
21
+ { "name": "Displays", "description": "KIP display discovery and control." }
22
+ ],
23
+ "components": {
24
+ "schemas": {
25
+ "DisplayInfo": {
26
+ "type": "object",
27
+ "properties": {
28
+ "displayId": { "type": "string", "description": "KIP instance UUID" },
29
+ "displayName": { "type": "string", "nullable": true }
30
+ },
31
+ "required": ["displayId"]
32
+ },
33
+ "SuccessResponse": {
34
+ "type": "object",
35
+ "properties": {
36
+ "state": { "type": "string", "enum": ["SUCCESS"] },
37
+ "statusCode": { "type": "integer", "enum": [200] }
38
+ },
39
+ "required": ["state", "statusCode"]
40
+ },
41
+ "ErrorResponse": {
42
+ "type": "object",
43
+ "properties": {
44
+ "state": { "type": "string", "enum": ["FAILED"] },
45
+ "statusCode": { "type": "integer" },
46
+ "message": { "type": "string" }
47
+ },
48
+ "required": ["state", "statusCode", "message"]
49
+ },
50
+ "ActiveScreenSetRequest": {
51
+ "type": "object",
52
+ "properties": {
53
+ "screenIdx": { "type": "integer", "nullable": true, "description": "Index of active screen or null to clear" }
54
+ }
55
+ },
56
+ "AnyObjectOrNull": {
57
+ "oneOf": [
58
+ { "type": "object", "additionalProperties": true },
59
+ { "type": "null" }
60
+ ]
61
+ }
62
+ },
63
+ "parameters": {
64
+ "DisplayIdParam": {
65
+ "in": "path",
66
+ "required": true,
67
+ "name": "displayId",
68
+ "description": "KIP instance UUID",
69
+ "schema": { "type": "string" }
70
+ }
71
+ },
72
+ "securitySchemes": {
73
+ "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" },
74
+ "cookieAuth": { "type": "apiKey", "in": "cookie", "name": "JAUTHENTICATION" }
75
+ }
76
+ },
77
+ "security": [{ "cookieAuth": [] }, { "bearerAuth": [] }],
78
+ "paths": {
79
+ "/plugins/kip/displays": {
80
+ "get": {
81
+ "tags": ["Displays"],
82
+ "summary": "List available KIP displays",
83
+ "responses": {
84
+ "200": {
85
+ "description": "List of KIP instances discovered under self.displays",
86
+ "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DisplayInfo" } } } }
87
+ },
88
+ "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
89
+ }
90
+ }
91
+ },
92
+ "/plugins/kip/displays/{displayId}": {
93
+ "parameters": [{ "$ref": "#/components/parameters/DisplayIdParam" }],
94
+ "get": {
95
+ "tags": ["Displays"],
96
+ "summary": "Get raw display entry under self.displays.{displayId}",
97
+ "responses": {
98
+ "200": { "description": "Display object", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnyObjectOrNull" } } } },
99
+ "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
100
+ "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
101
+ }
102
+ },
103
+ "put": {
104
+ "tags": ["Displays"],
105
+ "summary": "Set display entry under self.displays.{displayId}",
106
+ "requestBody": {
107
+ "required": false,
108
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnyObjectOrNull" } } }
109
+ },
110
+ "responses": {
111
+ "200": { "description": "Updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuccessResponse" } } } },
112
+ "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
113
+ }
114
+ }
115
+ },
116
+ "/plugins/kip/displays/{displayId}/activeScreen": {
117
+ "parameters": [{ "$ref": "#/components/parameters/DisplayIdParam" }],
118
+ "get": {
119
+ "tags": ["Displays"],
120
+ "summary": "Get active screen index for display",
121
+ "responses": {
122
+ "200": { "description": "Active screen index or null", "content": { "application/json": { "schema": { "type": "integer", "nullable": true } } } },
123
+ "404": { "description": "Not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
124
+ "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
125
+ }
126
+ },
127
+ "put": {
128
+ "tags": ["Displays"],
129
+ "summary": "Set active screen index for display",
130
+ "requestBody": {
131
+ "required": false,
132
+ "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ActiveScreenSetRequest" } } }
133
+ },
134
+ "responses": {
135
+ "200": { "description": "Updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuccessResponse" } } } },
136
+ "400": { "description": "Bad request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ }
@@ -478,58 +478,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
478
478
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
479
479
  SOFTWARE.
480
480
 
481
- --------------------------------------------------------------------------------
482
- Package: @angular/router
483
- License: "MIT"
484
-
485
- The MIT License
486
-
487
- Copyright (c) 2010-2025 Google LLC. https://angular.dev/license
488
-
489
- Permission is hereby granted, free of charge, to any person obtaining a copy
490
- of this software and associated documentation files (the "Software"), to deal
491
- in the Software without restriction, including without limitation the rights
492
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
493
- copies of the Software, and to permit persons to whom the Software is
494
- furnished to do so, subject to the following conditions:
495
-
496
- The above copyright notice and this permission notice shall be included in
497
- all copies or substantial portions of the Software.
498
-
499
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
500
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
501
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
502
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
503
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
504
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
505
- THE SOFTWARE.
506
-
507
- --------------------------------------------------------------------------------
508
- Package: compare-versions
509
- License: "MIT"
510
-
511
- The MIT License (MIT)
512
-
513
- Copyright (c) 2015-2021 Ole Michelsen
514
-
515
- Permission is hereby granted, free of charge, to any person obtaining a copy
516
- of this software and associated documentation files (the "Software"), to deal
517
- in the Software without restriction, including without limitation the rights
518
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
519
- copies of the Software, and to permit persons to whom the Software is
520
- furnished to do so, subject to the following conditions:
521
-
522
- The above copyright notice and this permission notice shall be included in all
523
- copies or substantial portions of the Software.
524
-
525
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
526
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
527
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
528
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
529
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
530
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
531
- SOFTWARE.
532
-
533
481
  --------------------------------------------------------------------------------
534
482
  Package: rxjs
535
483
  License: "Apache-2.0"
@@ -789,6 +737,32 @@ maintained libraries used by this software which have their own
789
737
  licenses; we recommend you read them, as their terms may differ from the
790
738
  terms above.
791
739
 
740
+ --------------------------------------------------------------------------------
741
+ Package: compare-versions
742
+ License: "MIT"
743
+
744
+ The MIT License (MIT)
745
+
746
+ Copyright (c) 2015-2021 Ole Michelsen
747
+
748
+ Permission is hereby granted, free of charge, to any person obtaining a copy
749
+ of this software and associated documentation files (the "Software"), to deal
750
+ in the Software without restriction, including without limitation the rights
751
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
752
+ copies of the Software, and to permit persons to whom the Software is
753
+ furnished to do so, subject to the following conditions:
754
+
755
+ The above copyright notice and this permission notice shall be included in all
756
+ copies or substantial portions of the Software.
757
+
758
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
759
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
760
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
761
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
762
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
763
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
764
+ SOFTWARE.
765
+
792
766
  --------------------------------------------------------------------------------
793
767
  Package: @angular/forms
794
768
  License: "MIT"
@@ -883,6 +857,32 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
883
857
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
884
858
  THE SOFTWARE.
885
859
 
860
+ --------------------------------------------------------------------------------
861
+ Package: @angular/router
862
+ License: "MIT"
863
+
864
+ The MIT License
865
+
866
+ Copyright (c) 2010-2025 Google LLC. https://angular.dev/license
867
+
868
+ Permission is hereby granted, free of charge, to any person obtaining a copy
869
+ of this software and associated documentation files (the "Software"), to deal
870
+ in the Software without restriction, including without limitation the rights
871
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
872
+ copies of the Software, and to permit persons to whom the Software is
873
+ furnished to do so, subject to the following conditions:
874
+
875
+ The above copyright notice and this permission notice shall be included in
876
+ all copies or substantial portions of the Software.
877
+
878
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
879
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
880
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
881
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
882
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
883
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
884
+ THE SOFTWARE.
885
+
886
886
  --------------------------------------------------------------------------------
887
887
  Package: core-js
888
888
  License: "MIT"
@@ -3,8 +3,8 @@ KIP supports multiple input modes for seamless navigation across devices.
3
3
 
4
4
  | Actions | Touch | Mouse | Keyboard Shortcuts |
5
5
  |----------------------------|--------------|------------------------------|----------------------------------------------------|
6
- | Open Actions menu | Swipe left | Click, drag left, and release| <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>←</kbd> (Left Arrow) |
7
- | Open Notification menu | Swipe right | Click, drag right, and release| <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>→</kbd> (Right Arrow) |
6
+ | Open Actions sidenav | Swipe left | Click, drag left, and release| <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>←</kbd> (Left Arrow) |
7
+ | Open Notification sidenav | Swipe right | Click, drag right, and release| <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>→</kbd> (Right Arrow) |
8
8
  | Cycle through dashboards | Swipe up/down | Click, drag up/down, and release| <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>↑</kbd>/<kbd>↓</kbd> (Up/Down Arrow) |
9
9
  | Toggle Fullscreen | N/A | N/A | <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>F</kbd> |
10
10
  | Toggle Night mode | N/A | N/A | <kbd>Shift</kbd> + <kbd>Ctrl</kbd> + <kbd>N</kbd> |
@@ -59,12 +59,16 @@
59
59
  <path fill="currentColor" d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2m0 16H5V5h14z" />
60
60
  <path fill="var(--mat-sys-primary)" d="M7 7h4v4H7zm6 0h4v4h-4z" />
61
61
  </svg>
62
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14" id="settings" height="14" width="14">
62
+ <svg id="settings" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14" height="14" width="14">
63
63
  <path fill="none" d="m4.093 3.976 0.36 -0.93a0.838 0.838 0 0 1 0.78 -0.536h0.687a0.838 0.838 0 0 1 0.779 0.536l0.36 0.93 1.223 0.704 0.99 -0.151a0.838 0.838 0 0 1 0.837 0.41l0.335 0.587a0.837 0.837 0 0 1 -0.067 0.947l-0.612 0.779v1.407l0.629 0.78a0.838 0.838 0 0 1 0.067 0.946l-0.335 0.587a0.837 0.837 0 0 1 -0.838 0.41l-0.989 -0.15 -1.223 0.703 -0.36 0.93a0.838 0.838 0 0 1 -0.78 0.536h-0.703a0.838 0.838 0 0 1 -0.78 -0.536l-0.36 -0.93 -1.223 -0.704 -0.988 0.151a0.838 0.838 0 0 1 -0.838 -0.41l-0.335 -0.587a0.838 0.838 0 0 1 0.067 -0.946l0.611 -0.78V7.252l-0.628 -0.78a0.838 0.838 0 0 1 -0.067 -0.946l0.335 -0.586a0.838 0.838 0 0 1 0.838 -0.411l0.988 0.15 1.24 -0.703Zm-0.192 3.98a1.676 1.676 0 1 0 3.351 0 1.676 1.676 0 0 0 -3.351 0Z" stroke-width="1"></path>
64
64
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M5.92 2.51h-0.687a0.838 0.838 0 0 0 -0.78 0.536l-0.36 0.93 -1.24 0.704 -0.988 -0.151a0.838 0.838 0 0 0 -0.838 0.41l-0.335 0.587a0.838 0.838 0 0 0 0.067 0.947l0.628 0.779v1.407l-0.611 0.78a0.838 0.838 0 0 0 -0.067 0.946l0.335 0.587a0.837 0.837 0 0 0 0.838 0.41l0.988 -0.15 1.223 0.703 0.36 0.93a0.838 0.838 0 0 0 0.78 0.536h0.704a0.838 0.838 0 0 0 0.779 -0.536l0.36 -0.93 1.223 -0.704 0.989 0.151a0.838 0.838 0 0 0 0.838 -0.41l0.335 -0.587a0.838 0.838 0 0 0 -0.067 -0.946l-0.629 -0.78v-0.907m-5.864 0.204a1.676 1.676 0 1 0 3.351 0 1.676 1.676 0 0 0 -3.351 0Z" stroke-width="1"></path>
65
65
  <path fill="var(--mat-sys-primary)" d="M8.1 3.603c-0.306 -0.053 -0.306 -0.494 0 -0.548A2.779 2.779 0 0 0 10.34 0.912l0.018 -0.085c0.067 -0.303 0.499 -0.305 0.568 -0.002l0.023 0.098a2.793 2.793 0 0 0 2.244 2.13c0.309 0.055 0.309 0.498 0 0.551a2.793 2.793 0 0 0 -2.244 2.131l-0.023 0.099c-0.069 0.302 -0.501 0.3 -0.568 -0.003l-0.018 -0.084a2.779 2.779 0 0 0 -2.238 -2.144Z" stroke-width="1"></path>
66
66
  <path stroke="var(--mat-sys-primary)" stroke-linecap="round" stroke-linejoin="round" d="M8.1 3.603c-0.306 -0.053 -0.306 -0.494 0 -0.548A2.779 2.779 0 0 0 10.34 0.912l0.018 -0.085c0.067 -0.303 0.499 -0.305 0.568 -0.002l0.023 0.098a2.793 2.793 0 0 0 2.244 2.13c0.309 0.055 0.309 0.498 0 0.551a2.793 2.793 0 0 0 -2.244 2.131l-0.023 0.099c-0.069 0.302 -0.501 0.3 -0.568 -0.003l-0.018 -0.084a2.779 2.779 0 0 0 -2.238 -2.144Z" stroke-width="1"></path>
67
67
  </svg>
68
+ <svg id="remote-control" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16" height="16" width="16">
69
+ <path fill="var(--mat-sys-primary)" fill-opacity="0.5" d="M14 3.5v9c0 0.132625 -0.0526875 0.2598125 -0.1464375 0.3535625S13.632625 13 13.5 13H3c0 -0.2651875 -0.10535625 -0.5195625 -0.29289375 -0.707125C2.51956875 12.105375 2.26521875 12 2 12V3.5c0 -0.13260625 0.05268125 -0.2597875 0.14644375 -0.35355625C2.2402125 3.05268125 2.36739375 3 2.5 3h11c0.132625 0 0.2598125 0.05268125 0.3535625 0.14644375C13.9473125 3.2402125 14 3.36739375 14 3.5Z" stroke-width="1"></path>
70
+ <path fill="currentColor" d="M14.5 3.5v9c0 0.2651875 -0.105375 0.5195625 -0.292875 0.707125 -0.1875625 0.1875 -0.4419375 0.292875 -0.707125 0.292875h-4.5c-0.132625 0 -0.2598125 -0.0526875 -0.3535625 -0.1464375S8.5 13.132625 8.5 13s0.0526875 -0.2598125 0.1464375 -0.3535625S8.867375 12.5 9 12.5h4.5V3.5H2.5v2.5c0 0.13260625 -0.05268125 0.2598125 -0.14644375 0.3535625C2.2597875 6.4473125 2.13260625 6.5 2 6.5s-0.2597875 -0.0526875 -0.35355625 -0.1464375C1.55268125 6.2598125 1.5 6.13260625 1.5 6V3.5c0 -0.26521875 0.10535625 -0.51956875 0.29289375 -0.70710625C1.98043125 2.60535625 2.23478125 2.5 2.5 2.5h11c0.2651875 0 0.5195625 0.10535625 0.707125 0.29289375C14.394625 2.98043125 14.5 3.23478125 14.5 3.5ZM2 11.5c-0.13260625 0 -0.2597875 0.0526875 -0.35355625 0.1464375C1.55268125 11.7401875 1.5 11.867375 1.5 12s0.05268125 0.2598125 0.14644375 0.3535625C1.7402125 12.4473125 1.86739375 12.5 2 12.5s0.2597875 0.0526875 0.35355625 0.1464375C2.44731875 12.7401875 2.5 12.867375 2.5 13s0.05268125 0.2598125 0.14644375 0.3535625C2.7402125 13.4473125 2.86739375 13.5 3 13.5s0.2597875 -0.0526875 0.35355625 -0.1464375C3.44731875 13.2598125 3.5 13.132625 3.5 13c0 -0.3978125 -0.1580375 -0.779375 -0.4393375 -1.0606875C2.77935625 11.6580625 2.397825 11.5 2 11.5Zm0 -2c-0.13260625 0 -0.2597875 0.0526875 -0.35355625 0.1464375C1.55268125 9.7401875 1.5 9.867375 1.5 10s0.05268125 0.2598125 0.14644375 0.3535625C1.7402125 10.4473125 1.86739375 10.5 2 10.5c0.66304375 0 1.298925 0.263375 1.76776875 0.73225C4.23660625 11.7010625 4.5 12.3369375 4.5 13c0 0.132625 0.05268125 0.2598125 0.14644375 0.3535625C4.7402125 13.4473125 4.86739375 13.5 5 13.5s0.2597875 -0.0526875 0.35355625 -0.1464375C5.44731875 13.2598125 5.5 13.132625 5.5 13c-0.00099375 -0.9279375 -0.3700625 -1.817625 -1.026225 -2.47375C3.8176125 9.8700625 2.92795 9.501 2 9.5Zm0 -2c-0.13260625 0 -0.2597875 0.0526875 -0.35355625 0.1464375C1.55268125 7.7401875 1.5 7.867375 1.5 8s0.05268125 0.2598125 0.14644375 0.3535625C1.7402125 8.4473125 1.86739375 8.5 2 8.5c1.19306875 0.0013125 2.33689375 0.475875 3.18051875 1.3195C6.02414375 10.663125 6.4986875 11.8069375 6.5 13c0 0.132625 0.0526875 0.2598125 0.1464375 0.3535625S6.867375 13.5 7 13.5s0.2598125 -0.0526875 0.3535625 -0.1464375S7.5 13.132625 7.5 13c-0.001625 -1.4581875 -0.581625 -2.8561875 -1.6127375 -3.88725C4.85616875 8.081625 3.45818125 7.501625 2 7.5Z" stroke-width="1"></path>
71
+ </svg>
68
72
  <svg id="help-center" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
69
73
  <circle fill="currentColor" fill-opacity="0" stroke="currentColor" stroke-width="2" cx="12" cy="13" r="9" />
70
74
  <text fill="var(--mat-sys-primary)" x="12" y="19" font-size="16" font-family="Roboto" font-style="bolder" text-anchor="middle" >?</text>