steamworks-ffi-node 0.2.3 → 0.3.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/README.md CHANGED
@@ -1,10 +1,15 @@
1
- # Steamworks FFI - Real Steam Integration
1
+ [![npm](https://img.shields.io/npm/v/steamworks-ffi-node.svg)](https://www.npmjs.com/package/steamworks-ffi-node)
2
+ [![Chat](https://img.shields.io/discord/1426518243077656699?label=chat&logo=discord)](https://discord.gg/Ruzx4Z7cKr)
2
3
 
3
- A production-ready TypeScript/JavaScript wrapper for the Steamworks SDK using Koffi FFI, designed for Node.js and Electron applications with **real Steam client integration**.
4
+ # Steamworks FFI - Steamworks SDK Integration
5
+
6
+ A production-ready TypeScript/JavaScript wrapper for the Steamworks SDK using Koffi FFI, designed for Node.js and Electron applications with **Steamworks SDK integration**.
4
7
 
5
8
  > ✅ **No C++ Compilation Required**: Uses Koffi FFI for seamless installation without Visual Studio Build Tools!
6
9
 
7
- > 🎉 **NEW: 100% Achievement API Coverage** - All 20 Steam achievement functions now implemented! See [Complete Achievement Manager Documentation](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/docs/AchievementManager.md)
10
+ > 🎉 **NEW: 100% Achievement API Coverage** - All 20 Steam achievement functions implemented! [See Documentation](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/docs/ACHIEVEMENT_MANAGER.md)
11
+
12
+ > 🎉 **NEW: 100% Stats API Coverage** - All 13 Steam statistics functions implemented! [See Documentation](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/docs/STATS_MANAGER.md)
8
13
 
9
14
  ## 🎯 Features
10
15
 
@@ -15,7 +20,11 @@ A production-ready TypeScript/JavaScript wrapper for the Steamworks SDK using Ko
15
20
  - ✅ Friend comparisons (see friend achievements)
16
21
  - ✅ Global statistics (unlock percentages, popularity sorting)
17
22
  - ✅ Testing tools (reset stats/achievements)
18
- - **Real Steam Integration**: Direct FFI calls to Steamworks C++ SDK
23
+ - **Complete Stats API**: 100% coverage of Steam User Stats functionality (13/13 functions)
24
+ - ✅ User stats (get/set int/float, average rate tracking)
25
+ - ✅ Friend comparisons (compare stats with friends)
26
+ - ✅ Global statistics (worldwide aggregated data with history)
27
+ - **Steamworks Integration**: Direct FFI calls to Steamworks C++ SDK
19
28
  - **Cross-Platform**: Windows, macOS, and Linux support
20
29
  - **Batteries Included**: All Steamworks redistributables bundled - no SDK download needed!
21
30
  - **Electron Ready**: Perfect for Electron applications
@@ -45,14 +54,14 @@ npm install steamworks-ffi-node
45
54
  ```typescript
46
55
  import Steam from 'steamworks-ffi-node';
47
56
 
48
- // Initialize real Steam connection
57
+ // Initialize Steam connection
49
58
  const steam = Steam.getInstance();
50
59
  const initialized = steam.init({ appId: 480 }); // Your Steam App ID
51
60
 
52
61
  if (initialized) {
53
62
  // Get achievements from Steam servers
54
63
  const achievements = await steam.getAllAchievements();
55
- console.log('Real Steam achievements:', achievements);
64
+ console.log('Steam achievements:', achievements);
56
65
 
57
66
  // Unlock achievement (permanent in Steam!)
58
67
  await steam.unlockAchievement('ACH_WIN_ONE_GAME');
@@ -60,6 +69,17 @@ if (initialized) {
60
69
  // Check unlock status from Steam
61
70
  const isUnlocked = await steam.isAchievementUnlocked('ACH_WIN_ONE_GAME');
62
71
  console.log('Achievement unlocked:', isUnlocked);
72
+
73
+ // Track user statistics
74
+ const kills = await steam.getStatInt('total_kills') || 0;
75
+ await steam.setStatInt('total_kills', kills + 1);
76
+
77
+ // Get global statistics
78
+ await steam.requestGlobalStats(7);
79
+ await new Promise(resolve => setTimeout(resolve, 2000));
80
+ steam.runCallbacks();
81
+ const globalKills = await steam.getGlobalStatInt('global.total_kills');
82
+ console.log('Total kills worldwide:', globalKills);
63
83
  }
64
84
 
65
85
  // Cleanup
@@ -100,23 +120,22 @@ For immediate testing, use Spacewar (App ID 480):
100
120
 
101
121
  ## 📚 API Documentation
102
122
 
103
- ### Documentation
123
+ Complete documentation for all APIs is available in the [docs folder](https://github.com/ArtyProf/steamworks-ffi-node/tree/main/docs):
104
124
 
105
- - **[SteamAPICore Documentation](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/docs/SteamAPICore.md)** - Initialization, lifecycle management, callbacks
106
- - **[Achievement Manager API](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/docs/AchievementManager.md)** - Complete achievement functionality (20 functions)
125
+ ➡️ **[View Complete Documentation](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/docs/README.md)**
107
126
 
108
- ## 🎮 Real Steam Integration
127
+ ## 🎮 Steamworks Integration
109
128
 
110
129
  This library connects directly to the Steam client and Steamworks SDK:
111
130
 
112
131
  ```javascript
113
- // Real Steam API - no mocking!
132
+ // Steam API - no mocking!
114
133
  const steam = Steam.getInstance();
115
134
  steam.init({ appId: 480 }); // Connects to actual Steam
116
135
 
117
136
  // Live achievements from Steam servers
118
137
  const achievements = await steam.getAllAchievements();
119
- console.log(achievements); // Real achievement data from your Steam app
138
+ console.log(achievements); // Achievement data from your Steam app
120
139
 
121
140
  // Permanent achievement unlock in Steam
122
141
  await steam.unlockAchievement('YOUR_ACHIEVEMENT');
@@ -155,6 +174,45 @@ app.on('before-quit', () => {
155
174
  });
156
175
  ```
157
176
 
177
+ ### 📦 Packaging with ASAR
178
+
179
+ When packaging your Electron app with ASAR archives, **native modules must be unpacked**. The library automatically detects ASAR and looks for files in `.asar.unpacked`.
180
+
181
+ #### electron-builder Configuration
182
+
183
+ Add to your `package.json` or `electron-builder.yml`:
184
+
185
+ ```json
186
+ {
187
+ "build": {
188
+ "asarUnpack": [
189
+ "node_modules/steamworks-ffi-node/**/*"
190
+ ]
191
+ }
192
+ }
193
+ ```
194
+
195
+ #### electron-forge Configuration
196
+
197
+ Add to your `forge.config.js`:
198
+
199
+ ```javascript
200
+ module.exports = {
201
+ packagerConfig: {
202
+ asar: {
203
+ unpack: "**/{node_modules/steamworks-ffi-node}/**/*"
204
+ }
205
+ }
206
+ };
207
+ ```
208
+
209
+ The library will automatically:
210
+ 1. Detect if running inside an ASAR archive
211
+ 2. Replace `.asar` with `.asar.unpacked` in the library path
212
+ 3. Load the Steamworks SDK from the unpacked directory
213
+
214
+ This ensures native libraries work correctly in packaged Electron apps!
215
+
158
216
  ## 🔧 Requirements
159
217
 
160
218
  - **Node.js**: 18+
@@ -186,7 +244,9 @@ All redistributable binaries are included in the package - no manual SDK downloa
186
244
 
187
245
  ### Electron-specific issues
188
246
  - ❌ Initialized in renderer → **Solution**: Only initialize in main process
189
- - ❌ Not cleaning up → **Solution**: Call `shutdown()` in `before-quit` event
247
+ - ❌ Not cleaning up → **Solution**: Call `shutdown()` in `before-quit` event
248
+ - ❌ "cannot open shared object file: Not a directory" (Linux) → **Solution**: Add `asarUnpack` configuration (see Electron Integration section above)
249
+ - ❌ Native module errors in packaged app → **Solution**: Ensure `steamworks-ffi-node` is in `asarUnpack` list
190
250
 
191
251
  ## 📄 License
192
252
 
@@ -197,4 +257,4 @@ MIT License - see LICENSE file for details.
197
257
  This package includes redistributable binaries from the Steamworks SDK (© Valve Corporation).
198
258
  These are distributed under the Steamworks SDK Access Agreement in accordance with Section 1.1(b).
199
259
 
200
- See [THIRD_PARTY_LICENSES.md](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/THIRD_PARTY_LICENSES.md) for full details.
260
+ See [THIRD_PARTY_LICENSES.md](https://github.com/ArtyProf/steamworks-ffi-node/blob/main/THIRD_PARTY_LICENSES.md) for full details.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import SteamworksSDK from './steam';
2
- import { SteamAchievement, SteamInitOptions, SteamStatus, AchievementProgressLimits, UserAchievement, AchievementGlobalStats, AchievementWithIcon } from './types';
3
- export { SteamAchievement, SteamInitOptions, SteamStatus, AchievementProgressLimits, UserAchievement, AchievementGlobalStats, AchievementWithIcon };
2
+ import { SteamAchievement, SteamInitOptions, SteamStatus, AchievementProgressLimits, UserAchievement, AchievementGlobalStats, AchievementWithIcon, SteamStat, GlobalStat, GlobalStatHistory, UserStat } from './types';
3
+ export { SteamAchievement, SteamInitOptions, SteamStatus, AchievementProgressLimits, UserAchievement, AchievementGlobalStats, AchievementWithIcon, SteamStat, GlobalStat, GlobalStatHistory, UserStat };
4
4
  export default SteamworksSDK;
5
5
  export { SteamworksSDK as Steam };
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,SAAS,CAAC;AACpC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACpB,CAAC;AAGF,eAAe,aAAa,CAAC;AAG7B,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,SAAS,CAAC;AACpC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACT,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,QAAQ,EACT,CAAC;AAGF,eAAe,aAAa,CAAC;AAG7B,OAAO,EAAE,aAAa,IAAI,KAAK,EAAE,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,oDAAoC;AA0BV,gBA1BnB,eAAa,CA0BW;AAJ/B,0BAA0B;AAC1B,kBAAe,eAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,oDAAoC;AAkCV,gBAlCnB,eAAa,CAkCW;AAJ/B,0BAA0B;AAC1B,kBAAe,eAAa,CAAC"}
@@ -1,45 +1,235 @@
1
1
  import { SteamInitOptions, SteamStatus } from '../types';
2
2
  import { SteamLibraryLoader } from './SteamLibraryLoader';
3
3
  /**
4
- * Core Steam API initialization and lifecycle management
4
+ * SteamAPICore
5
+ *
6
+ * Core Steam API initialization and lifecycle management.
7
+ * Handles Steam client connection, interface management, and callback processing.
8
+ *
9
+ * This class manages the fundamental Steam API operations:
10
+ * - Initialization and shutdown of the Steam API
11
+ * - Interface retrieval (UserStats, User)
12
+ * - Status monitoring (Steam running, initialization state)
13
+ * - Callback processing for Steam events
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const loader = new SteamLibraryLoader();
18
+ * const apiCore = new SteamAPICore(loader);
19
+ *
20
+ * const success = apiCore.init({ appId: 480 });
21
+ * if (success) {
22
+ * console.log('Steam API initialized!');
23
+ * // Use Steam features...
24
+ * apiCore.shutdown();
25
+ * }
26
+ * ```
5
27
  */
6
28
  export declare class SteamAPICore {
29
+ /** Steam library loader for FFI function calls */
7
30
  private libraryLoader;
31
+ /** Whether the Steam API has been successfully initialized */
8
32
  private initialized;
33
+ /** The Steam App ID for this application */
9
34
  private appId;
35
+ /** Pointer to the ISteamUserStats interface */
10
36
  private userStatsInterface;
37
+ /** Pointer to the ISteamUser interface */
11
38
  private userInterface;
39
+ /**
40
+ * Creates a new SteamAPICore instance
41
+ *
42
+ * @param libraryLoader - The Steam library loader for FFI calls
43
+ */
12
44
  constructor(libraryLoader: SteamLibraryLoader);
13
45
  /**
14
- * Initialize Steam API
46
+ * Initialize the Steam API
47
+ *
48
+ * Establishes connection to the Steam client and retrieves necessary interfaces.
49
+ * Creates steam_appid.txt file required by Steam, loads the Steamworks library,
50
+ * and initializes all necessary Steam interfaces.
51
+ *
52
+ * @param options - Initialization options containing the Steam App ID
53
+ * @returns true if initialization was successful, false otherwise
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const success = apiCore.init({ appId: 480 });
58
+ * if (success) {
59
+ * console.log('Connected to Steam for App ID:', 480);
60
+ * } else {
61
+ * console.error('Failed to initialize Steam API');
62
+ * }
63
+ * ```
64
+ *
65
+ * @remarks
66
+ * - Creates steam_appid.txt file in the current working directory
67
+ * - Sets SteamAppId environment variable
68
+ * - Automatically requests current stats from Steam servers
69
+ * - Runs callbacks to process initial Steam events
70
+ *
71
+ * @warning
72
+ * Requires Steam client to be running and user to be logged in
73
+ *
74
+ * Steamworks SDK Functions:
75
+ * - `SteamAPI_Init()` - Initialize the Steam API
76
+ * - `SteamAPI_IsSteamRunning()` - Check if Steam client is running
77
+ * - `SteamAPI_SteamUserStats_v013()` - Get ISteamUserStats interface
78
+ * - `SteamAPI_SteamUser_v023()` - Get ISteamUser interface
79
+ * - `SteamAPI_ISteamUserStats_RequestCurrentStats()` - Request current stats from Steam
80
+ * - `SteamAPI_RunCallbacks()` - Process Steam callbacks
15
81
  */
16
82
  init(options: SteamInitOptions): boolean;
17
83
  /**
18
- * Shutdown Steam API
84
+ * Shutdown the Steam API
85
+ *
86
+ * Cleanly shuts down the Steam API connection and releases all interfaces.
87
+ * Should be called when the application is closing or Steam features are no longer needed.
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * process.on('SIGINT', () => {
92
+ * apiCore.shutdown();
93
+ * process.exit(0);
94
+ * });
95
+ * ```
96
+ *
97
+ * @remarks
98
+ * - Safe to call multiple times (only shuts down if initialized)
99
+ * - Clears all interface pointers
100
+ * - Sets initialized state to false
101
+ *
102
+ * Steamworks SDK Functions:
103
+ * - `SteamAPI_Shutdown()` - Shutdown the Steam API
19
104
  */
20
105
  shutdown(): void;
21
106
  /**
22
- * Get current Steam status
107
+ * Get the current Steam status
108
+ *
109
+ * Returns detailed status information including initialization state,
110
+ * App ID, and the current user's Steam ID.
111
+ *
112
+ * @returns Object containing initialization status, App ID, and Steam ID
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * const status = apiCore.getStatus();
117
+ * console.log(`Initialized: ${status.initialized}`);
118
+ * console.log(`App ID: ${status.appId}`);
119
+ * console.log(`Steam ID: ${status.steamId}`);
120
+ * ```
121
+ *
122
+ * @remarks
123
+ * - Steam ID is '0' if not initialized or unable to retrieve
124
+ * - App ID is 0 if not initialized
125
+ *
126
+ * Steamworks SDK Functions:
127
+ * - `SteamAPI_ISteamUser_GetSteamID()` - Get current user's Steam ID
23
128
  */
24
129
  getStatus(): SteamStatus;
25
130
  /**
26
131
  * Run Steam callbacks to process pending events
132
+ *
133
+ * Processes all pending Steam callbacks and events. Should be called regularly
134
+ * (e.g., in a game loop or timer) to ensure Steam events are processed promptly.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * // In a game loop or setInterval
139
+ * setInterval(() => {
140
+ * apiCore.runCallbacks();
141
+ * }, 100); // Every 100ms
142
+ * ```
143
+ *
144
+ * @remarks
145
+ * - Safe to call even if not initialized (will be ignored)
146
+ * - Automatically called by init() and after stat/achievement operations
147
+ * - Required for receiving Steam events and callbacks
148
+ *
149
+ * Steamworks SDK Functions:
150
+ * - `SteamAPI_RunCallbacks()` - Process all pending Steam callbacks
27
151
  */
28
152
  runCallbacks(): void;
29
153
  /**
30
- * Check if Steam client is running
154
+ * Check if the Steam client is running
155
+ *
156
+ * Verifies that the Steam client application is currently running on the user's system.
157
+ *
158
+ * @returns true if Steam is running, false otherwise
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * if (apiCore.isSteamRunning()) {
163
+ * console.log('Steam client is active');
164
+ * } else {
165
+ * console.warn('Steam client is not running');
166
+ * }
167
+ * ```
168
+ *
169
+ * @remarks
170
+ * - Returns false if Steam API is not initialized
171
+ * - Safe to call at any time
172
+ *
173
+ * Steamworks SDK Functions:
174
+ * - `SteamAPI_IsSteamRunning()` - Check if Steam client is running
31
175
  */
32
176
  isSteamRunning(): boolean;
33
177
  /**
34
- * Check if initialized
178
+ * Check if the Steam API is initialized
179
+ *
180
+ * Returns the current initialization state of the Steam API.
181
+ *
182
+ * @returns true if initialized and ready to use, false otherwise
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * if (!apiCore.isInitialized()) {
187
+ * console.error('Cannot perform Steam operations - not initialized');
188
+ * return;
189
+ * }
190
+ * ```
35
191
  */
36
192
  isInitialized(): boolean;
37
193
  /**
38
- * Get UserStats interface pointer
194
+ * Get the ISteamUserStats interface pointer
195
+ *
196
+ * Returns the native pointer to the ISteamUserStats interface, which is used
197
+ * for achievement and stats operations.
198
+ *
199
+ * @returns Pointer to ISteamUserStats interface, or null if not initialized
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * const userStats = apiCore.getUserStatsInterface();
204
+ * if (userStats) {
205
+ * // Use interface for stats/achievement operations
206
+ * }
207
+ * ```
208
+ *
209
+ * @remarks
210
+ * - Returns null if Steam API is not initialized
211
+ * - This is a native pointer for use with FFI calls
39
212
  */
40
213
  getUserStatsInterface(): any;
41
214
  /**
42
- * Get User interface pointer
215
+ * Get the ISteamUser interface pointer
216
+ *
217
+ * Returns the native pointer to the ISteamUser interface, which is used
218
+ * for user identity operations.
219
+ *
220
+ * @returns Pointer to ISteamUser interface, or null if not initialized
221
+ *
222
+ * @example
223
+ * ```typescript
224
+ * const user = apiCore.getUserInterface();
225
+ * if (user) {
226
+ * // Use interface for user operations
227
+ * }
228
+ * ```
229
+ *
230
+ * @remarks
231
+ * - Returns null if Steam API is not initialized
232
+ * - This is a native pointer for use with FFI calls
43
233
  */
44
234
  getUserInterface(): any;
45
235
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SteamAPICore.d.ts","sourceRoot":"","sources":["../../src/internal/SteamAPICore.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,aAAa,CAAa;gBAEtB,aAAa,EAAE,kBAAkB;IAI7C;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;IAmExC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAWhB;;OAEG;IACH,SAAS,IAAI,WAAW;IAmBxB;;OAEG;IACH,YAAY,IAAI,IAAI;IAUpB;;OAEG;IACH,cAAc,IAAI,OAAO;IAYzB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,qBAAqB,IAAI,GAAG;IAI5B;;OAEG;IACH,gBAAgB,IAAI,GAAG;CAGxB"}
1
+ {"version":3,"file":"SteamAPICore.d.ts","sourceRoot":"","sources":["../../src/internal/SteamAPICore.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,YAAY;IACvB,kDAAkD;IAClD,OAAO,CAAC,aAAa,CAAqB;IAE1C,8DAA8D;IAC9D,OAAO,CAAC,WAAW,CAAkB;IAErC,4CAA4C;IAC5C,OAAO,CAAC,KAAK,CAAa;IAE1B,+CAA+C;IAC/C,OAAO,CAAC,kBAAkB,CAAa;IAEvC,0CAA0C;IAC1C,OAAO,CAAC,aAAa,CAAa;IAElC;;;;OAIG;gBACS,aAAa,EAAE,kBAAkB;IAI7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;IAmExC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,QAAQ,IAAI,IAAI;IAWhB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,SAAS,IAAI,WAAW;IAmBxB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,YAAY,IAAI,IAAI;IAUpB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,cAAc,IAAI,OAAO;IAYzB;;;;;;;;;;;;;;OAcG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,qBAAqB,IAAI,GAAG;IAI5B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAAgB,IAAI,GAAG;CAGxB"}