@galacean/engine-spine 0.0.0-experimental-2024071602 → 0.0.0-experimental-2024071801

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 (44) hide show
  1. package/README.md +2 -2
  2. package/dist/browser.js +1 -1
  3. package/dist/main.js +1 -1
  4. package/dist/main.js.map +1 -1
  5. package/dist/miniprogram.js +1 -1
  6. package/dist/module.js +1 -1
  7. package/dist/module.js.map +1 -1
  8. package/package.json +15 -5
  9. package/types/cypress.config.d.ts +2 -0
  10. package/types/e2e/case/.mockForE2E.d.ts +3 -0
  11. package/types/e2e/case/mix-and-match.d.ts +1 -0
  12. package/types/e2e/case/raptor.d.ts +1 -0
  13. package/types/e2e/case/spine-boy.d.ts +1 -0
  14. package/types/e2e/config.d.ts +19 -0
  15. package/types/e2e/support/commands.d.ts +8 -0
  16. package/types/e2e/support/e2e.d.ts +1 -0
  17. package/types/e2e/tests/index.cy.d.ts +1 -0
  18. package/types/example/main.d.ts +1 -0
  19. package/types/example/outline.d.ts +11 -0
  20. package/types/jest.setup.d.ts +5 -0
  21. package/types/src/SpineAnimationRenderer.d.ts +213 -0
  22. package/types/src/SpineGenerator.d.ts +37 -0
  23. package/types/src/SpineMaterial.d.ts +6 -0
  24. package/types/src/index.d.ts +7 -0
  25. package/types/src/loader/EditorSpineAtlasLoader.d.ts +6 -0
  26. package/types/src/loader/LoaderUtils.d.ts +18 -0
  27. package/types/src/loader/SkeletonDataResource.d.ts +12 -0
  28. package/types/src/loader/SpineLoader.d.ts +29 -0
  29. package/types/src/util/BlendMode.d.ts +4 -0
  30. package/types/src/util/BufferReader.d.ts +10 -0
  31. package/types/src/util/ClearablePool.d.ts +8 -0
  32. package/types/src/util/ReturnablePool.d.ts +8 -0
  33. package/types/tests/SpineAnimation.test.d.ts +1 -0
  34. package/types/tests/SpineGenerator.test.d.ts +1 -0
  35. package/types/tests/SpineMaterial.test.d.ts +1 -0
  36. package/types/tests/loader/EditorSpineAtlasLoader.test.d.ts +1 -0
  37. package/types/tests/loader/SkeletonDataResource.test.d.ts +1 -0
  38. package/types/tests/loader/SpineLoader.test.d.ts +1 -0
  39. package/types/tests/loader/loaderUtil.test.d.ts +0 -0
  40. package/types/tests/testUtils.d.ts +3 -0
  41. package/types/tests/util/BlendMode.test.d.ts +1 -0
  42. package/types/tests/util/BufferReader.test.d.ts +1 -0
  43. package/types/tests/util/ClearablePool.test.d.ts +1 -0
  44. package/types/tests/util/ReturnablePool.test.d.ts +1 -0
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.0-experimental-2024071602",
2
+ "version": "0.0.0-experimental-2024071801",
3
3
  "description": "galacean spine runtime",
4
4
  "name": "@galacean/engine-spine",
5
5
  "main": "dist/main.js",
@@ -36,15 +36,17 @@
36
36
  "@vitejs/plugin-basic-ssl": "^1.1.0",
37
37
  "babel-core": "^6.26.3",
38
38
  "babel-jest": "^29.7.0",
39
- "canvas": "^2.11.2",
40
39
  "chai": "^4.3.6",
41
40
  "chai-spies": "^1.0.0",
42
41
  "cross-env": "^5.2.1",
43
42
  "cypress": "^13.13.0",
43
+ "cypress-recurse": "^1.35.3",
44
44
  "dat.gui": "^0.7.9",
45
- "electron": "^12.0.0",
46
45
  "jest": "^29.7.0",
47
46
  "jest-environment-jsdom": "^29.7.0",
47
+ "jest-webgl-canvas-mock": "^2.5.3",
48
+ "nock": "^13.5.4",
49
+ "odiff-bin": "^3.0.1",
48
50
  "react": "^16.14.0",
49
51
  "react-dom": "^16.14.0",
50
52
  "regenerator-runtime": "^0.14.1",
@@ -55,12 +57,13 @@
55
57
  "rollup-plugin-swc3": "^0.8.0",
56
58
  "rollup-plugin-terser": "^7.0.2",
57
59
  "rollup-plugin-version-injector": "^1.3.3",
60
+ "sass": "^1.77.8",
58
61
  "sinon": "^18.0.0",
59
62
  "ts-jest": "^29.2.2",
60
63
  "ts-node": "^10.9.2",
61
64
  "tsconfig-paths": "^4.2.0",
62
65
  "typescript": "^5.5.3",
63
- "vite": "^4.3.9"
66
+ "vite": "^5.3.4"
64
67
  },
65
68
  "ci": {
66
69
  "type": "aci",
@@ -74,7 +77,7 @@
74
77
  "runner": "jest-runner",
75
78
  "testEnvironment": "jsdom",
76
79
  "testEnvironmentOptions": {
77
- "url": "https://jestjs.io/",
80
+ "url": "https://mdn.alipayobjects.com/",
78
81
  "userAgent": "Agent/007"
79
82
  },
80
83
  "preset": "ts-jest",
@@ -89,6 +92,10 @@
89
92
  },
90
93
  "transformIgnorePatterns": [
91
94
  "node_modules/(?!(.*@esotericsoftware/spine-core.*))"
95
+ ],
96
+ "setupFilesAfterEnv": [
97
+ "./jest.setup.ts",
98
+ "jest-webgl-canvas-mock"
92
99
  ]
93
100
  },
94
101
  "scripts": {
@@ -96,6 +103,9 @@
96
103
  "test": "jest",
97
104
  "test:cov": "jest --coverage",
98
105
  "test:debug": "cross-env DEBUG_MODE=1 jest",
106
+ "e2e:case": "vite serve ./e2e/.dev --config ./e2e/.dev/vite.config.js",
107
+ "e2e": "cypress run --browser chrome --headless",
108
+ "e2e:debug": "cypress open",
99
109
  "dev": "rollup -cw",
100
110
  "build": "npm run b:types && cross-env BUILD_TYPE=ALL rollup -c",
101
111
  "build:watch": "npm run b:types && cross-env BUILD_TYPE=ALL rollup -c --watch",
@@ -0,0 +1,2 @@
1
+ declare const _default: Cypress.ConfigOptions<any>;
2
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { Camera, Engine } from "@galacean/engine-core";
2
+ export declare const updateForE2E: (engine: any, deltaTime?: number, loopTime?: number) => void;
3
+ export declare function initScreenshot(engine: Engine, camera: Camera, width?: number, height?: number, flipY?: boolean, isPNG?: boolean, jpgQuality?: number): void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ export declare const E2E_CONFIG: {
2
+ Spine: {
3
+ 'spine-boy': {
4
+ category: string;
5
+ caseFileName: string;
6
+ threshold: number;
7
+ };
8
+ raptor: {
9
+ category: string;
10
+ caseFileName: string;
11
+ threshold: number;
12
+ };
13
+ 'mix-and-match': {
14
+ category: string;
15
+ caseFileName: string;
16
+ threshold: number;
17
+ };
18
+ };
19
+ };
@@ -0,0 +1,8 @@
1
+ declare global {
2
+ namespace Cypress {
3
+ interface Chainable {
4
+ screenshotWithThreshold(category: string, name: string, threshold?: number): Chainable<Element>;
5
+ }
6
+ }
7
+ }
8
+ export {};
@@ -0,0 +1 @@
1
+ import "./commands";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { Entity, MeshRenderer, Camera } from '@galacean/engine';
2
+ export default class BoundingBoxLine extends MeshRenderer {
3
+ private attachedEntity;
4
+ private renderers;
5
+ private boundingBox;
6
+ constructor(entity: Entity);
7
+ updateBoundingBox(): void;
8
+ attachToEntity(entity: Entity): void;
9
+ private updateVertices;
10
+ _render(camera: Camera): void;
11
+ }
@@ -0,0 +1,5 @@
1
+ declare class MockImage {
2
+ onload: () => void;
3
+ onerror: () => void;
4
+ set src(_url: string);
5
+ }
@@ -0,0 +1,213 @@
1
+ import { Skeleton, SkeletonData, AnimationState, AnimationStateData } from "@esotericsoftware/spine-core";
2
+ import { Buffer, Renderer, Entity, Material, Engine, BoundingBox, Primitive, SubPrimitive } from "@galacean/engine";
3
+ import { SkeletonDataResource } from "./loader/SkeletonDataResource";
4
+ export declare class SpineAnimationRenderer extends Renderer {
5
+ private static _defaultMaterial;
6
+ private static _spineGenerator;
7
+ private static _positionVertexElement;
8
+ private static _colorVertexElement;
9
+ private static _uvVertexElement;
10
+ /** @internal */
11
+ static _materialCache: Map<string, Material>;
12
+ /** @internal */
13
+ static _animationDataCache: Map<SkeletonData, AnimationStateData>;
14
+ /** @internal */
15
+ static _getDefaultMaterial(engine: Engine): Material;
16
+ /** Render setting for spine rendering. */
17
+ setting: SpineRenderSetting;
18
+ /**
19
+ * Default state for spine animation.
20
+ * Contains the default animation name to be played, whether this animation should loop,
21
+ * the default skin name, and the default scale of the skeleton.
22
+ */
23
+ defaultState: DefaultState;
24
+ /** @internal */
25
+ _primitive: Primitive;
26
+ /** @internal */
27
+ _subPrimitives: SubPrimitive[];
28
+ /** @internal */
29
+ _indexBuffer: Buffer;
30
+ /** @internal */
31
+ _vertexBuffer: Buffer;
32
+ /** @internal */
33
+ _vertices: Float32Array;
34
+ /** @internal */
35
+ _indices: Uint16Array;
36
+ /** @internal */
37
+ _needResizeBuffer: boolean;
38
+ /** @internal */
39
+ _vertexCount: number;
40
+ /** @internal */
41
+ _resource: SkeletonDataResource;
42
+ private _skeleton;
43
+ private _state;
44
+ /**
45
+ * Setting `skeletonData` initializes a new Spine animation with the provided data.
46
+ * This property allows you to switch between different animations at runtime.
47
+ */
48
+ set resource(value: SkeletonDataResource);
49
+ /**
50
+ * Provides access to `AnimationState` which controls animation playback on a skeleton.
51
+ * You can use its API to manage, blend, and transition between multiple simultaneous animations effectively.
52
+ */
53
+ get state(): AnimationState;
54
+ /**
55
+ * Provides access to `Skeleton`, which defines the structure of a Spine model.
56
+ * Through its API, users can manipulate bone positions, rotations, scaling
57
+ * and change spine attachment to customize character appearances dynamically during runtime.
58
+ */
59
+ get skeleton(): Skeleton;
60
+ constructor(entity: Entity);
61
+ /**
62
+ * Separate slot by slot name. This will add a new sub primitive, and new materials.
63
+ */
64
+ addSeparateSlot(slotName: string): void;
65
+ /**
66
+ * @internal
67
+ */
68
+ _onEnable(): void;
69
+ /**
70
+ * @internal
71
+ */
72
+ update(delta: number): void;
73
+ /**
74
+ * @internal
75
+ */
76
+ _render(context: any): void;
77
+ /**
78
+ * @internal
79
+ */
80
+ _updateBounds(worldBounds: BoundingBox): void;
81
+ /**
82
+ * @internal
83
+ */
84
+ _calculateGeneratorBounds(worldBounds: BoundingBox): void;
85
+ /**
86
+ * @internal
87
+ */
88
+ _cloneTo(target: SpineAnimationRenderer): void;
89
+ /**
90
+ * @internal
91
+ */
92
+ _onDestroy(): void;
93
+ /**
94
+ * @internal
95
+ */
96
+ _createBuffer(vertexCount: number): void;
97
+ /**
98
+ * @internal
99
+ */
100
+ _addSubPrimitive(subPrimitive: SubPrimitive): void;
101
+ /**
102
+ * @internal
103
+ */
104
+ _clearSubPrimitives(): void;
105
+ /**
106
+ * @internal
107
+ */
108
+ _isContainDirtyFlag(type: number): boolean;
109
+ /**
110
+ * @internal
111
+ */
112
+ _setDirtyFlagFalse(type: number): void;
113
+ /**
114
+ * @internal
115
+ */
116
+ _onWorldVolumeChanged(): void;
117
+ private _onAnimationStart;
118
+ private _onAnimationComplete;
119
+ private _clearMaterialCache;
120
+ private _initializeDefaultState;
121
+ }
122
+ /**
123
+ * @internal
124
+ */
125
+ export declare enum SpineAnimationUpdateFlags {
126
+ /** On World Transform Changed */
127
+ TransformVolume = 1,
128
+ /** On Animation start play */
129
+ AnimationVolume = 2,
130
+ /** On skeleton data asset changed */
131
+ InitialVolume = 4
132
+ }
133
+ /**
134
+ * @internal
135
+ */
136
+ export declare enum RendererUpdateFlags {
137
+ /** Include world position and world bounds. */
138
+ WorldVolume = 1
139
+ }
140
+ /**
141
+ * Render setting for spine rendering.
142
+ */
143
+ export declare class SpineRenderSetting {
144
+ /**
145
+ * The spacing between z layers.
146
+ */
147
+ zSpacing: number;
148
+ /**
149
+ * Whether to use clipping.
150
+ */
151
+ useClipping: boolean;
152
+ /**
153
+ * Creates an instance of SpineRenderSetting.
154
+ * @param {number} [zSpacing=0.01] - The spacing between z layers.
155
+ * @param {boolean} [useClipping=true] - Whether to use clipping.
156
+ */
157
+ constructor(
158
+ /**
159
+ * The spacing between z layers.
160
+ */
161
+ zSpacing?: number,
162
+ /**
163
+ * Whether to use clipping.
164
+ */
165
+ useClipping?: boolean);
166
+ }
167
+ /**
168
+ * Default state for spine animation.
169
+ * Contains the default animation name to be played, whether this animation should loop,
170
+ * the default skin name, and the default scale of the skeleton.
171
+ */
172
+ export declare class DefaultState {
173
+ /**
174
+ * The default scale of the animation.
175
+ */
176
+ scale: number;
177
+ /**
178
+ * Whether the default animation should loop.
179
+ */
180
+ loop: boolean;
181
+ /**
182
+ * The name of the default animation.
183
+ */
184
+ animationName: string | null;
185
+ /**
186
+ * The name of the default skin.
187
+ */
188
+ skinName: string;
189
+ /**
190
+ * Creates an instance of DefaultState.
191
+ * @param {number} [scale=1] - The default scale of the animation.
192
+ * @param {boolean} [loop=false] - Whether the default animation should loop.
193
+ * @param {string | null} [animationName=null] - The name of the default animation.
194
+ * @param {string} [skinName="default"] - The name of the default skin.
195
+ */
196
+ constructor(
197
+ /**
198
+ * The default scale of the animation.
199
+ */
200
+ scale?: number,
201
+ /**
202
+ * Whether the default animation should loop.
203
+ */
204
+ loop?: boolean,
205
+ /**
206
+ * The name of the default animation.
207
+ */
208
+ animationName?: string | null,
209
+ /**
210
+ * The name of the default skin.
211
+ */
212
+ skinName?: string);
213
+ }
@@ -0,0 +1,37 @@
1
+ import { Texture2D, SubPrimitive, BoundingBox } from "@galacean/engine";
2
+ import { Skeleton, Color, BlendMode, SkeletonData } from "@esotericsoftware/spine-core";
3
+ import { SpineAnimationRenderer } from "./SpineAnimationRenderer";
4
+ import { AdaptiveTexture } from "./loader/LoaderUtils";
5
+ import { ReturnablePool } from "./util/ReturnablePool";
6
+ import { ClearablePool } from "./util/ClearablePool";
7
+ declare class SubRenderItem {
8
+ subPrimitive: SubPrimitive;
9
+ blendMode: BlendMode;
10
+ texture: any;
11
+ slotName?: string;
12
+ }
13
+ export declare class SpineGenerator {
14
+ static QUAD_TRIANGLES: number[];
15
+ static VERTEX_SIZE: number;
16
+ static VERTEX_STRIDE: number;
17
+ static tempDark: Color;
18
+ static tempColor: Color;
19
+ static tempVerts: any[];
20
+ static tempBlendMode: BlendMode | null;
21
+ static tempTexture: AdaptiveTexture | null;
22
+ static subPrimitivePool: ReturnablePool<SubPrimitive>;
23
+ static subRenderItemPool: ClearablePool<SubRenderItem>;
24
+ static bounds: BoundingBox;
25
+ private _clipper;
26
+ private _subRenderItems;
27
+ private _separateSlots;
28
+ private _separateSlotTextureMap;
29
+ getMaxVertexCount(skeletonData: SkeletonData): number;
30
+ buildPrimitive(skeleton: Skeleton, renderer: SpineAnimationRenderer): void;
31
+ addSeparateSlot(slotName: string): void;
32
+ addSeparateSlotTexture(slotName: string, texture: Texture2D): void;
33
+ private _createMaterialForTexture;
34
+ private _expandByPoint;
35
+ private _getSkinVertexCount;
36
+ }
37
+ export {};
@@ -0,0 +1,6 @@
1
+ import { Engine, Material } from "@galacean/engine";
2
+ export declare class SpineMaterial extends Material {
3
+ private static _spineVS;
4
+ private static _spineFS;
5
+ constructor(engine: Engine);
6
+ }
@@ -0,0 +1,7 @@
1
+ import "./loader/SpineLoader";
2
+ import "./loader/EditorSpineAtlasLoader";
3
+ export { SpineAnimationRenderer } from "./SpineAnimationRenderer";
4
+ export { SkeletonDataResource } from "./loader/SkeletonDataResource";
5
+ export { createTextureAtlas } from "./loader/LoaderUtils";
6
+ export * from "@esotericsoftware/spine-core";
7
+ export declare const version = "__buildVersion";
@@ -0,0 +1,6 @@
1
+ import { AssetPromise, Loader, ResourceManager, LoadItem } from "@galacean/engine";
2
+ import { TextureAtlas } from "@esotericsoftware/spine-core";
3
+ declare class EditorSpineAtlasLoader extends Loader<TextureAtlas> {
4
+ load(item: LoadItem, resourceManager: ResourceManager): AssetPromise<TextureAtlas>;
5
+ }
6
+ export { EditorSpineAtlasLoader };
@@ -0,0 +1,18 @@
1
+ import { AssetPromise, Engine, Texture2D } from "@galacean/engine";
2
+ import { TextureAtlas, SkeletonData, Texture, TextureFilter, TextureWrap } from "@esotericsoftware/spine-core";
3
+ export declare function createSkeletonData(textureAtlas: TextureAtlas, skeletonTextData: string | ArrayBuffer, skeletonFileType: 'json' | 'skel'): SkeletonData;
4
+ export declare function loadTexturesByPath(imagePaths: string[], imageExtensions: string[], engine: Engine): Promise<Texture2D[]>;
5
+ export declare function loadTextureAtlas(atlasPath: string, engine: Engine): Promise<TextureAtlas>;
6
+ export declare function createTextureAtlas(atlasText: string, textures: Texture2D[]): TextureAtlas;
7
+ export declare function loadTexture(url: string, engine: Engine, imageLoaderType?: string): AssetPromise<Texture2D>;
8
+ export declare function createAdaptiveTexture(texture: Texture2D): AdaptiveTexture;
9
+ export declare function getBaseUrl(url: string): string;
10
+ export declare class AdaptiveTexture extends Texture {
11
+ texture: Texture2D;
12
+ constructor(image: HTMLImageElement | ImageBitmap, texture: Texture2D);
13
+ getImage(): any;
14
+ setFilters(minFilter: TextureFilter, magFilter: TextureFilter): void;
15
+ setWraps(uWrap: TextureWrap, vWrap: TextureWrap): void;
16
+ dispose(): void;
17
+ private _convertWrapMode;
18
+ }
@@ -0,0 +1,12 @@
1
+ import { SkeletonData } from "@esotericsoftware/spine-core";
2
+ import { Engine, ReferResource, Texture2D } from "@galacean/engine";
3
+ export declare class SkeletonDataResource extends ReferResource {
4
+ readonly textures: Texture2D[];
5
+ private _skeletonData;
6
+ get skeletonData(): SkeletonData;
7
+ constructor(engine: Engine, skeletonData: SkeletonData);
8
+ protected _onDestroy(): void;
9
+ private _disassociationSuperResource;
10
+ private _associationTextureInSkeletonData;
11
+ private _clearAttachmentTextures;
12
+ }
@@ -0,0 +1,29 @@
1
+ import { AssetPromise, Loader, LoadItem, ResourceManager } from "@galacean/engine";
2
+ import { SkeletonDataResource } from "./SkeletonDataResource";
3
+ export type SpineAssetBundle = {
4
+ skeletonPath: string;
5
+ skeletonExtension: string;
6
+ skeletonTextData?: string | ArrayBuffer;
7
+ atlasPath: string;
8
+ imagePaths: string[];
9
+ imageExtensions: string[];
10
+ };
11
+ type SpineLoaderParams = {
12
+ fileExtensions?: string | string[];
13
+ };
14
+ type SpineLoadItem = LoadItem & {
15
+ params?: SpineLoaderParams;
16
+ };
17
+ export declare class SpineLoader extends Loader<SkeletonDataResource> {
18
+ static imageExtensions: string[];
19
+ static skeletonExtensions: string[];
20
+ static parseAndAssignSpineAsset(url: string, fileExtension: string | null, bundle: SpineAssetBundle): void;
21
+ static deriveAndAssignSpineAsset(url: string, fileExtension: string | null, bundle: SpineAssetBundle): void;
22
+ static verifyFileExtensions(fileExtensions: string | string[], expectArray: boolean): string | string[] | null;
23
+ static getUrlExtension(url: string, fileExtension: string): string | null;
24
+ load(item: SpineLoadItem, resourceManager: ResourceManager): AssetPromise<SkeletonDataResource>;
25
+ private _handleEditorAsset;
26
+ private _handleOriginAsset;
27
+ private _determineSkeletonDataType;
28
+ }
29
+ export {};
@@ -0,0 +1,4 @@
1
+ import { BlendMode } from "@esotericsoftware/spine-core";
2
+ import { Material } from "@galacean/engine";
3
+ export declare function setBlendMode(material: Material, blendMode: BlendMode): void;
4
+ export declare function getBlendMode(material: Material): BlendMode;
@@ -0,0 +1,10 @@
1
+ export declare class BufferReader {
2
+ data: Uint8Array;
3
+ private _dataView;
4
+ private _position;
5
+ constructor(data: Uint8Array, byteOffset?: number, byteLength?: number);
6
+ nextUint16(): number;
7
+ nextStr(): string;
8
+ nextImageData(): Uint8Array;
9
+ private decodeText;
10
+ }
@@ -0,0 +1,8 @@
1
+ export declare class ClearablePool<T> {
2
+ private _type;
3
+ private _elements;
4
+ private _usedElementCount;
5
+ constructor(type: new () => T);
6
+ get(): T;
7
+ clear(): void;
8
+ }
@@ -0,0 +1,8 @@
1
+ export declare class ReturnablePool<T> {
2
+ private _type;
3
+ private _elements;
4
+ private _lastElementIndex;
5
+ constructor(type: new () => T, initializeCount?: number);
6
+ get(): T;
7
+ return(element: T): void;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1,3 @@
1
+ import { WebGLEngine } from "@galacean/engine";
2
+ export declare function createEngine(): Promise<WebGLEngine>;
3
+ export declare function mockSkeletonDataResource(): void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};