@homebridge-plugins/homebridge-sharkiq 2.0.0-beta.3 → 2.0.0-beta.31

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 (47) hide show
  1. package/CHANGELOG.md +19 -2
  2. package/README.md +41 -4
  3. package/config.schema.json +8 -26
  4. package/dist/constants.d.ts.map +1 -1
  5. package/dist/constants.js.map +1 -1
  6. package/dist/devices/BaseMatterAccessory.d.ts +74 -0
  7. package/dist/devices/BaseMatterAccessory.d.ts.map +1 -0
  8. package/dist/devices/BaseMatterAccessory.js +210 -0
  9. package/dist/devices/BaseMatterAccessory.js.map +1 -0
  10. package/dist/devices/RoboticVacuumAccessory.d.ts +85 -0
  11. package/dist/devices/RoboticVacuumAccessory.d.ts.map +1 -0
  12. package/dist/devices/RoboticVacuumAccessory.js +944 -0
  13. package/dist/devices/RoboticVacuumAccessory.js.map +1 -0
  14. package/dist/devices/index.d.ts +9 -0
  15. package/dist/devices/index.d.ts.map +1 -0
  16. package/dist/devices/index.js +8 -0
  17. package/dist/devices/index.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +3 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/login.js +1 -1
  23. package/dist/login.js.map +1 -1
  24. package/dist/platform.d.ts +39 -16
  25. package/dist/platform.d.ts.map +1 -1
  26. package/dist/platform.js +196 -104
  27. package/dist/platform.js.map +1 -1
  28. package/dist/sharkiq-js/ayla_api.js.map +1 -1
  29. package/dist/sharkiq-js/room_encoding.d.ts +8 -0
  30. package/dist/sharkiq-js/room_encoding.d.ts.map +1 -0
  31. package/dist/sharkiq-js/room_encoding.js +35 -0
  32. package/dist/sharkiq-js/room_encoding.js.map +1 -0
  33. package/dist/sharkiq-js/sharkiq.d.ts.map +1 -1
  34. package/dist/sharkiq-js/sharkiq.js +4 -20
  35. package/dist/sharkiq-js/sharkiq.js.map +1 -1
  36. package/docs/assets/highlight.css +9 -2
  37. package/docs/index.html +35 -3
  38. package/docs/variables/default.html +2 -1
  39. package/package.json +15 -15
  40. package/dist/errorHandling.d.ts +0 -19
  41. package/dist/errorHandling.d.ts.map +0 -1
  42. package/dist/errorHandling.js +0 -27
  43. package/dist/errorHandling.js.map +0 -1
  44. package/dist/platformAccessory.d.ts +0 -33
  45. package/dist/platformAccessory.d.ts.map +0 -1
  46. package/dist/platformAccessory.js +0 -384
  47. package/dist/platformAccessory.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -2,11 +2,27 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. This project uses [Semantic Versioning](https://semver.org/)
4
4
 
5
- ## [1.4.1] (TBD)
5
+ ## [2.0.0] (https://github.com/homebridge-plugins/homebridge-sharkiq/releases/tag/v2.0.0) (2025-XX-XX)
6
+
7
+ ### Breaking Changes
8
+ - This release is Matter-only. The plugin now publishes external Matter Robotic Vacuum Cleaner accessories and no longer publishes HAP platform accessories. If you need the legacy HAP behavior, continue using a pre-2.0 release or a branch that preserves the HAP path.
9
+ - Minimum required Homebridge: >= 2.0.0-alpha.28 (or later) with Matter support exposed via `api.matter`.
10
+
11
+ ### What's Changed
12
+ - Converted plugin to Matter-only and added Matter external accessory publishing for Robotic Vacuum Cleaner devices.
13
+ - Added lifecycle wiring so accessories wait for READY before initial sync and polling.
14
+ - Added retry/backoff for critical Ayla API calls.
15
+ - Removed HAP-specific configuration options (invertDockedStatus, dockedUpdateInterval, enhancedVacuumMode).
16
+
17
+ **Full Changelog**: https://github.com/homebridge-plugins/homebridge-sharkiq/compare/v1.4.1...v2.0.0
18
+
19
+ ## [1.4.1] (https://github.com/homebridge-plugins/homebridge-sharkiq/releases/tag/v1.4.1) (2025-XX-XX)
6
20
 
7
21
  ### What's Changed
8
22
  - Fix ARM64 OAuth code handling for users with both email/password and OAuth code [#54](https://github.com/homebridge-plugins/homebridge-sharkiq/issues/54)
9
23
 
24
+ **Full Changelog**: https://github.com/homebridge-plugins/homebridge-sharkiq/compare/v1.4.0...v1.4.1
25
+
10
26
  ## [1.4.0](https://github.com/homebridge-plugins/homebridge-sharkiq/releases/tag/v1.4.0) (2025-07-17)
11
27
 
12
28
  ### What's Changes
@@ -14,4 +30,5 @@ All notable changes to this project will be documented in this file. This projec
14
30
  - Fix JSON parsing errors in SharkIQ API responses [#44](https://github.com/homebridge-plugins/homebridge-sharkiq/pull/44) [@mmenanno](https://github.com/mmenanno)
15
31
  - Housekeeping and updated dependencies.
16
32
 
17
- **Full Changelog**: https://github.com/homebridge-plugins/homebridge-sharkiq/compare/v1.3.2...v1.4.0
33
+ **Full Changelog**: https://github.com/homebridge-plugins/homebridge-sharkiq/compare/v1.3.2...v1.4.0
34
+
package/README.md CHANGED
@@ -39,10 +39,7 @@ Configure Homebridge. The config file for SharkIQ should include:
39
39
  "[Shark Vacuum DSN]",
40
40
  "..."
41
41
  ],
42
- "europe": false,
43
- "invertDockedStatus": false,
44
- "dockedUpdateInterval": 30000,
45
- "enhancedVacuumMode": true
42
+ "europe": false
46
43
  }
47
44
  ]
48
45
  }
@@ -78,6 +75,15 @@ The `enhancedVacuumMode` option (enabled by default) provides improved vacuum be
78
75
 
79
76
  ## Homebridge 2.0.0+ Compatibility
80
77
 
78
+ This release of the plugin is Matter-only and requires a Homebridge runtime that exposes the Matter API.
79
+ Minimum tested Homebridge: 2.0.0-alpha.28 or later. If your Homebridge installation does not support Matter, this plugin will log an error and will not start.
80
+
81
+ This plugin uses Matter external accessories (Robotic Vacuum Cleaner) to integrate with the platform and no longer publishes HAP platform accessories.
82
+
83
+ If you rely on the legacy HAP (HomeKit) path, keep using an older plugin release or run this code from a separate branch — this release intentionally removes HAP fallback.
84
+
85
+ Compatibility notes and behavior:
86
+
81
87
  This plugin is compatible with Homebridge 2.0.0-alpha.28 and later versions, providing enhanced vacuum functionality while maintaining compatibility with current HomeKit limitations:
82
88
 
83
89
  - **Current Implementation**: Uses optimized FanV2 service with vacuum-specific behavior
@@ -109,3 +115,34 @@ Contributions would be very helpful to help this Homebridge plugin stay maintain
109
115
  ## Useful Links
110
116
 
111
117
  - [SharkIQ Python](https://github.com/JeffResc/sharkiq/)
118
+
119
+ ## Integration checklist — Matter
120
+
121
+ Follow these steps to verify Matter integration locally on a Homebridge instance that supports Matter (Homebridge >= 2.0.0-alpha.28):
122
+
123
+ 1. Ensure your Homebridge runtime supports Matter and the `api.matter` external accessory API.
124
+ 2. Configure the plugin in `config.json` with your Shark credentials or `oAuthCode` and do NOT include deprecated HAP-only options (the plugin is Matter-only).
125
+ 3. Start Homebridge in a terminal and watch logs. You should see the plugin log the DSNs found on your account and then a "Publishing X robotic device(s) as external Matter accessories" message.
126
+ 4. After publishing, Homebridge should emit READY/COMMISSIONED events for each accessory. The plugin will perform an initial sync and start polling.
127
+ 5. From the Home app or a Matter controller, attempt these actions and verify the vacuum responds:
128
+
129
+ - Start / Stop cleaning
130
+ - Pause / Resume
131
+ - Go Home (return to dock)
132
+ - Select Areas (if your device supports area cleaning)
133
+
134
+ 6. Observe plugin logs for successful API calls and state updates. Look for `Matter accessory ready` and `Performing initial device sync` log lines.
135
+
136
+ Quick troubleshooting:
137
+
138
+ - If you see "requires Homebridge with Matter support" in logs, update Homebridge to a Matter-enabled build.
139
+ - If actions fail, inspect network connectivity and plugin logs for Ayla API errors; the plugin now includes retries with exponential backoff for critical calls.
140
+
141
+ Optional: run the prepublish checks locally (lint, build, docs) to validate everything before publishing:
142
+
143
+ ```bash
144
+ # Run this in the project root (macOS / zsh)
145
+ npm run prepublishOnly
146
+ ```
147
+
148
+ If you'd like, I can add a short automated script that validates a sample run (requires a Matter-enabled Homebridge instance and credentials).
@@ -30,7 +30,7 @@
30
30
  "vacuums": {
31
31
  "title": "SharkClean Vacuum Devicess",
32
32
  "type": "array",
33
- "required": true,
33
+ "required": false,
34
34
  "items": {
35
35
  "title": "SharkClean DSN",
36
36
  "type": "string"
@@ -43,25 +43,14 @@
43
43
  "required": false,
44
44
  "default": false
45
45
  },
46
- "invertDockedStatus": {
47
- "title": "Invert Vacuum Docked Status",
48
- "type": "boolean",
49
- "required": false,
50
- "default": false
51
- },
52
- "dockedUpdateInterval": {
53
- "title": "Docked Update Interval",
54
- "type": "integer",
46
+ "pollInterval": {
47
+ "title": "Polling interval (seconds)",
48
+ "description": "How often to poll Shark devices for status updates. Set to 0 to disable polling.",
49
+ "type": "number",
55
50
  "required": false,
56
- "default": 30000
57
- },
58
- "enhancedVacuumMode": {
59
- "title": "Enhanced Vacuum Mode",
60
- "type": "boolean",
61
- "required": false,
62
- "default": true,
63
- "description": "Use improved power level mappings and vacuum-optimized behavior. Prepares for future robot vacuum service support."
51
+ "default": 30
64
52
  }
53
+
65
54
  }
66
55
  },
67
56
  "layout": [
@@ -113,14 +102,7 @@
113
102
  }
114
103
  ]
115
104
  },
116
- "europe",
117
- "invertDockedStatus",
118
- "dockedUpdateInterval",
119
- {
120
- "type": "help",
121
- "helpvalue": "<h5>Enhanced Vacuum Mode</h5><em class='primary-text'>Enables improved vacuum behavior with better power level mappings (25%=Eco, 50%=Normal, 100%=Max). This prepares your setup for future native HomeKit robot vacuum support.</em>"
122
- },
123
- "enhancedVacuumMode"
105
+ "europe"
124
106
  ]
125
107
  }
126
108
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,aAAa;;;;;CAKhB,CAAC;AAEX,eAAO,MAAM,QAAQ;;;;;;CAMX,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,aAAa;;;;;CAKhB,CAAA;AAEV,eAAO,MAAM,QAAQ;;;;;;CAMX,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,EAAE;IACV,GAAG,EAAE,EAAE;CACC,CAAC;AAEX,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,IAAI;IACnB,mBAAmB,EAAE,GAAG;IACxB,8BAA8B,EAAE,IAAI;IACpC,uBAAuB,EAAE,GAAG;CACpB,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,EAAE;IACV,GAAG,EAAE,EAAE;CACC,CAAA;AAEV,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,IAAI;IACnB,mBAAmB,EAAE,GAAG;IACxB,8BAA8B,EAAE,IAAI;IACpC,uBAAuB,EAAE,GAAG;CACpB,CAAA"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Base Matter Accessory Class
3
+ *
4
+ * This base class implements the MatterAccessory interface and provides
5
+ * common functionality that all Matter devices can use.
6
+ *
7
+ * Individual device types should extend this class and call super() with
8
+ * the required configuration.
9
+ */
10
+ import type { API, EndpointType, Logger, MatterAccessory } from 'homebridge';
11
+ export interface BaseMatterAccessoryConfig {
12
+ uuid: string;
13
+ displayName: string;
14
+ deviceType: EndpointType;
15
+ serialNumber: string;
16
+ manufacturer: string;
17
+ model: string;
18
+ firmwareRevision: string;
19
+ hardwareRevision: string;
20
+ context?: Record<string, unknown>;
21
+ clusters?: MatterAccessory['clusters'];
22
+ handlers?: MatterAccessory['handlers'];
23
+ parts?: MatterAccessory['parts'];
24
+ /** Optional mapping from legacy cluster names to supported cluster names. */
25
+ clusterNameMap?: Record<string, string>;
26
+ /** Enable translation behavior for legacy clusters like 'power' and 'diagnostics'. */
27
+ translateLegacyClusters?: boolean;
28
+ }
29
+ /**
30
+ * Base class for all Matter accessories
31
+ * Implements the MatterAccessory interface and provides common methods
32
+ */
33
+ export declare abstract class BaseMatterAccessory implements MatterAccessory {
34
+ /** In-memory cache for battery/charging state to suppress noisy logs */
35
+ protected lastBatteryLevel: number | null;
36
+ protected lastChargingStatus: boolean | null;
37
+ readonly uuid: string;
38
+ readonly displayName: string;
39
+ readonly deviceType: EndpointType;
40
+ readonly serialNumber: string;
41
+ readonly manufacturer: string;
42
+ readonly model: string;
43
+ readonly firmwareRevision: string;
44
+ readonly hardwareRevision: string;
45
+ readonly context: Record<string, unknown>;
46
+ readonly clusters?: MatterAccessory['clusters'];
47
+ readonly handlers?: MatterAccessory['handlers'];
48
+ readonly parts?: MatterAccessory['parts'];
49
+ /** Optional mapping table for legacy cluster names */
50
+ readonly clusterNameMap?: Record<string, string>;
51
+ /** Whether to translate legacy clusters (can be toggled at runtime via context.translateLegacyClusters) */
52
+ protected readonly translateLegacyClusters: boolean;
53
+ protected readonly api: API;
54
+ protected readonly log: Logger;
55
+ constructor(api: API, log: Logger, config: BaseMatterAccessoryConfig);
56
+ /**
57
+ * Update the accessory state
58
+ * Helper method to update cluster attributes
59
+ */
60
+ protected updateState(cluster: string, attributes: Record<string, unknown>): Promise<void>;
61
+ /**
62
+ * Log helper methods
63
+ */
64
+ protected logInfo(message: string, ...args: unknown[]): void;
65
+ protected logError(message: string, ...args: unknown[]): void;
66
+ protected logDebug(message: string, ...args: unknown[]): void;
67
+ protected logWarn(message: string, ...args: unknown[]): void;
68
+ /**
69
+ * Convert this class instance to a plain MatterAccessory object
70
+ * This is what gets registered with Homebridge
71
+ */
72
+ toAccessory(): MatterAccessory;
73
+ }
74
+ //# sourceMappingURL=BaseMatterAccessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseMatterAccessory.d.ts","sourceRoot":"","sources":["../../src/devices/BaseMatterAccessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Base Matter Accessory Class
3
+ *
4
+ * This base class implements the MatterAccessory interface and provides
5
+ * common functionality that all Matter devices can use.
6
+ *
7
+ * Individual device types should extend this class and call super() with
8
+ * the required configuration.
9
+ */
10
+ /**
11
+ * Base class for all Matter accessories
12
+ * Implements the MatterAccessory interface and provides common methods
13
+ */
14
+ export class BaseMatterAccessory {
15
+ /** In-memory cache for battery/charging state to suppress noisy logs */
16
+ lastBatteryLevel = null;
17
+ lastChargingStatus = null;
18
+ // Required MatterAccessory properties
19
+ uuid;
20
+ displayName;
21
+ deviceType;
22
+ serialNumber;
23
+ manufacturer;
24
+ model;
25
+ firmwareRevision;
26
+ hardwareRevision;
27
+ context;
28
+ clusters;
29
+ handlers;
30
+ parts;
31
+ /** Optional mapping table for legacy cluster names */
32
+ clusterNameMap;
33
+ /** Whether to translate legacy clusters (can be toggled at runtime via context.translateLegacyClusters) */
34
+ translateLegacyClusters;
35
+ // Protected properties available to child classes
36
+ api;
37
+ log;
38
+ constructor(api, log, config) {
39
+ this.api = api;
40
+ this.log = log;
41
+ // Set all required properties
42
+ this.uuid = config.uuid;
43
+ this.displayName = config.displayName;
44
+ this.deviceType = config.deviceType;
45
+ this.serialNumber = config.serialNumber;
46
+ this.manufacturer = config.manufacturer;
47
+ this.model = config.model;
48
+ this.firmwareRevision = config.firmwareRevision;
49
+ this.hardwareRevision = config.hardwareRevision;
50
+ this.clusters = config.clusters;
51
+ this.handlers = config.handlers;
52
+ this.parts = config.parts;
53
+ this.clusterNameMap = config.clusterNameMap || {};
54
+ this.translateLegacyClusters = typeof config.translateLegacyClusters === 'boolean' ? config.translateLegacyClusters : true;
55
+ // Set context with all metadata
56
+ this.context = {
57
+ serialNumber: this.serialNumber,
58
+ manufacturer: this.manufacturer,
59
+ model: this.model,
60
+ firmwareRevision: this.firmwareRevision,
61
+ hardwareRevision: this.hardwareRevision,
62
+ ...config.context,
63
+ };
64
+ }
65
+ /**
66
+ * Update the accessory state
67
+ * Helper method to update cluster attributes
68
+ */
69
+ async updateState(cluster, attributes) {
70
+ // First, allow a configured mapping from legacy cluster names to the
71
+ // clusters we actually registered. This supports older code paths that
72
+ // attempted to update clusters like 'power' or 'diagnostics'. The mapping
73
+ // is optional and can be provided per-accessory via config.
74
+ const mapped = (this.clusterNameMap && this.clusterNameMap[cluster]) || cluster;
75
+ // If the mapped cluster exists on this accessory and this is not a
76
+ // legacy cluster that requires translation, forward the update.
77
+ const isLegacy = cluster === 'power' || cluster === 'diagnostics';
78
+ if (this.clusters && (mapped in this.clusters) && !isLegacy) {
79
+ try {
80
+ await this.api.matter.updateAccessoryState(this.uuid, mapped, attributes);
81
+ this.log.debug(`[${this.displayName}] Updated ${mapped} state (from ${cluster}):`, attributes);
82
+ }
83
+ catch (e) {
84
+ // Matter may report the accessory as not registered when running
85
+ // in Child/Bridge configurations; surface as debug to avoid
86
+ // noisy stack traces while still recording the failure.
87
+ this.logDebug(`Failed to update ${mapped} state (from ${cluster}): ${e?.message || e}`);
88
+ }
89
+ return;
90
+ }
91
+ // Special-case handling for legacy clusters when no direct mapping exists.
92
+ // These translate a small set of commonly-updated attributes into updates
93
+ // against supported clusters (for vacuum devices we commonly support
94
+ // 'rvcOperationalState'). This avoids noisy "Behavior ID ... does not
95
+ // exist" errors while preserving useful state updates.
96
+ // Determine whether translations are enabled for this accessory at runtime.
97
+ const runtimeTranslate = typeof this.context.translateLegacyClusters === 'boolean'
98
+ ? this.context.translateLegacyClusters
99
+ : this.translateLegacyClusters;
100
+ if (cluster === 'power') {
101
+ // batteryLevel and charging are informational. If charging is present
102
+ // and we have rvcOperationalState, translate charging->Charging(65)
103
+ // or not-charging->Docked(66). Also log battery percentage locally.
104
+ const batteryLevel = attributes.batteryLevel;
105
+ const charging = attributes.charging;
106
+ if (typeof batteryLevel === 'number') {
107
+ // Use in-memory cache to suppress noisy logs
108
+ const chargingBool = typeof charging === 'boolean' ? charging : (charging === 1);
109
+ const batteryChanged = this.lastBatteryLevel === null || this.lastBatteryLevel !== batteryLevel;
110
+ const chargingChanged = this.lastChargingStatus === null || this.lastChargingStatus !== chargingBool;
111
+ if (batteryChanged || chargingChanged) {
112
+ this.logInfo(`battery updated (via legacy 'power'): ${batteryLevel}%`);
113
+ }
114
+ else {
115
+ this.logDebug(`legacy 'power' battery unchanged: ${batteryLevel}% (charging: ${String(chargingBool)})`);
116
+ }
117
+ // Always update the in-memory cache
118
+ this.lastBatteryLevel = batteryLevel;
119
+ this.lastChargingStatus = chargingBool;
120
+ }
121
+ if (runtimeTranslate && typeof charging !== 'undefined') {
122
+ // Choose the target cluster to update. Prefer an explicit mapping
123
+ // if provided, otherwise fall back to rvcOperationalState when
124
+ // available.
125
+ const target = (this.clusterNameMap && this.clusterNameMap[cluster]) || 'rvcOperationalState';
126
+ const targetExists = this.clusters && (target in this.clusters);
127
+ const rvcExists = this.clusters && ('rvcOperationalState' in this.clusters);
128
+ if (targetExists || rvcExists) {
129
+ const isCharging = charging === true || charging === 1;
130
+ const opState = isCharging ? 65 : 66;
131
+ const chosen = targetExists ? target : 'rvcOperationalState';
132
+ try {
133
+ await this.api.matter.updateAccessoryState(this.uuid, chosen, { operationalState: opState });
134
+ this.log.debug(`[${this.displayName}] Translated legacy 'power' charging=${String(charging)} -> ${chosen}=${opState}`);
135
+ }
136
+ catch (e) {
137
+ this.logDebug(`Failed to translate legacy 'power' charging=${String(charging)} -> ${chosen}: ${e?.message || e}`);
138
+ }
139
+ return;
140
+ }
141
+ }
142
+ const available = this.clusters ? Object.keys(this.clusters).join(', ') : '(none)';
143
+ this.logWarn(`Attempt to update legacy cluster 'power' but no mapping or supported target found. Available clusters: ${available}`);
144
+ return;
145
+ }
146
+ if (cluster === 'diagnostics') {
147
+ // diagnostics commonly carries an errorCode. If present and non-zero,
148
+ // translate to rvcOperationalState Error (3) when supported.
149
+ const errorCode = attributes.errorCode;
150
+ if (runtimeTranslate && typeof errorCode === 'number' && errorCode > 0) {
151
+ const target = (this.clusterNameMap && this.clusterNameMap[cluster]) || 'rvcOperationalState';
152
+ const targetExists = this.clusters && (target in this.clusters);
153
+ const rvcExists = this.clusters && ('rvcOperationalState' in this.clusters);
154
+ if (targetExists || rvcExists) {
155
+ const chosen = targetExists ? target : 'rvcOperationalState';
156
+ try {
157
+ await this.api.matter.updateAccessoryState(this.uuid, chosen, { operationalState: 3 });
158
+ this.logWarn(`[${this.displayName}] Translated legacy 'diagnostics' errorCode=${errorCode} -> ${chosen}=3 (Error)`);
159
+ }
160
+ catch (e) {
161
+ this.logDebug(`Failed to translate legacy 'diagnostics' errorCode=${errorCode} -> ${chosen}: ${e?.message || e}`);
162
+ }
163
+ return;
164
+ }
165
+ }
166
+ const available = this.clusters ? Object.keys(this.clusters).join(', ') : '(none)';
167
+ this.logDebug(`Attempt to update legacy cluster 'diagnostics' but no mapping or supported target found. Available clusters: ${available}`);
168
+ return;
169
+ }
170
+ // Fallback: warn and skip unknown clusters to avoid Matter server errors.
171
+ const available = this.clusters ? Object.keys(this.clusters).join(', ') : '(none)';
172
+ this.logWarn(`Attempt to update unknown cluster '${cluster}' (mapped to '${mapped}'). Available clusters: ${available}`);
173
+ }
174
+ /**
175
+ * Log helper methods
176
+ */
177
+ logInfo(message, ...args) {
178
+ this.log.info(`[${this.displayName}] ${message}`, ...args);
179
+ }
180
+ logError(message, ...args) {
181
+ this.log.error(`[${this.displayName}] ${message}`, ...args);
182
+ }
183
+ logDebug(message, ...args) {
184
+ this.log.debug(`[${this.displayName}] ${message}`, ...args);
185
+ }
186
+ logWarn(message, ...args) {
187
+ this.log.warn(`[${this.displayName}] ${message}`, ...args);
188
+ }
189
+ /**
190
+ * Convert this class instance to a plain MatterAccessory object
191
+ * This is what gets registered with Homebridge
192
+ */
193
+ toAccessory() {
194
+ return {
195
+ uuid: this.uuid,
196
+ displayName: this.displayName,
197
+ deviceType: this.deviceType,
198
+ serialNumber: this.serialNumber,
199
+ manufacturer: this.manufacturer,
200
+ model: this.model,
201
+ firmwareRevision: this.firmwareRevision,
202
+ hardwareRevision: this.hardwareRevision,
203
+ context: this.context,
204
+ clusters: this.clusters,
205
+ handlers: this.handlers,
206
+ parts: this.parts,
207
+ };
208
+ }
209
+ }
210
+ //# sourceMappingURL=BaseMatterAccessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseMatterAccessory.js","sourceRoot":"","sources":["../../src/devices/BaseMatterAccessory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH;;;GAGG;AACH,MAAM,OAAgB,mBAAmB;IACvC,wEAAwE;IAC9D,gBAAgB,GAAkB,IAAI,CAAA;IACtC,kBAAkB,GAAmB,IAAI,CAAA;IACnD,sCAAsC;IACtB,IAAI,CAAQ;IACZ,WAAW,CAAQ;IACnB,UAAU,CAAc;IACxB,YAAY,CAAQ;IACpB,YAAY,CAAQ;IACpB,KAAK,CAAQ;IACb,gBAAgB,CAAQ;IACxB,gBAAgB,CAAQ;IACxB,OAAO,CAAyB;IAChC,QAAQ,CAA8B;IACtC,QAAQ,CAA8B;IACtC,KAAK,CAA2B;IAChD,sDAAsD;IACtC,cAAc,CAAyB;IACvD,2GAA2G;IACxF,uBAAuB,CAAS;IAEnD,kDAAkD;IAC/B,GAAG,CAAK;IACR,GAAG,CAAQ;IAE9B,YACE,GAAQ,EACR,GAAW,EACX,MAAiC;QAEjC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QAEd,8BAA8B;QAC9B,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QACvB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAA;QACrC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;QACnC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAA;QACvC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAA;QACvC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;QACzB,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAA;QAC/C,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAA;QAC/C,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAC/B,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;QAC/B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;QACzB,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,EAAE,CAAA;QACjD,IAAI,CAAC,uBAAuB,GAAG,OAAO,MAAM,CAAC,uBAAuB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAA;QAE1H,gCAAgC;QAChC,IAAI,CAAC,OAAO,GAAG;YACb,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,GAAG,MAAM,CAAC,OAAO;SAClB,CAAA;IACH,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,UAAmC;QAC9E,qEAAqE;QACrE,uEAAuE;QACvE,0EAA0E;QAC1E,4DAA4D;QAC5D,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAA;QAE/E,mEAAmE;QACnE,gEAAgE;QAChE,MAAM,QAAQ,GAAG,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,aAAa,CAAA;QACjE,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC5D,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,CAAA;gBACzE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,aAAa,MAAM,gBAAgB,OAAO,IAAI,EAAE,UAAU,CAAC,CAAA;YAChG,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,iEAAiE;gBACjE,4DAA4D;gBAC5D,wDAAwD;gBACxD,IAAI,CAAC,QAAQ,CAAC,oBAAoB,MAAM,gBAAgB,OAAO,MAAM,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAA;YACzF,CAAC;YACD,OAAM;QACR,CAAC;QAED,2EAA2E;QAC3E,0EAA0E;QAC1E,qEAAqE;QACrE,sEAAsE;QACtE,uDAAuD;QACvD,4EAA4E;QAC5E,MAAM,gBAAgB,GAAG,OAAQ,IAAI,CAAC,OAAe,CAAC,uBAAuB,KAAK,SAAS;YACzF,CAAC,CAAE,IAAI,CAAC,OAAe,CAAC,uBAAuB;YAC/C,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAA;QAEhC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,sEAAsE;YACtE,oEAAoE;YACpE,oEAAoE;YACpE,MAAM,YAAY,GAAG,UAAU,CAAC,YAAkC,CAAA;YAClE,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAwC,CAAA;YAEpE,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;gBACrC,6CAA6C;gBAC7C,MAAM,YAAY,GAAG,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAA;gBAChF,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,KAAK,IAAI,IAAI,IAAI,CAAC,gBAAgB,KAAK,YAAY,CAAA;gBAC/F,MAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,KAAK,IAAI,IAAI,IAAI,CAAC,kBAAkB,KAAK,YAAY,CAAA;gBACpG,IAAI,cAAc,IAAI,eAAe,EAAE,CAAC;oBACtC,IAAI,CAAC,OAAO,CAAC,yCAAyC,YAAY,GAAG,CAAC,CAAA;gBACxE,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,QAAQ,CAAC,qCAAqC,YAAY,gBAAgB,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;gBACzG,CAAC;gBACD,oCAAoC;gBACpC,IAAI,CAAC,gBAAgB,GAAG,YAAY,CAAA;gBACpC,IAAI,CAAC,kBAAkB,GAAG,YAAY,CAAA;YACxC,CAAC;YAED,IAAI,gBAAgB,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACxD,kEAAkE;gBAClE,+DAA+D;gBAC/D,aAAa;gBACb,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,qBAAqB,CAAA;gBAC7F,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAA;gBAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAA;gBAE3E,IAAI,YAAY,IAAI,SAAS,EAAE,CAAC;oBAC9B,MAAM,UAAU,GAAG,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,CAAC,CAAA;oBACtD,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;oBACpC,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAA;oBAC5D,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CAAA;wBAC5F,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,wCAAwC,MAAM,CAAC,QAAQ,CAAC,OAAO,MAAM,IAAI,OAAO,EAAE,CAAC,CAAA;oBACxH,CAAC;oBAAC,OAAO,CAAM,EAAE,CAAC;wBAChB,IAAI,CAAC,QAAQ,CAAC,+CAA+C,MAAM,CAAC,QAAQ,CAAC,OAAO,MAAM,KAAK,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAA;oBACnH,CAAC;oBACD,OAAM;gBACR,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;YAClF,IAAI,CAAC,OAAO,CAAC,0GAA0G,SAAS,EAAE,CAAC,CAAA;YACnI,OAAM;QACR,CAAC;QAED,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YAC9B,sEAAsE;YACtE,6DAA6D;YAC7D,MAAM,SAAS,GAAG,UAAU,CAAC,SAA+B,CAAA;YAC5D,IAAI,gBAAgB,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBACvE,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,qBAAqB,CAAA;gBAC7F,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAA;gBAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAA;gBAC3E,IAAI,YAAY,IAAI,SAAS,EAAE,CAAC;oBAC9B,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAA;oBAC5D,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAA;wBACtF,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,WAAW,+CAA+C,SAAS,OAAO,MAAM,YAAY,CAAC,CAAA;oBACrH,CAAC;oBAAC,OAAO,CAAM,EAAE,CAAC;wBAChB,IAAI,CAAC,QAAQ,CAAC,sDAAsD,SAAS,OAAO,MAAM,KAAK,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAA;oBACnH,CAAC;oBACD,OAAM;gBACR,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;YAClF,IAAI,CAAC,QAAQ,CAAC,gHAAgH,SAAS,EAAE,CAAC,CAAA;YAC1I,OAAM;QACR,CAAC;QAED,0EAA0E;QAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QAClF,IAAI,CAAC,OAAO,CAAC,sCAAsC,OAAO,iBAAiB,MAAM,2BAA2B,SAAS,EAAE,CAAC,CAAA;IAC1H,CAAC;IAED;;OAEG;IACO,OAAO,CAAC,OAAe,EAAE,GAAG,IAAe;QACnD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;IAC5D,CAAC;IAES,QAAQ,CAAC,OAAe,EAAE,GAAG,IAAe;QACpD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;IAC7D,CAAC;IAES,QAAQ,CAAC,OAAe,EAAE,GAAG,IAAe;QACpD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;IAC7D,CAAC;IAES,OAAO,CAAC,OAAe,EAAE,GAAG,IAAe;QACnD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;IAC5D,CAAC;IAED;;;OAGG;IACI,WAAW;QAChB,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAA;IACH,CAAC;CACF"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Robotic Vacuum Cleaner Accessory Class
3
+ *
4
+ * This is a comprehensive example demonstrating all available features
5
+ * of the RoboticVacuumCleaner device type including:
6
+ * - Multiple run modes (Idle, Cleaning, Mapping)
7
+ * - Multiple clean modes (Vacuum, Mop, Vacuum & Mop, Deep Clean)
8
+ * - Operational state management with realistic transitions
9
+ * - Service area (room) support
10
+ *
11
+ * IMPORTANT: Platform Matter accessories
12
+ * =======================================
13
+ * This vacuum is registered as a platform accessory using
14
+ * api.matter.registerPlatformAccessories(), which works the same as HAP.
15
+ * Platform accessories are registered synchronously and are immediately ready for use.
16
+ *
17
+ * Demo behavior:
18
+ * - Start/Resume: Sets run mode to "Cleaning", runs for 15/10 seconds, then returns to dock
19
+ * - Return to dock: Immediately sets "Idle" mode, then Seeking (5s) → Charging (3s) → Docked
20
+ * - Stop: Immediately stops and resets to "Idle" mode
21
+ * - Pause: Cancels automatic completion timer, keeps "Cleaning" mode
22
+ */
23
+ import type { API, Logger } from 'homebridge';
24
+ import type { SharkIqVacuum } from '../sharkiq-js/sharkiq.js';
25
+ import { BaseMatterAccessory } from './BaseMatterAccessory.js';
26
+ export declare class RoboticVacuumAccessory extends BaseMatterAccessory {
27
+ private activeTimers;
28
+ private lastRunMode;
29
+ protected lastBatteryLevel: number | null;
30
+ protected lastChargingStatus: boolean | null;
31
+ private lastOperationalState;
32
+ private lastRssi;
33
+ private lastSelectedAreas;
34
+ private lastCleanMode;
35
+ private readonly sharkDevice?;
36
+ private pollInterval?;
37
+ constructor(api: API, log: Logger, sharkDevice?: SharkIqVacuum, pollIntervalMs?: number);
38
+ /**
39
+ * Initialize cached runtime values from the Shark device wrapper where
40
+ * available, otherwise fall back to persisted accessory state exposed by the API.
41
+ */
42
+ private initCachedState;
43
+ /**
44
+ * Persist a named cache value into accessory context and keep in-memory copy.
45
+ * This centralizes writes so callers only need to update the in-memory field
46
+ * and call this to persist to Homebridge accessory.context.
47
+ */
48
+ private persistCache;
49
+ private startPolling;
50
+ private stopPolling;
51
+ private buildServiceAreaCluster;
52
+ private handleChangeRunMode;
53
+ private handleChangeCleanMode;
54
+ private handlePause;
55
+ private handleStop;
56
+ private handleStart;
57
+ private handleResume;
58
+ private handleGoHome;
59
+ private handleSelectAreas;
60
+ private handleSkipArea;
61
+ /**
62
+ * Helper method to clear all active timers
63
+ */
64
+ private clearTimers;
65
+ /**
66
+ * Helper method to initiate return to dock sequence
67
+ * Can be called synchronously from other handlers
68
+ */
69
+ private returnToDock;
70
+ /**
71
+ * Update Methods - Use these to update the vacuum state from your API/device
72
+ *
73
+ * Since this is a platform accessory, state updates work immediately after registration.
74
+ */
75
+ updateOperationalState(state: number): void;
76
+ updateRunMode(mode: number): void;
77
+ updateCleanMode(mode: number): void;
78
+ updateSelectedAreas(areaIds: number[]): void;
79
+ updateCurrentArea(areaId: number | null): void;
80
+ updateProgress(progress: Array<{
81
+ areaId: number;
82
+ status: number;
83
+ }>): void;
84
+ }
85
+ //# sourceMappingURL=RoboticVacuumAccessory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoboticVacuumAccessory.d.ts","sourceRoot":"","sources":["../../src/devices/RoboticVacuumAccessory.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAkB,MAAM,YAAY,CAAA;AAE7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAG7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAE9D,qBAAa,sBAAuB,SAAQ,mBAAmB;IAC7D,OAAO,CAAC,YAAY,CAAuB;IAE3C,OAAO,CAAC,WAAW,CAAsB;IAEzC,SAAS,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAO;IAChD,SAAS,CAAC,kBAAkB,EAAE,OAAO,GAAG,IAAI,CAAO;IAEnD,OAAO,CAAC,oBAAoB,CAAsB;IAElD,OAAO,CAAC,QAAQ,CAAsB;IAEtC,OAAO,CAAC,iBAAiB,CAAwB;IAEjD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAe;IAC5C,OAAO,CAAC,YAAY,CAAC,CAAgB;gBAEzB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,aAAa,EAAE,cAAc,CAAC,EAAE,MAAM;IAmMvF;;;OAGG;IACH,OAAO,CAAC,eAAe;IAkJvB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,YAAY;IAwKpB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,uBAAuB;YAqCjB,mBAAmB;YAoDnB,qBAAqB;YA4BrB,WAAW;YAaX,UAAU;YAcV,WAAW;YA0BX,YAAY;YA0BZ,YAAY;YAuBZ,iBAAiB;YAsBjB,cAAc;IAQ5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;;OAGG;IACH,OAAO,CAAC,YAAY;IA0BpB;;;;OAIG;IAEI,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IA2B3C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAmBjC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA8BnC,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAkC5C,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAU9C,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;CAIjF"}