@analogjs/vitest-angular 1.4.0-beta.10

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,218 @@
1
+ # @analogjs/vitest-angular
2
+
3
+ A standalone builder for running tests with Vitest and Angular.
4
+
5
+ ## Installation
6
+
7
+ Use your package manager of choice to install the necessary packages.
8
+
9
+ With ng add:
10
+
11
+ ```sh
12
+ ng add @analogjs/vitest-angular
13
+ ```
14
+
15
+ With npm:
16
+
17
+ ```sh
18
+ npm install @analogjs/vitest-angular vitest --save-dev
19
+ ```
20
+
21
+ With pnpm:
22
+
23
+ ```sh
24
+ pnpm install -w @analogjs/vitest-angular vitest --dev
25
+ ```
26
+
27
+ With Yarn:
28
+
29
+ ```sh
30
+ yarn install @analogjs/vitest-angular vitest --dev
31
+ ```
32
+
33
+ ## Setup for Running Tests in Node
34
+
35
+ To setup Vitest, create a `vite.config.ts` at the root of your project:
36
+
37
+ ```ts
38
+ /// <reference types="vitest" />
39
+ import { defineConfig } from 'vite';
40
+
41
+ import angular from '@analogjs/vite-plugin-angular';
42
+
43
+ export default defineConfig(({ mode }) => ({
44
+ plugins: [angular()],
45
+ test: {
46
+ globals: true,
47
+ setupFiles: ['src/test-setup.ts'],
48
+ environment: 'jsdom',
49
+ include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
50
+ reporters: ['default'],
51
+ },
52
+ define: {
53
+ 'import.meta.vitest': mode !== 'production',
54
+ },
55
+ }));
56
+ ```
57
+
58
+ Next, define a `src/test-setup.ts` file to setup the `TestBed`:
59
+
60
+ ```ts
61
+ import '@analogjs/vitest-angular/setup-zone';
62
+
63
+ import {
64
+ BrowserDynamicTestingModule,
65
+ platformBrowserDynamicTesting,
66
+ } from '@angular/platform-browser-dynamic/testing';
67
+ import { getTestBed } from '@angular/core/testing';
68
+
69
+ getTestBed().initTestEnvironment(
70
+ BrowserDynamicTestingModule,
71
+ platformBrowserDynamicTesting()
72
+ );
73
+ ```
74
+
75
+ Next, update the `test` target in the `angular.json` to use the `@analogjs/vitest-angular:test` builder:
76
+
77
+ ```json
78
+ {
79
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
80
+ "version": 1,
81
+ "newProjectRoot": "projects",
82
+ "projects": {
83
+ "your-project": {
84
+ "projectType": "application",
85
+ "architect": {
86
+ "test": {
87
+ "builder": "@analogjs/vitest-angular:test"
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ Lastly, add the `src/test-setup.ts` to `files` array in the `tsconfig.spec.json` in the root of your project, set the `target` to `es2016`, and update the `types`.
96
+
97
+ ```json
98
+ {
99
+ "extends": "./tsconfig.json",
100
+ "compilerOptions": {
101
+ "outDir": "./out-tsc/spec",
102
+ "target": "es2016",
103
+ "types": ["vitest/globals", "node"]
104
+ },
105
+ "files": ["src/test-setup.ts"],
106
+ "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
107
+ }
108
+ ```
109
+
110
+ ## Running Tests
111
+
112
+ To run unit tests, use the `test` command:
113
+
114
+ ```shell
115
+ npm run test
116
+ ```
117
+
118
+ ```shell
119
+ yarn test
120
+ ```
121
+
122
+ ```shell
123
+ pnpm test
124
+ ```
125
+
126
+ > The `npx vitest` command can also be used directly.
127
+
128
+ ## Snapshot Testing
129
+
130
+ For snapshot testing you can use `toMatchSnapshot` from `expect` API.
131
+
132
+ Below is a small example of how to write a snapshot test:
133
+
134
+ ```ts
135
+ // card.component.spec.ts
136
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
137
+
138
+ import { CardComponent } from './card.component';
139
+
140
+ describe('CardComponent', () => {
141
+ let fixture: ComponentFixture<CardComponent>;
142
+ let component: CardComponent;
143
+
144
+ beforeEach(() =>
145
+ TestBed.configureTestingModule({
146
+ imports: [CardComponent],
147
+ })
148
+ );
149
+
150
+ beforeEach(() => {
151
+ fixture = TestBed.createComponent(CardComponent);
152
+ component = fixture.componentInstance;
153
+ fixture.detectChanges();
154
+ });
155
+
156
+ it('should create the app', () => {
157
+ expect(fixture).toMatchSnapshot();
158
+ });
159
+ });
160
+ ```
161
+
162
+ After you run the test, a `card.component.spec.ts.snap` file is created in the`__snapshots__` folder with the below content:
163
+
164
+ ```ts
165
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
166
+
167
+ exports[`CardComponent > should create the app 1`] = `
168
+ <component-code>
169
+ `;
170
+ ```
171
+
172
+ The snapshots generated should be reviewed and added to version control.
173
+
174
+ ## Using TypeScript Config Path Aliases
175
+
176
+ If you are using `paths` in your `tsconfig.json`, support for those aliases can be added to the `vite.config.ts`.
177
+
178
+ First, install the `vite-tsconfig-paths` package.
179
+
180
+ With npm:
181
+
182
+ ```shell
183
+ npm install vite-tsconfig-paths --save-dev
184
+ ```
185
+
186
+ With pnpm:
187
+
188
+ ```shell
189
+ pnpm install -w vite-tsconfig-paths --dev
190
+ ```
191
+
192
+ With Yarn:
193
+
194
+ ```shell
195
+ yarn add vite-tsconfig-paths --dev
196
+ ```
197
+
198
+ Next, add the plugin to the `plugins` array in the `vite.config.ts`.
199
+
200
+ ```ts
201
+ /// <reference types="vitest" />
202
+ import { defineConfig } from 'vite';
203
+
204
+ import angular from '@analogjs/vite-plugin-angular';
205
+ import viteTsConfigPaths from 'vite-tsconfig-paths';
206
+
207
+ export default defineConfig(({ mode }) => ({
208
+ // ...other config
209
+ plugins: [angular(), viteTsConfigPaths()],
210
+ }));
211
+ ```
212
+
213
+ ## Supporting Analog
214
+
215
+ - Star the [GitHub Repo](https://github.com/analogjs/analog)
216
+ - Join the [Discord](https://chat.analogjs.org)
217
+ - Follow us on [Twitter](https://twitter.com/analogjs)
218
+ - Become a [Sponsor](https://analogjs.org/docs/sponsoring)
package/builders.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "builders": {
3
+ "test": {
4
+ "implementation": "./src/lib/vitest.impl",
5
+ "schema": "./src/lib/schema.json",
6
+ "description": "Test with Vitest"
7
+ }
8
+ }
9
+ }
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@analogjs/vitest-angular",
3
+ "version": "1.4.0-beta.10",
4
+ "description": "Vitest Builder for Angular",
5
+ "type": "commonjs",
6
+ "author": "Brandon Roberts <robertsbt@gmail.com>",
7
+ "exports": {
8
+ ".": "./src/index.js",
9
+ "./package.json": "./package.json",
10
+ "./setup-zone": "./setup-zone.js"
11
+ },
12
+ "keywords": [
13
+ "angular",
14
+ "vite",
15
+ "vitest",
16
+ "meta-framework"
17
+ ],
18
+ "license": "MIT",
19
+ "bugs": {
20
+ "url": "https://github.com/analogjs/analog/issues"
21
+ },
22
+ "homepage": "https://analogjs.org",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/analogjs/analog.git"
26
+ },
27
+ "builders": "./builders.json",
28
+ "ng-add": {
29
+ "save": "devDependencies"
30
+ },
31
+ "peerDependencies": {
32
+ "@analogjs/vite-plugin-angular": "^1.3.0",
33
+ "@angular-devkit/architect": "^0.1500.0 || ^0.1600.0 || ^0.1700.0 || ^0.1800.0",
34
+ "vitest": "^1.3.1"
35
+ },
36
+ "ng-update": {
37
+ "packageGroup": [
38
+ "@analogjs/platform",
39
+ "@analogjs/content",
40
+ "@analogjs/router",
41
+ "@analogjs/trpc",
42
+ "@analogjs/vite-plugin-angular",
43
+ "@analogjs/vite-plugin-nitro",
44
+ "@analogjs/vitest-angular"
45
+ ]
46
+ },
47
+ "main": "./src/index.js"
48
+ }
@@ -0,0 +1,4 @@
1
+ import 'zone.js';
2
+ import 'zone.js/plugins/sync-test';
3
+ import 'zone.js/plugins/proxy';
4
+ import 'zone.js/testing';
package/setup-zone.js ADDED
@@ -0,0 +1,219 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ require("zone.js");
4
+ require("zone.js/plugins/sync-test");
5
+ require("zone.js/plugins/proxy");
6
+ require("zone.js/testing");
7
+ /**
8
+ * Patch Vitest's describe/test/beforeEach/afterEach functions so test code
9
+ * always runs in a testZone (ProxyZone).
10
+ */
11
+ /* global Zone */
12
+ const Zone = globalThis['Zone'];
13
+ if (Zone === undefined) {
14
+ throw new Error('Missing: Zone (zone.js)');
15
+ }
16
+ if (globalThis['__vitest_zone_patch__'] === true) {
17
+ throw new Error("'vitest' has already been patched with 'Zone'.");
18
+ }
19
+ globalThis['__vitest_zone_patch__'] = true;
20
+ const SyncTestZoneSpec = Zone['SyncTestZoneSpec'];
21
+ const ProxyZoneSpec = Zone['ProxyZoneSpec'];
22
+ if (SyncTestZoneSpec === undefined) {
23
+ throw new Error('Missing: SyncTestZoneSpec (zone.js/plugins/sync-test)');
24
+ }
25
+ if (ProxyZoneSpec === undefined) {
26
+ throw new Error('Missing: ProxyZoneSpec (zone.js/plugins/proxy.js)');
27
+ }
28
+ const env = globalThis;
29
+ const ambientZone = Zone.current;
30
+ // Create a synchronous-only zone in which to run `describe` blocks in order to
31
+ // raise an error if any asynchronous operations are attempted
32
+ // inside of a `describe` but outside of a `beforeEach` or `it`.
33
+ const syncZone = ambientZone.fork(new SyncTestZoneSpec('vitest.describe'));
34
+ function wrapDescribeInZone(describeBody) {
35
+ return function (...args) {
36
+ return syncZone.run(describeBody, null, args);
37
+ };
38
+ }
39
+ // Create a proxy zone in which to run `test` blocks so that the tests function
40
+ // can retroactively install different zones.
41
+ const testProxyZone = ambientZone.fork(new ProxyZoneSpec());
42
+ function wrapTestInZone(testBody) {
43
+ if (testBody === undefined) {
44
+ return;
45
+ }
46
+ const wrappedFunc = function () {
47
+ return testProxyZone.run(testBody, null, arguments);
48
+ };
49
+ try {
50
+ Object.defineProperty(wrappedFunc, 'length', {
51
+ configurable: true,
52
+ writable: true,
53
+ enumerable: false,
54
+ });
55
+ wrappedFunc.length = testBody.length;
56
+ }
57
+ catch (e) {
58
+ return testBody.length === 0
59
+ ? () => testProxyZone.run(testBody, null)
60
+ : (done) => testProxyZone.run(testBody, null, [done]);
61
+ }
62
+ return wrappedFunc;
63
+ }
64
+ /**
65
+ * Allows Vitest to handle Angular test fixtures
66
+ *
67
+ * Vitest Snapshot guide ==> https://vitest.dev/guide/snapshot.html
68
+ *
69
+ * @returns customSnapshotSerializer for Angular Fixture Component
70
+ */
71
+ const customSnapshotSerializer = () => {
72
+ function serialize(val, config, indentation, depth, refs, printer) {
73
+ // `printer` is a function that serializes a value using existing plugins.
74
+ return `${printer(fixtureVitestSerializer(val), config, indentation, depth, refs)}`;
75
+ }
76
+ function test(val) {
77
+ // * If it's a ComponentFixture we apply the transformation rules
78
+ return val && isAngularFixture(val);
79
+ }
80
+ return {
81
+ serialize,
82
+ test,
83
+ };
84
+ };
85
+ /**
86
+ * Check if is an Angular fixture
87
+ *
88
+ * @param val Angular fixture
89
+ * @returns boolean who check if is an angular fixture
90
+ */
91
+ function isAngularFixture(val) {
92
+ if (typeof val !== 'object') {
93
+ return false;
94
+ }
95
+ if (val['componentRef'] || val['componentInstance']) {
96
+ return true;
97
+ }
98
+ if (val['componentType']) {
99
+ return true;
100
+ }
101
+ // * Angular fixture keys in Fixture component Object
102
+ const fixtureKeys = [
103
+ 'componentRef',
104
+ 'ngZone',
105
+ 'effectRunner',
106
+ '_autoDetect',
107
+ '_isStable',
108
+ '_isDestroyed',
109
+ '_resolve',
110
+ '_promise',
111
+ '_onUnstableSubscription',
112
+ '_onStableSubscription',
113
+ '_onMicrotaskEmptySubscription',
114
+ '_onErrorSubscription',
115
+ 'changeDetectorRef',
116
+ 'elementRef',
117
+ 'debugElement',
118
+ 'componentInstance',
119
+ 'nativeElement',
120
+ ];
121
+ // * Angular fixture keys in Fixture componentRef Object
122
+ const fixtureComponentRefKeys = [
123
+ 'location',
124
+ '_rootLView',
125
+ '_tNode',
126
+ 'previousInputValues',
127
+ 'instance',
128
+ 'changeDetectorRef',
129
+ 'hostView',
130
+ 'componentType',
131
+ ];
132
+ return (JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureKeys) ||
133
+ JSON.stringify(Object.keys(val)) === JSON.stringify(fixtureComponentRefKeys));
134
+ }
135
+ /**
136
+ * Serialize Angular fixture for Vitest
137
+ *
138
+ * @param fixture Angular Fixture Component
139
+ * @returns HTML Child Node
140
+ */
141
+ function fixtureVitestSerializer(fixture) {
142
+ // * Get Component meta data
143
+ const componentType = (fixture && fixture.componentType
144
+ ? fixture.componentType
145
+ : fixture.componentRef.componentType);
146
+ let inputsData = '';
147
+ const selector = Reflect.getOwnPropertyDescriptor(componentType, '__annotations__')?.value[0].selector;
148
+ if (componentType && componentType.propDecorators) {
149
+ inputsData = Object.entries(componentType.propDecorators)
150
+ .map(([key, value]) => `${key}="${value}"`)
151
+ .join('');
152
+ }
153
+ // * Get DOM Elements
154
+ const divElement = fixture && fixture.nativeElement
155
+ ? fixture.nativeElement
156
+ : fixture.location.nativeElement;
157
+ // * Convert string data to HTML data
158
+ const doc = new DOMParser().parseFromString(`<${selector} ${inputsData}>${divElement.innerHTML}</${selector}>`, 'text/html');
159
+ return doc.body.childNodes[0];
160
+ }
161
+ /**
162
+ * bind describe method to wrap describe.each function
163
+ */
164
+ const bindDescribe = (originalVitestFn) => function (...eachArgs) {
165
+ return function (...args) {
166
+ args[1] = wrapDescribeInZone(args[1]);
167
+ // @ts-ignore
168
+ return originalVitestFn.apply(this, eachArgs).apply(this, args);
169
+ };
170
+ };
171
+ /**
172
+ * bind test method to wrap test.each function
173
+ */
174
+ const bindTest = (originalVitestFn) => function (...eachArgs) {
175
+ return function (...args) {
176
+ args[1] = wrapTestInZone(args[1]);
177
+ // @ts-ignore
178
+ return originalVitestFn.apply(this, eachArgs).apply(this, args);
179
+ };
180
+ };
181
+ ['describe'].forEach((methodName) => {
182
+ const originalvitestFn = env[methodName];
183
+ env[methodName] = function (...args) {
184
+ args[1] = wrapDescribeInZone(args[1]);
185
+ return originalvitestFn.apply(this, args);
186
+ };
187
+ env[methodName].each = bindDescribe(originalvitestFn.each);
188
+ if (methodName === 'describe') {
189
+ env[methodName].only = bindDescribe(originalvitestFn.only);
190
+ env[methodName].skip = bindDescribe(originalvitestFn.skip);
191
+ }
192
+ });
193
+ ['test', 'it'].forEach((methodName) => {
194
+ const originalvitestFn = env[methodName];
195
+ env[methodName] = function (...args) {
196
+ args[1] = wrapTestInZone(args[1]);
197
+ return originalvitestFn.apply(this, args);
198
+ };
199
+ env[methodName].each = bindTest(originalvitestFn.each);
200
+ env[methodName].only = bindTest(originalvitestFn.only);
201
+ env[methodName].skip = bindTest(originalvitestFn.skip);
202
+ if (methodName === 'test' || methodName === 'it') {
203
+ env[methodName].todo = function (...args) {
204
+ return originalvitestFn.todo.apply(this, args);
205
+ };
206
+ }
207
+ });
208
+ ['beforeEach', 'afterEach', 'beforeAll', 'afterAll'].forEach((methodName) => {
209
+ const originalvitestFn = env[methodName];
210
+ env[methodName] = function (...args) {
211
+ args[0] = wrapTestInZone(args[0]);
212
+ return originalvitestFn.apply(this, args);
213
+ };
214
+ });
215
+ ['expect'].forEach((methodName) => {
216
+ const originalvitestFn = env[methodName];
217
+ return originalvitestFn.addSnapshotSerializer(customSnapshotSerializer());
218
+ });
219
+ //# sourceMappingURL=setup-zone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-zone.js","sourceRoot":"","sources":["../../../packages/vitest-angular/setup-zone.ts"],"names":[],"mappings":"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"}
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import vitestBuilder from './lib/vitest.impl';
2
+ export { vitestBuilder };
package/src/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.vitestBuilder = void 0;
4
+ const vitest_impl_1 = require("./lib/vitest.impl");
5
+ exports.vitestBuilder = vitest_impl_1.default;
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/vitest-angular/src/index.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAErC,wBAFF,qBAAa,CAEE"}
@@ -0,0 +1,34 @@
1
+ {
2
+ "version": 2,
3
+ "cli": "nx",
4
+ "title": "Vitest Builder for Angular",
5
+ "description": "Run unit tests using Vitest.",
6
+ "type": "object",
7
+ "properties": {
8
+ "configFile": {
9
+ "type": "string",
10
+ "description": "The path to the local vitest config",
11
+ "x-completion-type": "file",
12
+ "x-completion-glob": "@(vitest|vite).config@(.js|.ts)",
13
+ "aliases": ["config"]
14
+ },
15
+ "reportsDirectory": {
16
+ "type": "string",
17
+ "description": "Directory to write coverage report to."
18
+ },
19
+ "mode": {
20
+ "type": "string",
21
+ "description": "Mode for Vite."
22
+ },
23
+ "testFiles": {
24
+ "aliases": ["testFile"],
25
+ "type": "array",
26
+ "items": { "type": "string" }
27
+ },
28
+ "watch": {
29
+ "description": "Watch files for changes and rerun tests related to changed files.",
30
+ "type": "boolean"
31
+ }
32
+ },
33
+ "required": []
34
+ }
@@ -0,0 +1,4 @@
1
+ import { VitestSchema } from './schema';
2
+ export declare function getExtraArgs(options: VitestSchema): Promise<Record<string, any>>;
3
+ declare const _default: any;
4
+ export default _default;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getExtraArgs = void 0;
4
+ const architect_1 = require("@angular-devkit/architect");
5
+ async function vitestBuilder(options, context) {
6
+ process.env['TEST'] = 'true';
7
+ process.env['VITEST'] = 'true';
8
+ const { startVitest } = await Function('return import("vitest/node")')();
9
+ const projectConfig = await context.getProjectMetadata(context.target);
10
+ const extraArgs = await getExtraArgs(options);
11
+ const config = {
12
+ root: `${projectConfig['root'] || '.'}`,
13
+ watch: options.watch === true,
14
+ ...extraArgs,
15
+ };
16
+ const server = await startVitest('test', options.testFiles ?? [], config);
17
+ let hasErrors = false;
18
+ const processExit = () => {
19
+ server?.exit();
20
+ if (hasErrors) {
21
+ process.exit(1);
22
+ }
23
+ else {
24
+ process.exit(0);
25
+ }
26
+ };
27
+ if (options.watch) {
28
+ process.on('SIGINT', processExit);
29
+ process.on('SIGTERM', processExit);
30
+ process.on('exit', processExit);
31
+ }
32
+ // vitest sets the exitCode = 1 when code coverage isn't met
33
+ hasErrors = (process.exitCode && process.exitCode !== 0);
34
+ return {
35
+ success: !hasErrors,
36
+ };
37
+ }
38
+ async function getExtraArgs(options) {
39
+ // support passing extra args to Vitest CLI
40
+ const schema = await Promise.resolve().then(() => require('./schema.json'));
41
+ const extraArgs = {};
42
+ for (const key of Object.keys(options)) {
43
+ if (!schema.properties[key]) {
44
+ extraArgs[key] = options[key];
45
+ }
46
+ }
47
+ return extraArgs;
48
+ }
49
+ exports.getExtraArgs = getExtraArgs;
50
+ exports.default = (0, architect_1.createBuilder)(vitestBuilder);
51
+ //# sourceMappingURL=vitest.impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest.impl.js","sourceRoot":"","sources":["../../../../../packages/vitest-angular/src/lib/vitest.impl.ts"],"names":[],"mappings":";;;AAAA,yDAImC;AAInC,KAAK,UAAU,aAAa,CAC1B,OAAqB,EACrB,OAAuB;IAEvB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC;IAE/B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAO,QAAQ,CACrC,8BAA8B,CAC/B,EAA4C,CAAC;IAE9C,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,kBAAkB,CACpD,OAAO,CAAC,MAA2B,CACpC,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE;QACvC,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,IAAI;QAC7B,GAAG,SAAS;KACb,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;IAE1E,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,MAAM,WAAW,GAAG,GAAG,EAAE;QACvB,MAAM,EAAE,IAAI,EAAE,CAAC;QACf,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACnC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,CAAC;IAED,4DAA4D;IAC5D,SAAS,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC,CAAY,CAAC;IAEpE,OAAO;QACL,OAAO,EAAE,CAAC,SAAS;KACpB,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,YAAY,CAChC,OAAqB;IAErB,2CAA2C;IAC3C,MAAM,MAAM,GAAG,2CAAa,eAAe,EAAC,CAAC;IAC7C,MAAM,SAAS,GAAwB,EAAE,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACvC,IAAI,CAAE,MAAc,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,SAAS,CAAC,GAAG,CAAC,GAAI,OAAe,CAAC,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAbD,oCAaC;AAED,kBAAe,IAAA,yBAAa,EAAC,aAAa,CAAQ,CAAC"}