@embrs/user-feedback 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,227 @@
1
+ # User Feedback
2
+
3
+ 基於 Node.js 的 MCP 反饋收集工具,支援 AI 工作彙報和用戶反饋收集。
4
+
5
+ ## 功能特點
6
+
7
+ - **MCP 協議支援**:符合 Model Context Protocol 標準,可與 Claude Desktop、Cursor 等 MCP 客戶端整合
8
+ - **左右分割介面**:左側顯示 AI 工作彙報,右側為用戶反饋區域
9
+ - **圖片處理**:支援拖放上傳、順序調整、彈窗檢視
10
+ - **罐頭語快速回覆**:預設常用回覆,支援自訂編輯
11
+ - **深色主題**:與 IDE 環境風格一致
12
+
13
+ ## 系統需求
14
+
15
+ - Node.js 18.0.0 或更高版本
16
+ - npm 或 yarn 套件管理器
17
+
18
+ ## 安裝
19
+
20
+ ### 從 npm 安裝(推薦)
21
+
22
+ ```bash
23
+ # 全域安裝
24
+ npm install -g @embrs/user-feedback
25
+
26
+ # 更新到最新版本
27
+ npm update -g @embrs/user-feedback
28
+
29
+ # 或使用 npx 直接執行(無需安裝,自動使用最新版)
30
+ npx @embrs/user-feedback@latest --help
31
+ ```
32
+
33
+ ### 從原始碼安裝(開發用)
34
+
35
+ ```bash
36
+ # 克隆專案
37
+ git clone https://github.com/Embrs/user-feedback.git
38
+ cd user-feedback
39
+
40
+ # 安裝依賴並建置
41
+ npm install
42
+ npm run build
43
+
44
+ # 建立全域連結(本地測試用)
45
+ npm link
46
+ ```
47
+
48
+ ## 解除安裝
49
+
50
+ ```bash
51
+ # 如果使用 npm 全域安裝
52
+ npm uninstall -g @embrs/user-feedback
53
+
54
+ # 如果從原始碼安裝,先移除連結再刪除專案
55
+ npm unlink -g @embrs/user-feedback
56
+ rm -rf user-feedback
57
+ ```
58
+
59
+ **注意**:解除安裝後,請記得從 MCP 客戶端配置中移除相關設定(如 Claude Desktop 的 `claude_desktop_config.json`)。
60
+
61
+ ## 使用方式
62
+
63
+ ### 作為 MCP 服務器
64
+
65
+ ```bash
66
+ # 啟動 MCP 服務器(預設模式)
67
+ user-feedback start
68
+
69
+ # 指定端口
70
+ user-feedback start --port 3000
71
+
72
+ # 啟用除錯模式
73
+ user-feedback start --debug
74
+ ```
75
+
76
+ ### 僅 Web 模式(測試用)
77
+
78
+ ```bash
79
+ user-feedback start --web
80
+ ```
81
+
82
+ ### 其他命令
83
+
84
+ ```bash
85
+ # 檢查配置和系統狀態
86
+ user-feedback health
87
+
88
+ # 顯示當前配置
89
+ user-feedback config
90
+ ```
91
+
92
+ ## MCP 客戶端配置
93
+
94
+ ### Cursor
95
+
96
+ 1. 打開 Cursor 設定(`Cmd + ,`)
97
+ 2. 搜尋 "MCP" 或進入 Features → MCP Servers
98
+ 3. 點擊 "Edit in settings.json" 或 "Add Server"
99
+ 4. 添加以下配置:
100
+
101
+ **方法一:使用絕對路徑(推薦本地開發)**
102
+ ```json
103
+ {
104
+ "mcpServers": {
105
+ "user-feedback": {
106
+ "command": "node",
107
+ "args": ["/Users/embrs/Desktop/Program/self/user-feedback/dist/cli.js"]
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ **方法二:使用 npm 全域安裝後**
114
+ ```json
115
+ {
116
+ "mcpServers": {
117
+ "user-feedback": {
118
+ "command": "npx",
119
+ "args": ["-y", "@embrs/user-feedback"]
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
125
+ 5. 重啟 Cursor 使配置生效
126
+
127
+ ### Claude Desktop
128
+
129
+ 在 `~/Library/Application Support/Claude/claude_desktop_config.json` 中添加:
130
+
131
+ ```json
132
+ {
133
+ "mcpServers": {
134
+ "user-feedback": {
135
+ "command": "node",
136
+ "args": ["/Users/embrs/Desktop/Program/self/user-feedback/dist/cli.js"]
137
+ }
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### Windsurf
143
+
144
+ 在 MCP 設定中添加:
145
+
146
+ ```json
147
+ {
148
+ "mcpServers": {
149
+ "user-feedback": {
150
+ "command": "node",
151
+ "args": ["/Users/embrs/Desktop/Program/self/user-feedback/dist/cli.js"]
152
+ }
153
+ }
154
+ }
155
+ ```
156
+
157
+ ## 環境變數配置
158
+
159
+ 複製 `.env.example` 為 `.env` 並根據需要修改:
160
+
161
+ | 變數 | 說明 | 預設值 |
162
+ |------|------|--------|
163
+ | `MCP_WEB_PORT` | Web 服務器端口 | 3239 |
164
+ | `MCP_DIALOG_TIMEOUT` | 反饋超時時間(秒) | 600 |
165
+ | `LOG_LEVEL` | 日誌級別(silent/error/warn/info/debug) | info |
166
+ | `MAX_IMAGE_SIZE_MB` | 最大圖片大小(MB) | 10 |
167
+
168
+ ## MCP 工具 API
169
+
170
+ ### collect_feedback
171
+
172
+ 收集用戶對 AI 工作的反饋。
173
+
174
+ **參數:**
175
+ - `work_summary` (string, 必填):AI 工作彙報內容
176
+
177
+ **返回:**
178
+ - 用戶提交的反饋內容(文字和/或圖片)
179
+
180
+ **範例:**
181
+ ```
182
+ AI 調用 collect_feedback 工具,傳入工作彙報內容
183
+ → 系統開啟 Web 介面
184
+ → 用戶在介面中提交反饋
185
+ → 反饋內容返回給 AI
186
+ ```
187
+
188
+ ## 開發
189
+
190
+ ```bash
191
+ # 安裝依賴
192
+ npm install
193
+
194
+ # 開發模式(監聽變更)
195
+ npm run dev
196
+
197
+ # 建置
198
+ npm run build
199
+
200
+ # 執行測試
201
+ npm test
202
+
203
+ # 程式碼檢查
204
+ npm run lint
205
+ ```
206
+
207
+ ## 專案結構
208
+
209
+ ```
210
+ src/
211
+ ├── cli.ts # CLI 入口
212
+ ├── index.ts # 模組導出
213
+ ├── config/ # 配置管理
214
+ ├── server/
215
+ │ ├── mcp-server.ts # MCP 服務器
216
+ │ └── web-server.ts # Web 服務器
217
+ ├── static/ # 前端資源
218
+ │ ├── index.html # 主頁面
219
+ │ ├── styles.css # 樣式
220
+ │ └── app.js # 前端邏輯
221
+ ├── types/ # TypeScript 類型
222
+ └── utils/ # 工具函數
223
+ ```
224
+
225
+ ## 授權
226
+
227
+ MIT License
package/dist/cli.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Feedback Collector - CLI 入口
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;GAEG"}
package/dist/cli.js ADDED
@@ -0,0 +1,128 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Feedback Collector - CLI 入口
4
+ */
5
+ import { program } from 'commander';
6
+ import { getConfig, displayConfig } from './config/index.js';
7
+ import { logger } from './utils/logger.js';
8
+ import { MCPServer } from './server/mcp-server.js';
9
+ import { MCPError } from './types/index.js';
10
+ import { VERSION } from './index.js';
11
+ // 檢測 MCP 模式
12
+ const isMCPMode = !process.stdin.isTTY ||
13
+ process.env['NODE_ENV'] === 'mcp' ||
14
+ process.argv.includes('--mcp-mode');
15
+ if (isMCPMode) {
16
+ logger.disableColors();
17
+ // 在 MCP 模式下保持最低級別的日誌以便調試
18
+ logger.setLevel('error');
19
+ }
20
+ /**
21
+ * 顯示歡迎資訊
22
+ */
23
+ function showWelcome() {
24
+ console.log('MCP Feedback Collector v' + VERSION);
25
+ console.log('基於 Node.js 的現代化反饋收集器\n');
26
+ }
27
+ /**
28
+ * 啟動 MCP 服務器
29
+ */
30
+ async function startMCPServer(options) {
31
+ try {
32
+ const config = getConfig();
33
+ if (!isMCPMode) {
34
+ showWelcome();
35
+ logger.setLevel(config.logLevel);
36
+ }
37
+ if (options.port) {
38
+ config.webPort = options.port;
39
+ }
40
+ if (!isMCPMode && options.debug) {
41
+ config.logLevel = 'debug';
42
+ logger.enableFileLogging();
43
+ logger.setLevel('debug');
44
+ logger.debug('除錯模式已啟用');
45
+ }
46
+ if (logger.getLevel() === 'debug') {
47
+ displayConfig(config);
48
+ console.log('');
49
+ }
50
+ const server = new MCPServer(config);
51
+ if (options.web) {
52
+ logger.info('啟動 Web 模式...');
53
+ await server.startWebOnly();
54
+ }
55
+ else {
56
+ logger.info('啟動 MCP 服務器...');
57
+ await server.start();
58
+ }
59
+ }
60
+ catch (error) {
61
+ if (error instanceof MCPError) {
62
+ logger.error(`MCP 錯誤 [${error.code}]: ${error.message}`);
63
+ }
64
+ else if (error instanceof Error) {
65
+ logger.error('啟動失敗:', error.message);
66
+ }
67
+ else {
68
+ logger.error('未知錯誤:', error);
69
+ }
70
+ process.exit(1);
71
+ }
72
+ }
73
+ /**
74
+ * 健康檢查
75
+ */
76
+ async function healthCheck() {
77
+ try {
78
+ const config = getConfig();
79
+ console.log('配置驗證通過');
80
+ console.log(`Web 端口: ${config.webPort}`);
81
+ console.log(`超時時間: ${config.dialogTimeout} 秒`);
82
+ }
83
+ catch (error) {
84
+ if (error instanceof MCPError) {
85
+ console.error(`配置錯誤 [${error.code}]: ${error.message}`);
86
+ }
87
+ else {
88
+ console.error('健康檢查失敗:', error);
89
+ }
90
+ process.exit(1);
91
+ }
92
+ }
93
+ // 配置 CLI 命令
94
+ program
95
+ .name('user-feedback')
96
+ .description('基於 Node.js 的 MCP 反饋收集器')
97
+ .version(VERSION);
98
+ // 主命令 - 啟動服務器
99
+ program
100
+ .command('start', { isDefault: true })
101
+ .description('啟動 MCP 反饋收集器')
102
+ .option('-p, --port <number>', '指定 Web 服務器端口', parseInt)
103
+ .option('-w, --web', '僅啟動 Web 模式(不啟動 MCP 服務器)')
104
+ .option('-d, --debug', '啟用除錯模式')
105
+ .option('--mcp-mode', '強制啟用 MCP 模式')
106
+ .action(startMCPServer);
107
+ // 健康檢查命令
108
+ program
109
+ .command('health')
110
+ .description('檢查配置和系統狀態')
111
+ .action(healthCheck);
112
+ // 配置顯示命令
113
+ program
114
+ .command('config')
115
+ .description('顯示當前配置')
116
+ .action(() => {
117
+ try {
118
+ const config = getConfig();
119
+ displayConfig(config);
120
+ }
121
+ catch (error) {
122
+ console.error('配置載入失敗:', error);
123
+ process.exit(1);
124
+ }
125
+ });
126
+ // 解析命令行參數
127
+ program.parse();
128
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MCP Feedback Collector - 配置管理
3
+ */
4
+ import { Config } from '../types/index.js';
5
+ /**
6
+ * 創建預設配置
7
+ */
8
+ export declare function createDefaultConfig(): Config;
9
+ /**
10
+ * 驗證配置
11
+ */
12
+ export declare function validateConfig(config: Config): void;
13
+ /**
14
+ * 獲取驗證後的配置
15
+ */
16
+ export declare function getConfig(): Config;
17
+ /**
18
+ * 顯示配置資訊(隱藏敏感資訊)
19
+ */
20
+ export declare function displayConfig(config: Config): void;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAY,MAAM,mBAAmB,CAAC;AA6CrD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAiB5C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiCnD;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAIlC;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAUlD"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * MCP Feedback Collector - 配置管理
3
+ */
4
+ import { config as dotenvConfig } from 'dotenv';
5
+ import { MCPError } from '../types/index.js';
6
+ // 載入環境變數
7
+ dotenvConfig();
8
+ /**
9
+ * 獲取環境變數值,支援預設值
10
+ */
11
+ function getEnvVar(key, defaultValue) {
12
+ return process.env[key] || defaultValue;
13
+ }
14
+ /**
15
+ * 獲取可選的環境變數值
16
+ */
17
+ function getOptionalEnvVar(key) {
18
+ return process.env[key] || undefined;
19
+ }
20
+ /**
21
+ * 獲取數字類型的環境變數
22
+ */
23
+ function getEnvNumber(key, defaultValue) {
24
+ const value = process.env[key];
25
+ if (!value)
26
+ return defaultValue;
27
+ const parsed = parseInt(value, 10);
28
+ if (isNaN(parsed)) {
29
+ console.warn(`Invalid number for ${key}: ${value}, using default: ${defaultValue}`);
30
+ return defaultValue;
31
+ }
32
+ return parsed;
33
+ }
34
+ /**
35
+ * 獲取布林類型的環境變數
36
+ */
37
+ function getEnvBoolean(key, defaultValue) {
38
+ const value = process.env[key];
39
+ if (!value)
40
+ return defaultValue;
41
+ return value.toLowerCase() === 'true';
42
+ }
43
+ /**
44
+ * 創建預設配置
45
+ */
46
+ export function createDefaultConfig() {
47
+ return {
48
+ apiKey: getOptionalEnvVar('MCP_API_KEY'),
49
+ apiBaseUrl: getEnvVar('MCP_API_BASE_URL', 'https://api.openai.com/v1'),
50
+ defaultModel: getEnvVar('MCP_DEFAULT_MODEL', 'gpt-4o-mini'),
51
+ webPort: getEnvNumber('MCP_WEB_PORT', 3239),
52
+ dialogTimeout: getEnvNumber('MCP_DIALOG_TIMEOUT', 600),
53
+ corsOrigin: getEnvVar('MCP_CORS_ORIGIN', '*'),
54
+ maxFileSize: getEnvNumber('MCP_MAX_FILE_SIZE', 10485760), // 10MB
55
+ logLevel: getEnvVar('LOG_LEVEL', 'info'),
56
+ serverHost: getOptionalEnvVar('MCP_SERVER_HOST'),
57
+ serverBaseUrl: getOptionalEnvVar('MCP_SERVER_BASE_URL'),
58
+ forcePort: getEnvBoolean('MCP_FORCE_PORT', false),
59
+ useFixedUrl: getEnvBoolean('MCP_USE_FIXED_URL', true),
60
+ enableImageToText: getEnvBoolean('MCP_ENABLE_IMAGE_TO_TEXT', true),
61
+ imageToTextPrompt: getEnvVar('MCP_IMAGE_TO_TEXT_PROMPT', '請詳細描述這張圖片的內容,包括主要元素、顏色、佈局、文字等資訊。')
62
+ };
63
+ }
64
+ /**
65
+ * 驗證配置
66
+ */
67
+ export function validateConfig(config) {
68
+ // 驗證端口範圍
69
+ if (config.webPort < 1024 || config.webPort > 65535) {
70
+ throw new MCPError(`Invalid port number: ${config.webPort}. Must be between 1024 and 65535.`, 'INVALID_PORT');
71
+ }
72
+ // 驗證超時時間(10 秒到 1 小時)
73
+ if (config.dialogTimeout < 10 || config.dialogTimeout > 3600) {
74
+ throw new MCPError(`Invalid timeout: ${config.dialogTimeout}. Must be between 10 and 3600 seconds.`, 'INVALID_TIMEOUT');
75
+ }
76
+ // 驗證文件大小限制(1KB - 100MB)
77
+ if (config.maxFileSize < 1024 || config.maxFileSize > 104857600) {
78
+ throw new MCPError(`Invalid max file size: ${config.maxFileSize}. Must be between 1KB and 100MB.`, 'INVALID_FILE_SIZE');
79
+ }
80
+ // 驗證日誌級別
81
+ const validLogLevels = ['error', 'warn', 'info', 'debug', 'silent'];
82
+ if (!validLogLevels.includes(config.logLevel)) {
83
+ throw new MCPError(`Invalid log level: ${config.logLevel}. Must be one of: ${validLogLevels.join(', ')}`, 'INVALID_LOG_LEVEL');
84
+ }
85
+ }
86
+ /**
87
+ * 獲取驗證後的配置
88
+ */
89
+ export function getConfig() {
90
+ const config = createDefaultConfig();
91
+ validateConfig(config);
92
+ return config;
93
+ }
94
+ /**
95
+ * 顯示配置資訊(隱藏敏感資訊)
96
+ */
97
+ export function displayConfig(config) {
98
+ console.log('MCP Feedback Collector Configuration:');
99
+ console.log(` Web Port: ${config.webPort}`);
100
+ console.log(` Dialog Timeout: ${config.dialogTimeout}s`);
101
+ console.log(` CORS Origin: ${config.corsOrigin}`);
102
+ console.log(` Max File Size: ${(config.maxFileSize / 1024 / 1024).toFixed(1)}MB`);
103
+ console.log(` Log Level: ${config.logLevel}`);
104
+ console.log(` API Key: ${config.apiKey ? '***configured***' : 'not set'}`);
105
+ console.log(` Server Host: ${config.serverHost || '自動檢測'}`);
106
+ console.log(` Image To Text: ${config.enableImageToText ? 'enabled' : 'disabled'}`);
107
+ }
108
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * MCP Feedback Collector - 主入口
3
+ */
4
+ export declare const VERSION = "3.0.0";
5
+ export { MCPServer } from './server/mcp-server.js';
6
+ export { WebServer } from './server/web-server.js';
7
+ export { getConfig, createDefaultConfig, validateConfig, displayConfig } from './config/index.js';
8
+ export { logger } from './utils/logger.js';
9
+ export * from './types/index.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,cAAc,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * MCP Feedback Collector - 主入口
3
+ */
4
+ export const VERSION = '3.0.0';
5
+ export { MCPServer } from './server/mcp-server.js';
6
+ export { WebServer } from './server/web-server.js';
7
+ export { getConfig, createDefaultConfig, validateConfig, displayConfig } from './config/index.js';
8
+ export { logger } from './utils/logger.js';
9
+ export * from './types/index.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClG,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * MCP Feedback Collector - MCP 服務器實現
3
+ */
4
+ import { Config } from '../types/index.js';
5
+ /**
6
+ * MCP 服務器類
7
+ */
8
+ export declare class MCPServer {
9
+ private mcpServer;
10
+ private webServer;
11
+ private config;
12
+ private isRunning;
13
+ constructor(config: Config);
14
+ /**
15
+ * 註冊 MCP 工具函數
16
+ */
17
+ private registerTools;
18
+ /**
19
+ * 實現 collect_feedback 功能
20
+ */
21
+ private collectFeedback;
22
+ /**
23
+ * 將反饋數據格式化為 MCP 內容
24
+ */
25
+ private formatFeedbackForMCP;
26
+ /**
27
+ * 啟動 MCP 服務器
28
+ */
29
+ start(): Promise<void>;
30
+ /**
31
+ * 僅啟動 Web 模式
32
+ */
33
+ startWebOnly(): Promise<void>;
34
+ /**
35
+ * 停止服務器
36
+ */
37
+ stop(): Promise<void>;
38
+ /**
39
+ * 獲取服務器狀態
40
+ */
41
+ getStatus(): {
42
+ running: boolean;
43
+ webPort?: number | undefined;
44
+ };
45
+ }
46
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/server/mcp-server.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,EAAE,MAAM,EAA4D,MAAM,mBAAmB,CAAC;AAIrG;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,MAAM;IAqB1B;;OAEG;IACH,OAAO,CAAC,aAAa;IAwCrB;;OAEG;YACW,eAAe;IAwC7B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA4C5B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC5B;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBnC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B;;OAEG;IACH,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;CAMhE"}