@companion-surface/base 0.6.0 → 0.6.1
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/CHANGELOG.md +7 -0
- package/dist/__tests__/util.test.d.ts +2 -0
- package/dist/__tests__/util.test.d.ts.map +1 -0
- package/dist/__tests__/util.test.js +115 -0
- package/dist/__tests__/util.test.js.map +1 -0
- package/dist/surface-api/types.d.ts +5 -1
- package/dist/surface-api/types.d.ts.map +1 -1
- package/dist/util.d.ts +23 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +44 -0
- package/dist/util.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.1](https://github.com/bitfocus/companion-surface-api/compare/companion-surface-base-v0.6.0...companion-surface-base-v0.6.1) (2025-11-24)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* make serialnumber always defined, and add helper for generating unique serials ([2cfc41e](https://github.com/bitfocus/companion-surface-api/commit/2cfc41ed58487a5d0bab7b6c6aa110774b1bf907))
|
|
9
|
+
|
|
3
10
|
## [0.6.0](https://github.com/bitfocus/companion-surface-api/compare/companion-surface-base-v0.5.0...companion-surface-base-v0.6.0) (2025-11-23)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { StableDeviceIdGenerator } from '../util.js';
|
|
3
|
+
describe('StableDeviceIdGenerator', () => {
|
|
4
|
+
test('generates different IDs for different uniqueness keys', () => {
|
|
5
|
+
const generator = new StableDeviceIdGenerator();
|
|
6
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
7
|
+
const id2 = generator.generateId('1234:9999', '/dev/hidraw1');
|
|
8
|
+
expect(id1).not.toBe(id2);
|
|
9
|
+
expect(id1).toHaveLength(40); // SHA1 hex digest length
|
|
10
|
+
expect(id2).toHaveLength(40);
|
|
11
|
+
});
|
|
12
|
+
test('generates different IDs for same uniqueness key with different paths', () => {
|
|
13
|
+
const generator = new StableDeviceIdGenerator();
|
|
14
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
15
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
16
|
+
expect(id1).not.toBe(id2);
|
|
17
|
+
});
|
|
18
|
+
test('returns same ID for same device path on repeated calls', () => {
|
|
19
|
+
const generator = new StableDeviceIdGenerator();
|
|
20
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
21
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
22
|
+
expect(id1).toBe(id2);
|
|
23
|
+
});
|
|
24
|
+
test('handles missing device path parameter', () => {
|
|
25
|
+
const generator = new StableDeviceIdGenerator();
|
|
26
|
+
const id1 = generator.generateId('1234:5678');
|
|
27
|
+
const id2 = generator.generateId('1234:5678');
|
|
28
|
+
// Without path, each call should generate a new ID
|
|
29
|
+
expect(id1).not.toBe(id2);
|
|
30
|
+
expect(id1).toHaveLength(40);
|
|
31
|
+
expect(id2).toHaveLength(40);
|
|
32
|
+
});
|
|
33
|
+
test('generates stable IDs with counter increment', () => {
|
|
34
|
+
const generator = new StableDeviceIdGenerator();
|
|
35
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
36
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
37
|
+
const id3 = generator.generateId('1234:5678', '/dev/hidraw2');
|
|
38
|
+
// All should be unique
|
|
39
|
+
expect(new Set([id1, id2, id3]).size).toBe(3);
|
|
40
|
+
});
|
|
41
|
+
test('separate instances have independent state', () => {
|
|
42
|
+
const generator1 = new StableDeviceIdGenerator();
|
|
43
|
+
const generator2 = new StableDeviceIdGenerator();
|
|
44
|
+
const id1 = generator1.generateId('1234:5678', '/dev/hidraw0');
|
|
45
|
+
const id2 = generator2.generateId('1234:5678', '/dev/hidraw1');
|
|
46
|
+
// Same inputs in different instances should produce same ID
|
|
47
|
+
expect(id1).toBe(id2);
|
|
48
|
+
});
|
|
49
|
+
test('handles multiple devices with same uniqueness key in batch', () => {
|
|
50
|
+
const generator = new StableDeviceIdGenerator();
|
|
51
|
+
// Simulate 3 identical devices (same vendor/product) with different paths
|
|
52
|
+
const ids = [
|
|
53
|
+
generator.generateId('1234:5678', '/dev/hidraw0'),
|
|
54
|
+
generator.generateId('1234:5678', '/dev/hidraw1'),
|
|
55
|
+
generator.generateId('1234:5678', '/dev/hidraw2'),
|
|
56
|
+
];
|
|
57
|
+
// All should be unique
|
|
58
|
+
expect(new Set(ids).size).toBe(3);
|
|
59
|
+
// Requesting same path again should return cached ID
|
|
60
|
+
expect(generator.generateId('1234:5678', '/dev/hidraw1')).toBe(ids[1]);
|
|
61
|
+
});
|
|
62
|
+
test('handles mixed scenarios with and without device paths', () => {
|
|
63
|
+
const generator = new StableDeviceIdGenerator();
|
|
64
|
+
const withPath1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
65
|
+
const withoutPath1 = generator.generateId('1234:5678');
|
|
66
|
+
const withPath2 = generator.generateId('1234:5678', '/dev/hidraw1');
|
|
67
|
+
const withoutPath2 = generator.generateId('1234:5678');
|
|
68
|
+
// All should be unique
|
|
69
|
+
expect(new Set([withPath1, withoutPath1, withPath2, withoutPath2]).size).toBe(4);
|
|
70
|
+
// Cached path should return same ID
|
|
71
|
+
expect(generator.generateId('1234:5678', '/dev/hidraw0')).toBe(withPath1);
|
|
72
|
+
});
|
|
73
|
+
test('handles undefined device path (same as omitted)', () => {
|
|
74
|
+
const generator = new StableDeviceIdGenerator();
|
|
75
|
+
const id1 = generator.generateId('1234:5678', undefined);
|
|
76
|
+
const id2 = generator.generateId('1234:5678', undefined);
|
|
77
|
+
// Should generate different IDs when path is undefined
|
|
78
|
+
expect(id1).not.toBe(id2);
|
|
79
|
+
});
|
|
80
|
+
test('generates valid hex SHA1 hashes', () => {
|
|
81
|
+
const generator = new StableDeviceIdGenerator();
|
|
82
|
+
const id = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
83
|
+
// Should be 40 character hex string
|
|
84
|
+
expect(id).toMatch(/^[0-9a-f]{40}$/);
|
|
85
|
+
});
|
|
86
|
+
test('deduplicates multiple endpoints of same device', () => {
|
|
87
|
+
const generator = new StableDeviceIdGenerator();
|
|
88
|
+
// Simulate same device with multiple HID endpoints (same path)
|
|
89
|
+
const id1 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
90
|
+
const id2 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
91
|
+
const id3 = generator.generateId('1234:5678', '/dev/hidraw0');
|
|
92
|
+
expect(id1).toBe(id2);
|
|
93
|
+
expect(id2).toBe(id3);
|
|
94
|
+
});
|
|
95
|
+
test('handles empty uniqueness key', () => {
|
|
96
|
+
const generator = new StableDeviceIdGenerator();
|
|
97
|
+
const id1 = generator.generateId('', '/dev/hidraw0');
|
|
98
|
+
const id2 = generator.generateId('', '/dev/hidraw1');
|
|
99
|
+
expect(id1).not.toBe(id2);
|
|
100
|
+
expect(id1).toHaveLength(40);
|
|
101
|
+
});
|
|
102
|
+
test('real-world scenario: 2 identical Stream Decks', () => {
|
|
103
|
+
const generator = new StableDeviceIdGenerator();
|
|
104
|
+
// Same vendor:product, different USB paths
|
|
105
|
+
const deck1 = generator.generateId('4057:96', '/dev/hidraw0');
|
|
106
|
+
const deck2 = generator.generateId('4057:96', '/dev/hidraw1');
|
|
107
|
+
expect(deck1).not.toBe(deck2);
|
|
108
|
+
expect(deck1).toHaveLength(40);
|
|
109
|
+
expect(deck2).toHaveLength(40);
|
|
110
|
+
// Re-enumerating same devices should return same IDs
|
|
111
|
+
expect(generator.generateId('4057:96', '/dev/hidraw0')).toBe(deck1);
|
|
112
|
+
expect(generator.generateId('4057:96', '/dev/hidraw1')).toBe(deck2);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=util.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.test.js","sourceRoot":"","sources":["../../src/__tests__/util.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,11 @@ export interface HIDDevice {
|
|
|
10
10
|
vendorId: number;
|
|
11
11
|
productId: number;
|
|
12
12
|
path: string;
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* The serial number of the device.
|
|
15
|
+
* This is either the serial number provided by the device, or something generated by Companion to give this device a unique ID
|
|
16
|
+
*/
|
|
17
|
+
serialNumber: string;
|
|
14
18
|
manufacturer: string | undefined;
|
|
15
19
|
product: string | undefined;
|
|
16
20
|
release: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/surface-api/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAExE;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/surface-api/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAA;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA;AAExE;;;GAGG;AACH,MAAM,WAAW,SAAS;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACzB;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAA;AAC9B,MAAM,MAAM,SAAS,GAAG,MAAM,CAAA;AAE9B,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AACD,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,QAAQ,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,UAAU,EAAE,OAAO,CAAA;IACnB;;OAEG;IACH,aAAa,EAAE,6BAA6B,CAAA;IAC5C;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,KAAK,CAAC,oBAAoB,GAAG,qBAAqB,CAAC,CAAA;IACvE;;;OAGG;IACH,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAEpC;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAEvB;;OAEG;IACH,YAAY,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,eAAe,CAAA;IACxB,aAAa,EAAE,oBAAoB,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,CAAA;IAElB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,2BAA2B;IAC3C,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,aAAa,CAAA;CACrB"}
|
package/dist/util.d.ts
CHANGED
|
@@ -5,4 +5,27 @@ export interface RgbColor {
|
|
|
5
5
|
b: number;
|
|
6
6
|
}
|
|
7
7
|
export declare function parseColor(color: string | undefined): RgbColor;
|
|
8
|
+
/**
|
|
9
|
+
* Helper class to generate stable, unique device IDs for devices that lack serial numbers.
|
|
10
|
+
* Each instance is scoped to a single batch of devices, ensuring uniqueness within that batch.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const generator = new StableDeviceIdGenerator()
|
|
15
|
+
* const serial1 = generator.generateId('1234:5678', '/dev/hidraw0')
|
|
16
|
+
* const serial2 = generator.generateId('1234:5678', '/dev/hidraw1')
|
|
17
|
+
* // serial1 and serial2 will be unique even for the same uniquenessKey
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class StableDeviceIdGenerator {
|
|
21
|
+
#private;
|
|
22
|
+
/**
|
|
23
|
+
* Generate a stable unique ID for a device within the current batch.
|
|
24
|
+
*
|
|
25
|
+
* @param uniquenessKey - A string containing device identifiers (e.g., "vendorId:productId")
|
|
26
|
+
* @param devicePath - A unique identifier for the device. Typically the device path. This is to ensure that multiple endpoints of the same hid device get the same id.
|
|
27
|
+
* @returns A stable unique identifier for the device
|
|
28
|
+
*/
|
|
29
|
+
generateId(uniquenessKey: string, devicePath?: string): string;
|
|
30
|
+
}
|
|
8
31
|
//# sourceMappingURL=util.d.ts.map
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI,CAE3C;AAED,MAAM,WAAW,QAAQ;IACxB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACT;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAM9D;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAuB;;IAInC;;;;;;OAMG;IACH,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;CAsB9D"}
|
package/dist/util.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
1
2
|
export function assertNever(_v) {
|
|
2
3
|
// Nothing to do
|
|
3
4
|
}
|
|
@@ -7,4 +8,47 @@ export function parseColor(color) {
|
|
|
7
8
|
const b = color ? parseInt(color.substr(5, 2), 16) : 0;
|
|
8
9
|
return { r, g, b };
|
|
9
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Helper class to generate stable, unique device IDs for devices that lack serial numbers.
|
|
13
|
+
* Each instance is scoped to a single batch of devices, ensuring uniqueness within that batch.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const generator = new StableDeviceIdGenerator()
|
|
18
|
+
* const serial1 = generator.generateId('1234:5678', '/dev/hidraw0')
|
|
19
|
+
* const serial2 = generator.generateId('1234:5678', '/dev/hidraw1')
|
|
20
|
+
* // serial1 and serial2 will be unique even for the same uniquenessKey
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class StableDeviceIdGenerator {
|
|
24
|
+
#previousForDevicePath = new Map();
|
|
25
|
+
#returnedIds = new Map();
|
|
26
|
+
/**
|
|
27
|
+
* Generate a stable unique ID for a device within the current batch.
|
|
28
|
+
*
|
|
29
|
+
* @param uniquenessKey - A string containing device identifiers (e.g., "vendorId:productId")
|
|
30
|
+
* @param devicePath - A unique identifier for the device. Typically the device path. This is to ensure that multiple endpoints of the same hid device get the same id.
|
|
31
|
+
* @returns A stable unique identifier for the device
|
|
32
|
+
*/
|
|
33
|
+
generateId(uniquenessKey, devicePath) {
|
|
34
|
+
// Generate a complete key
|
|
35
|
+
// If there is something cached against the devicePath, use that
|
|
36
|
+
const pathCacheKey = `${uniquenessKey}||${devicePath}`;
|
|
37
|
+
if (devicePath) {
|
|
38
|
+
const cached = this.#previousForDevicePath.get(pathCacheKey);
|
|
39
|
+
if (cached)
|
|
40
|
+
return cached;
|
|
41
|
+
}
|
|
42
|
+
// Loop until we find a non-colliding ID
|
|
43
|
+
for (let i = 0;; i++) {
|
|
44
|
+
const id = `${uniquenessKey}||${i}`;
|
|
45
|
+
if (!this.#returnedIds.has(id)) {
|
|
46
|
+
const fakeSerial = createHash('sha1').update(id).digest('hex');
|
|
47
|
+
this.#returnedIds.set(id, fakeSerial);
|
|
48
|
+
this.#previousForDevicePath.set(pathCacheKey, fakeSerial);
|
|
49
|
+
return fakeSerial;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
10
54
|
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,EAAS;IACpC,gBAAgB;AACjB,CAAC;AAQD,MAAM,UAAU,UAAU,CAAC,KAAyB;IACnD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEtD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;AACnB,CAAC"}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,MAAM,UAAU,WAAW,CAAC,EAAS;IACpC,gBAAgB;AACjB,CAAC;AAQD,MAAM,UAAU,UAAU,CAAC,KAAyB;IACnD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEtD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;AACnB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,uBAAuB;IAC1B,sBAAsB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAClD,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEjD;;;;;;OAMG;IACH,UAAU,CAAC,aAAqB,EAAE,UAAmB;QACpD,0BAA0B;QAE1B,gEAAgE;QAChE,MAAM,YAAY,GAAG,GAAG,aAAa,KAAK,UAAU,EAAE,CAAA;QACtD,IAAI,UAAU,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;YAC5D,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAA;QAC1B,CAAC;QAED,wCAAwC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAI,CAAC,EAAE,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,GAAG,aAAa,KAAK,CAAC,EAAE,CAAA;YACnC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAChC,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBAE9D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,UAAU,CAAC,CAAA;gBACrC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;gBACzD,OAAO,UAAU,CAAA;YAClB,CAAC;QACF,CAAC;IACF,CAAC;CACD"}
|