fan-components 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.
Files changed (33) hide show
  1. package/README.md +638 -0
  2. package/dist/components/Button/index.d.ts +3 -0
  3. package/dist/components/Button/index.d.ts.map +1 -0
  4. package/dist/components/Button/src/button.d.ts +40 -0
  5. package/dist/components/Button/src/button.d.ts.map +1 -0
  6. package/dist/components/Button/src/button.vue.d.ts +97 -0
  7. package/dist/components/Button/src/button.vue.d.ts.map +1 -0
  8. package/dist/components/Button/test/button.test.d.ts +2 -0
  9. package/dist/components/Button/test/button.test.d.ts.map +1 -0
  10. package/dist/components/Collapse/index.d.ts +3 -0
  11. package/dist/components/Collapse/index.d.ts.map +1 -0
  12. package/dist/components/Collapse/src/Collapse.d.ts +21 -0
  13. package/dist/components/Collapse/src/Collapse.d.ts.map +1 -0
  14. package/dist/components/Collapse/src/Collapse.vue.d.ts +28 -0
  15. package/dist/components/Collapse/src/Collapse.vue.d.ts.map +1 -0
  16. package/dist/components/Collapse/src/CollapseItem.vue.d.ts +33 -0
  17. package/dist/components/Collapse/src/CollapseItem.vue.d.ts.map +1 -0
  18. package/dist/components/Icon/index.d.ts +3 -0
  19. package/dist/components/Icon/index.d.ts.map +1 -0
  20. package/dist/components/Icon/src/Icon.d.ts +29 -0
  21. package/dist/components/Icon/src/Icon.d.ts.map +1 -0
  22. package/dist/components/Icon/src/Icon.vue.d.ts +206 -0
  23. package/dist/components/Icon/src/Icon.vue.d.ts.map +1 -0
  24. package/dist/components/index.d.ts +4 -0
  25. package/dist/components/index.d.ts.map +1 -0
  26. package/dist/components/index.js +1 -0
  27. package/dist/components/package.json +23 -0
  28. package/dist/components/types.d.ts +8 -0
  29. package/dist/theme-chalk/fonts/element-icons.ttf +0 -0
  30. package/dist/theme-chalk/fonts/element-icons.woff +0 -0
  31. package/dist/theme-chalk/index.css +1 -0
  32. package/dist/theme-chalk/package.json +12 -0
  33. package/package.json +79 -0
package/README.md ADDED
@@ -0,0 +1,638 @@
1
+ # monorepo工程管理
2
+
3
+ ## 解决问题
4
+
5
+ 1.统一打包2.建立包依赖3.统一测试4.发布
6
+
7
+ ## mutirepo vs monorepo
8
+
9
+ 常见monorepo管理工具:
10
+
11
+ - **pnpm**
12
+ - npm
13
+ - Yarn
14
+ - Lerna
15
+ - Nx
16
+ - Turborepo
17
+ - Rush
18
+ - ...
19
+
20
+ ### pnpm monorepo
21
+
22
+ ```shell
23
+ touch pnpm-workspace.yaml
24
+ ```
25
+
26
+ ```yaml
27
+ # pnpm-workspace.yaml
28
+
29
+ packages:
30
+ - "packages/*"
31
+ - "apps/*"
32
+ ```
33
+
34
+ 执行工程级命令
35
+
36
+ ```shell
37
+ pnpm --workspace-root [...]
38
+ ```
39
+
40
+
41
+
42
+ ```shell
43
+ pnpm -w [...]
44
+ ```
45
+
46
+ 执行子包命令
47
+
48
+ ```shell
49
+ 进入子目录中执行
50
+ ```
51
+
52
+
53
+
54
+ ```shell
55
+ pnpm -C 子包路径 [...]
56
+ ```
57
+
58
+ ## 环境版本锁定
59
+
60
+ ```json
61
+ // package.json
62
+ "engines": {
63
+ "node": ">=22.14.0",
64
+ "npm": ">=10.9.2",
65
+ "pnpm": ">=10.15.1"
66
+ }
67
+ ```
68
+
69
+ ```yaml
70
+ # .npmrc
71
+ engine-strict=true
72
+ ```
73
+
74
+ ## TypeScript
75
+
76
+ ```shell
77
+ pnpm -Dw add typescript @types/node
78
+ ```
79
+
80
+ ```shell
81
+ touch tsconfig.json
82
+ ```
83
+
84
+ ```json
85
+ // tsconfig.json
86
+ {
87
+ "compilerOptions": {
88
+ "baseUrl": ".",
89
+ "module": "esnext",
90
+ "target": "esnext",
91
+ "types": [],
92
+ "lib": ["esnext"],
93
+ "sourceMap": true,
94
+ "declaration": true,
95
+ "declarationMap": true,
96
+ "noUncheckedIndexedAccess": true,
97
+ "exactOptionalPropertyTypes": true,
98
+ "strict": true,
99
+ "verbatimModuleSyntax": false,
100
+ "moduleResolution": "bundler",
101
+ "isolatedModules": true,
102
+ "noUncheckedSideEffectImports": true,
103
+ "moduleDetection": "force",
104
+ "skipLibCheck": true
105
+ },
106
+ "exclude": ["node_modules", "dist"]
107
+ }
108
+ ```
109
+
110
+ ```json
111
+ // apps/backend/tsconfig.json
112
+ {
113
+ "extends": "../../tsconfig.json",
114
+ "compilerOptions": {
115
+ "types": ["node"],
116
+ "lib": ["esnext"]
117
+ },
118
+ "include": ["src"]
119
+ }
120
+ ```
121
+
122
+ ```json
123
+ // apps/frontend/tsconfig.json
124
+ {
125
+ "extends": "../../tsconfig.json",
126
+ "compilerOptions": {
127
+ "types": ["node"],
128
+ "lib": ["esnext", "DOM"]
129
+ },
130
+ "include": ["src"]
131
+ }
132
+ ```
133
+
134
+ ## 代码风格与质量检查
135
+
136
+ ### prettier
137
+
138
+ `prettier`安装
139
+
140
+ ```shell
141
+ pnpm -Dw add prettier
142
+ ```
143
+
144
+ `prettier`配置
145
+
146
+ ```shell
147
+ touch prettier.config.js
148
+ ```
149
+
150
+ ```js
151
+ // prettier.config.js
152
+ /**
153
+ * @type {import('prettier').Config}
154
+ * @see https://www.prettier.cn/docs/options.html
155
+ */
156
+ export default {
157
+ // 指定最大换行长度
158
+ printWidth: 120,
159
+ // 缩进制表符宽度 | 空格数
160
+ tabWidth: 2,
161
+ // 使用制表符而不是空格缩进行 (true:制表符,false:空格)
162
+ useTabs: false,
163
+ // 结尾不用分号 (true:有,false:没有)
164
+ semi: true,
165
+ // 使用单引号 (true:单引号,false:双引号)
166
+ singleQuote: false,
167
+ // 在对象字面量中决定是否将属性名用引号括起来 可选值 "<as-needed|consistent|preserve>"
168
+ quoteProps: "as-needed",
169
+ // 在JSX中使用单引号而不是双引号 (true:单引号,false:双引号)
170
+ jsxSingleQuote: false,
171
+ // 多行时尽可能打印尾随逗号 可选值"<none|es5|all>"
172
+ trailingComma: "none",
173
+ // 在对象,数组括号与文字之间加空格 "{ foo: bar }" (true:有,false:没有)
174
+ bracketSpacing: true,
175
+ // 将 > 多行元素放在最后一行的末尾,而不是单独放在下一行 (true:放末尾,false:单独一行)
176
+ bracketSameLine: false,
177
+ // (x) => {} 箭头函数参数只有一个时是否要有小括号 (avoid:省略括号,always:不省略括号)
178
+ arrowParens: "avoid",
179
+ // 指定要使用的解析器,不需要写文件开头的 @prettier
180
+ requirePragma: false,
181
+ // 可以在文件顶部插入一个特殊标记,指定该文件已使用 Prettier 格式化
182
+ insertPragma: false,
183
+ // 用于控制文本是否应该被换行以及如何进行换行
184
+ proseWrap: "preserve",
185
+ // 在html中空格是否是敏感的 "css" - 遵守 CSS 显示属性的默认值, "strict" - 空格被认为是敏感的 ,"ignore" - 空格被认为是不敏感的
186
+ htmlWhitespaceSensitivity: "css",
187
+ // 控制在 Vue 单文件组件中 <script> 和 <style> 标签内的代码缩进方式
188
+ vueIndentScriptAndStyle: false,
189
+ // 换行符使用 lf 结尾是 可选值 "<auto|lf|crlf|cr>"
190
+ endOfLine: "auto",
191
+ // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码 (rangeStart:开始,rangeEnd:结束)
192
+ rangeStart: 0,
193
+ rangeEnd: Infinity
194
+ };
195
+ ```
196
+
197
+ `prettier`忽略项
198
+
199
+ ```shell
200
+ touch .prettierignore
201
+ ```
202
+
203
+ ```yaml
204
+ # .prettierignore
205
+ dist
206
+ public
207
+ .local
208
+ node_modules
209
+ pnpm-lock.yaml
210
+ ```
211
+
212
+ `prettier`脚本命令
213
+
214
+ ```json
215
+ "scripts":{
216
+ //......其他省略
217
+ "lint:prettier": "prettier --write \"**/*.{js,ts,mjs,cjs,json,tsx,css,less,scss,vue,html,md}\"",
218
+ }
219
+ ```
220
+
221
+ 执行命令
222
+
223
+ ```shell
224
+ pnpm run lint:prettier
225
+ pnpm lint:prettier
226
+ ```
227
+
228
+ ### ESLint
229
+
230
+ ```shell
231
+ pnpm -Dw add eslint@latest @eslint/js globals typescript-eslint eslint-plugin-prettier eslint-config-prettier eslint-plugin-vue
232
+ ```
233
+
234
+ | 类别 | 库名 |
235
+ | -------------------- | -------------------------------------------------- |
236
+ | **核心引擎** | `eslint` |
237
+ | **官方规则集** | `@eslint/js` |
238
+ | **全局变量支持** | `globals` |
239
+ | **TypeScript 支持** | `typescript-eslint` |
240
+ | **类型定义(辅助)** | `@types/node` |
241
+ | **Prettier 集成** | `eslint-plugin-prettier`, `eslint-config-prettier` |
242
+ | **Vue.js 支持** | `eslint-plugin-vue` |
243
+
244
+ 配置
245
+
246
+ ```shell
247
+ touch eslint.config.js
248
+ ```
249
+
250
+ ```js
251
+ import { defineConfig } from "eslint/config";
252
+ import eslint from "@eslint/js";
253
+ import tseslint from "typescript-eslint";
254
+ import eslintPluginPrettier from "eslint-plugin-prettier";
255
+ import eslintPluginVue from "eslint-plugin-vue";
256
+ import globals from "globals";
257
+ import eslintConfigPrettier from "eslint-config-prettier/flat";
258
+
259
+ const ignores = ["**/dist/**", "**/node_modules/**", ".*", "scripts/**", "**/*.d.ts"];
260
+
261
+ export default defineConfig(
262
+ // 通用配置
263
+ {
264
+ ignores, // 忽略项
265
+ extends: [eslint.configs.recommended, ...tseslint.configs.recommended, eslintConfigPrettier], // 继承规则
266
+ plugins: {
267
+ prettier: eslintPluginPrettier
268
+ },
269
+ languageOptions: {
270
+ ecmaVersion: "latest", // ecma语法支持版本
271
+ sourceType: "module", // 模块化类型
272
+ parser: tseslint.parser // 解析器
273
+ },
274
+ rules: {
275
+ // 自定义
276
+ }
277
+ },
278
+ // 前端配置
279
+ {
280
+ ignores,
281
+ files: ["apps/frontend/**/*.{ts,js,tsx,jsx,vue}", "packages/components/**/*.{ts,js,tsx,jsx,vue}"],
282
+ extends: [...eslintPluginVue.configs["flat/recommended"], eslintConfigPrettier],
283
+ languageOptions: {
284
+ globals: {
285
+ ...globals.browser
286
+ }
287
+ }
288
+ },
289
+ // 后端配置
290
+ {
291
+ ignores,
292
+ files: ["apps/backend/**/*.{ts,js}"],
293
+ languageOptions: {
294
+ globals: {
295
+ ...globals.node
296
+ }
297
+ }
298
+ }
299
+ );
300
+ ```
301
+
302
+ 脚本命令
303
+
304
+ ```json
305
+ "scripts":{
306
+ //......其他省略
307
+ "lint:eslint": "eslint",
308
+ }
309
+ ```
310
+
311
+ ### 拼写检查
312
+
313
+ vscode插件: Code Spell Checker
314
+
315
+ 安装
316
+
317
+ ```shell
318
+ pnpm -Dw add cspell @cspell/dict-lorem-ipsum
319
+ ```
320
+
321
+ 配置
322
+
323
+ ```shell
324
+ touch cspell.json
325
+ ```
326
+
327
+ ```json
328
+ {
329
+ "import": ["@cspell/dict-lorem-ipsum/cspell-ext.json"],
330
+ "caseSensitive": false,
331
+ "dictionaries": ["custom-dictionary"],
332
+ "dictionaryDefinitions": [
333
+ {
334
+ "name": "custom-dictionary",
335
+ "path": "./.cspell/custom-dictionary.txt",
336
+ "addWords": true
337
+ }
338
+ ],
339
+ "ignorePaths": [
340
+ "**/node_modules/**",
341
+ "**/dist/**",
342
+ "**/build/**",
343
+ "**/lib/**",
344
+ "**/docs/**",
345
+ "**/vendor/**",
346
+ "**/public/**",
347
+ "**/static/**",
348
+ "**/out/**",
349
+ "**/tmp/**",
350
+ "**/*.d.ts",
351
+ "**/package.json",
352
+ "**/*.md",
353
+ "**/stats.html",
354
+ "eslint.config.mjs",
355
+ ".gitignore",
356
+ ".prettierignore",
357
+ "cspell.json",
358
+ "commitlint.config.js",
359
+ ".cspell"
360
+ ]
361
+ }
362
+ ```
363
+
364
+ 自定义字典
365
+
366
+ ```shell
367
+ mkdir -p ./.cspell && touch ./.cspell/custom-dictionary.txt
368
+ ```
369
+
370
+ 检查脚本
371
+
372
+ ```json
373
+ "lint:spellcheck": "cspell lint \"(packages|apps)/**/*.{js,ts,mjs,cjs,json,css,less,scss,vue,html,md}\""
374
+ ```
375
+
376
+ ## git提交规范
377
+
378
+ git仓库创建
379
+
380
+ ```shell
381
+ touch .gitignore
382
+ ```
383
+
384
+ ```yaml
385
+ # .gitignore
386
+ # Node
387
+ node_modules/
388
+ dist/
389
+ build/
390
+ .env
391
+ .env.*
392
+ *.log
393
+ npm-debug.log*
394
+ yarn-debug.log*
395
+ yarn-error.log*
396
+ pnpm-debug.log*
397
+
398
+ # IDE
399
+ .vscode/
400
+ .idea/
401
+ *.suo
402
+ *.ntvs*
403
+ *.njsproj
404
+ *.sln
405
+ *.sw?
406
+
407
+ # OS
408
+ .DS_Store
409
+ Thumbs.db
410
+
411
+ # TypeScript
412
+ *.tsbuildinfo
413
+
414
+ # Misc
415
+ coverage/
416
+ *.local
417
+ *.cache
418
+ *.tmp
419
+
420
+ # Git
421
+ .git/
422
+ ```
423
+
424
+ ```shell
425
+ git init
426
+ ```
427
+
428
+ ### commitizen
429
+
430
+ 安装
431
+
432
+ ```shell
433
+ pnpm -Dw add @commitlint/cli @commitlint/config-conventional commitizen cz-git
434
+ ```
435
+
436
+ - `@commitlint/cli 是 commitlint` 工具的核心。
437
+ - `@commitlint/config-conventional` 是基于 conventional commits 规范的配置文件。
438
+ - `commitizen` 提供了一个交互式撰写commit信息的插件
439
+ - [cz-git](https://cz-git.qbb.sh/zh/guide/)是国人开发了这一款工具,工程性更强,自定义更高,交互性更好。
440
+
441
+ 配置命令
442
+
443
+ ```json
444
+ // package.json
445
+ "scripts": {
446
+ // 其他省略
447
+ "commit": "git-cz"
448
+ },
449
+ "config": {
450
+ "commitizen": {
451
+ "path": "node_modules/cz-git"
452
+ }
453
+ }
454
+ ```
455
+
456
+ 配置`cz-git`
457
+
458
+ ```shell
459
+ touch commitlint.config.js
460
+ ```
461
+
462
+ ```js
463
+ /** @type {import('cz-git').UserConfig} */
464
+ export default {
465
+ extends: ["@commitlint/config-conventional"],
466
+ rules: {
467
+ // @see: https://commitlint.js.org/#/reference-rules
468
+ "body-leading-blank": [2, "always"],
469
+ "footer-leading-blank": [1, "always"],
470
+ "header-max-length": [2, "always", 108],
471
+ "subject-empty": [2, "never"],
472
+ "type-empty": [2, "never"],
473
+ "subject-case": [0],
474
+ "type-enum": [
475
+ 2,
476
+ "always",
477
+ [
478
+ "feat",
479
+ "fix",
480
+ "docs",
481
+ "style",
482
+ "refactor",
483
+ "perf",
484
+ "test",
485
+ "build",
486
+ "ci",
487
+ "chore",
488
+ "revert",
489
+ "wip",
490
+ "workflow",
491
+ "types",
492
+ "release"
493
+ ]
494
+ ]
495
+ },
496
+ prompt: {
497
+ types: [
498
+ { value: "feat", name: "✨ 新功能: 新增功能" },
499
+ { value: "fix", name: "🐛 修复: 修复缺陷" },
500
+ { value: "docs", name: "📚 文档: 更新文档" },
501
+ { value: "refactor", name: "📦 重构: 代码重构(不新增功能也不修复 bug)" },
502
+ { value: "perf", name: "🚀 性能: 提升性能" },
503
+ { value: "test", name: "🧪 测试: 添加测试" },
504
+ { value: "chore", name: "🔧 工具: 更改构建流程或辅助工具" },
505
+ { value: "revert", name: "⏪ 回滚: 代码回滚" },
506
+ { value: "style", name: "🎨 样式: 格式调整(不影响代码运行)" }
507
+ ],
508
+ scopes: ["root", "backend", "frontend", "components", "utils"],
509
+ allowCustomScopes: true,
510
+ skipQuestions: ["body", "footerPrefix", "footer", "breaking"], // 跳过“详细描述”和“底部信息”
511
+ messages: {
512
+ type: "📌 请选择提交类型:",
513
+ scope: "🎯 请选择影响范围 (可选):",
514
+ subject: "📝 请简要描述更改:",
515
+ body: "🔍 详细描述 (可选):",
516
+ footer: "🔗 关联的 ISSUE 或 BREAKING CHANGE (可选):",
517
+ confirmCommit: "✅ 确认提交?"
518
+ }
519
+ }
520
+ };
521
+ ```
522
+
523
+ ### husky
524
+
525
+ 安装`husky`
526
+
527
+ ```shell
528
+ pnpm -Dw add husky
529
+ ```
530
+
531
+ 初始化
532
+
533
+ ```cmd
534
+ pnpx husky init
535
+ ```
536
+
537
+ 配置
538
+
539
+ ```cmd
540
+ #!/usr/bin/env sh
541
+ pnpm lint:prettier && pnpm lint:eslint && pnpm lint:spellcheck
542
+ ```
543
+
544
+ ### lint-staged
545
+
546
+ 安装
547
+
548
+ ```shell
549
+ pnpm -Dw add lint-staged
550
+ ```
551
+
552
+ 配置命令
553
+
554
+ ```json
555
+ "precommit": "lint-staged"
556
+ ```
557
+
558
+ 配置文件
559
+
560
+ ```js
561
+ // .lintstagedrc.js
562
+ export default {
563
+ "*.{js,ts,mjs,cjs,json,tsx,css,less,scss,vue,html,md}": ["cspell lint"],
564
+ "*.{js,ts,vue,md}": ["prettier --write", "eslint"]
565
+ };
566
+ ```
567
+
568
+ 重新配置husky
569
+
570
+ ```cmd
571
+ #!/usr/bin/env sh
572
+ pnpm precommit
573
+ ```
574
+
575
+ ## 公共库打包
576
+
577
+ 安装`rollup`
578
+
579
+ ```shell
580
+ pnpm -Dw add rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs rollup-plugin-typescript2 @rollup/plugin-terser @vitejs/plugin-vue rollup-plugin-postcss
581
+ ```
582
+
583
+ - `@rollup/plugin-node-resolve`: 解析 node_modules 中的依赖
584
+ - `@rollup/plugin-commonjs`: 将 CommonJS 模块转为 ESM
585
+ - `rollup-plugin-typescript2`: 让 Rollup 支持 TS 编译
586
+ - `@rollup/plugin-terser`: 压缩和混淆
587
+ - `@vitejs/plugin-vue`: 支持SFC编译
588
+ - `rollup-plugin-postcss`: 处理css代码
589
+
590
+ 配置: 略
591
+
592
+ ## 子包间依赖
593
+
594
+ ```json
595
+ {
596
+ "foo": "workspace:*",
597
+ "bar": "workspace:^1.0.0"
598
+ }
599
+ ```
600
+
601
+ ## 单元测试
602
+
603
+ 安装
604
+
605
+ ```shell
606
+ pnpm -Dw add vitest @vitest/browser vitest-browser-vue vue
607
+ ```
608
+
609
+ 添加命令
610
+
611
+ ```json
612
+ "test": "vitest"
613
+ ```
614
+
615
+ 更改`tsconfig.json`
616
+
617
+ ```json
618
+ "types": ["vitest/globals", "@vitest/browser/matchers"],
619
+ "lib": ["esnext", "DOM"],
620
+ ```
621
+
622
+ 安装vscode插件: vitest
623
+
624
+ 编写测试脚本: 略
625
+
626
+ ## 发布
627
+
628
+ ## 命令
629
+
630
+ pnpm add -F xxx add common (为每个子应用安装公共的common方法库)
631
+
632
+ # 将 utils 安装到 components 子包中
633
+
634
+ pnpm add @fan-components/utils --filter @fan-components/components
635
+
636
+ # 在根目录执行,将 @fan-components/components 添加到根 package.json
637
+
638
+ pnpm add @fan-components/components -w
@@ -0,0 +1,3 @@
1
+ declare const _default: any;
2
+ export default _default;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../packages/components/Button/index.ts"],"names":[],"mappings":";AAGA,wBAAmC"}
@@ -0,0 +1,40 @@
1
+ import type { PropType } from "vue";
2
+ export type ButtonType = "primary" | "success" | "warning" | "danger" | "info";
3
+ export type ButtonSize = "large" | "small";
4
+ export type NativeType = "button" | "submit" | "reset";
5
+ export interface ButtonProps {
6
+ type?: ButtonType;
7
+ size?: ButtonSize;
8
+ plain?: boolean;
9
+ round?: boolean;
10
+ circle?: boolean;
11
+ disabled?: boolean;
12
+ nativeType?: NativeType;
13
+ autofocus?: boolean;
14
+ icon?: string;
15
+ loading?: boolean;
16
+ }
17
+ export interface ButtonInstance {
18
+ ref: HTMLButtonElement;
19
+ }
20
+ export declare const buttonProps: {
21
+ type: {
22
+ type: PropType<ButtonType>;
23
+ };
24
+ size: {
25
+ type: PropType<ButtonSize>;
26
+ };
27
+ plain: {
28
+ type: BooleanConstructor;
29
+ };
30
+ round: {
31
+ type: BooleanConstructor;
32
+ };
33
+ circle: {
34
+ type: BooleanConstructor;
35
+ };
36
+ disabled: {
37
+ type: BooleanConstructor;
38
+ };
39
+ };
40
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../packages/components/Button/src/button.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AACpC,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;AAC/E,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAC3C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AACD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,iBAAiB,CAAC;CACxB;AACD,eAAO,MAAM,WAAW;;cAEJ,QAAQ,CAAC,UAAU,CAAC;;;cAGpB,QAAQ,CAAC,UAAU,CAAC;;;;;;;;;;;;;;CAcvC,CAAC"}