@autumnsgrove/gossamer 0.0.1 → 0.1.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/dist/animation.d.ts +80 -0
- package/dist/animation.d.ts.map +1 -0
- package/dist/characters.d.ts +49 -0
- package/dist/characters.d.ts.map +1 -0
- package/dist/colors.d.ts +312 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/index.d.ts +39 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1826 -2
- package/dist/index.js.map +1 -1
- package/dist/patterns.d.ts +217 -0
- package/dist/patterns.d.ts.map +1 -0
- package/dist/renderer.d.ts +140 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/style.css +124 -0
- package/dist/svelte/GossamerBorder.svelte.d.ts +1 -0
- package/dist/svelte/GossamerClouds.svelte.d.ts +1 -0
- package/dist/svelte/GossamerImage.svelte.d.ts +1 -0
- package/dist/svelte/GossamerOverlay.svelte.d.ts +1 -0
- package/dist/svelte/GossamerText.svelte.d.ts +1 -0
- package/dist/svelte/index.d.ts +20 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +3648 -0
- package/dist/svelte/index.js.map +1 -0
- package/dist/svelte/presets.d.ts +38 -0
- package/dist/svelte/presets.d.ts.map +1 -0
- package/dist/utils/canvas.d.ts +73 -0
- package/dist/utils/canvas.d.ts.map +1 -0
- package/dist/utils/image.d.ts +74 -0
- package/dist/utils/image.d.ts.map +1 -0
- package/dist/utils/performance.d.ts +86 -0
- package/dist/utils/performance.d.ts.map +1 -0
- package/package.json +34 -7
- package/src/animation.test.ts +254 -0
- package/src/animation.ts +243 -0
- package/src/characters.test.ts +148 -0
- package/src/characters.ts +219 -0
- package/src/colors.ts +234 -0
- package/src/index.test.ts +115 -0
- package/src/index.ts +164 -11
- package/src/patterns.test.ts +273 -0
- package/src/patterns.ts +760 -0
- package/src/renderer.ts +470 -0
- package/src/svelte/GossamerBorder.svelte +326 -0
- package/src/svelte/GossamerClouds.svelte +269 -0
- package/src/svelte/GossamerImage.svelte +266 -0
- package/src/svelte/GossamerOverlay.svelte +232 -0
- package/src/svelte/GossamerText.svelte +239 -0
- package/src/svelte/index.ts +75 -0
- package/src/svelte/presets.ts +174 -0
- package/src/utils/canvas.ts +210 -0
- package/src/utils/image.ts +275 -0
- package/src/utils/performance.ts +282 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossamer Core Renderer
|
|
3
|
+
*
|
|
4
|
+
* Canvas-based ASCII rendering engine. Converts image data to ASCII characters
|
|
5
|
+
* by mapping brightness values to a character set.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Configuration for the Gossamer renderer
|
|
9
|
+
*/
|
|
10
|
+
export interface RenderConfig {
|
|
11
|
+
/** Canvas element to render to */
|
|
12
|
+
canvas: HTMLCanvasElement;
|
|
13
|
+
/** Character set ordered from light to dark */
|
|
14
|
+
characters: string;
|
|
15
|
+
/** Width of each character cell in pixels */
|
|
16
|
+
cellWidth: number;
|
|
17
|
+
/** Height of each character cell in pixels */
|
|
18
|
+
cellHeight: number;
|
|
19
|
+
/** Color for rendering characters */
|
|
20
|
+
color: string;
|
|
21
|
+
/** Background color (empty string for transparent) */
|
|
22
|
+
backgroundColor: string;
|
|
23
|
+
/** Font family */
|
|
24
|
+
fontFamily: string;
|
|
25
|
+
/** Custom brightness calculation function */
|
|
26
|
+
brightnessFunction: (r: number, g: number, b: number) => number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Core ASCII renderer class
|
|
30
|
+
*
|
|
31
|
+
* Handles all canvas rendering operations for ASCII effects.
|
|
32
|
+
* Supports both static rendering and animation loops.
|
|
33
|
+
*/
|
|
34
|
+
export declare class GossamerRenderer {
|
|
35
|
+
private ctx;
|
|
36
|
+
private config;
|
|
37
|
+
private animationId;
|
|
38
|
+
private lastFrameTime;
|
|
39
|
+
private isRunning;
|
|
40
|
+
private charAtlas;
|
|
41
|
+
private atlasCharacters;
|
|
42
|
+
constructor(canvas: HTMLCanvasElement, config?: Partial<Omit<RenderConfig, 'canvas'>>);
|
|
43
|
+
/**
|
|
44
|
+
* Build character texture atlas for fast rendering
|
|
45
|
+
* Pre-renders all characters to an offscreen canvas, then uses drawImage
|
|
46
|
+
* instead of fillText for 5-10x faster rendering
|
|
47
|
+
*/
|
|
48
|
+
private buildCharacterAtlas;
|
|
49
|
+
/**
|
|
50
|
+
* Set up the canvas with optimal rendering settings
|
|
51
|
+
*/
|
|
52
|
+
private setupCanvas;
|
|
53
|
+
/**
|
|
54
|
+
* Update the renderer configuration
|
|
55
|
+
*/
|
|
56
|
+
updateConfig(config: Partial<Omit<RenderConfig, 'canvas'>>): void;
|
|
57
|
+
/**
|
|
58
|
+
* Resize the canvas to match new dimensions
|
|
59
|
+
*/
|
|
60
|
+
resize(width: number, height: number): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get the current canvas dimensions
|
|
63
|
+
*/
|
|
64
|
+
getDimensions(): {
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Calculate the number of cells that fit in the canvas
|
|
70
|
+
*/
|
|
71
|
+
getCellCount(): {
|
|
72
|
+
cols: number;
|
|
73
|
+
rows: number;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Clear the canvas
|
|
77
|
+
*/
|
|
78
|
+
clear(): void;
|
|
79
|
+
/**
|
|
80
|
+
* Render a single frame from image data
|
|
81
|
+
*/
|
|
82
|
+
renderFrame(imageData: ImageData): void;
|
|
83
|
+
/**
|
|
84
|
+
* Render ASCII from a brightness grid (for pattern-based rendering)
|
|
85
|
+
*/
|
|
86
|
+
renderFromBrightnessGrid(grid: number[][]): void;
|
|
87
|
+
/**
|
|
88
|
+
* Render ASCII with per-cell colors (for colored image rendering)
|
|
89
|
+
*/
|
|
90
|
+
renderWithColors(data: Array<{
|
|
91
|
+
char: string;
|
|
92
|
+
color: string;
|
|
93
|
+
x: number;
|
|
94
|
+
y: number;
|
|
95
|
+
}>): void;
|
|
96
|
+
/**
|
|
97
|
+
* PERFORMANCE: Render from BrightnessBuffer using texture atlas
|
|
98
|
+
*
|
|
99
|
+
* Uses pre-rendered character sprites instead of fillText calls.
|
|
100
|
+
* 5-10x faster than renderFromBrightnessGrid for large canvases.
|
|
101
|
+
*
|
|
102
|
+
* @param buffer - BrightnessBuffer from fillBrightnessBuffer
|
|
103
|
+
*/
|
|
104
|
+
renderFromBuffer(buffer: {
|
|
105
|
+
data: Uint8Array;
|
|
106
|
+
cols: number;
|
|
107
|
+
rows: number;
|
|
108
|
+
}): void;
|
|
109
|
+
/**
|
|
110
|
+
* PERFORMANCE: Render brightness grid using atlas (legacy grid format)
|
|
111
|
+
*
|
|
112
|
+
* @param grid - 2D array of brightness values
|
|
113
|
+
*/
|
|
114
|
+
renderGridFast(grid: number[][]): void;
|
|
115
|
+
/**
|
|
116
|
+
* Calculate average brightness for a cell region
|
|
117
|
+
*/
|
|
118
|
+
private getCellBrightness;
|
|
119
|
+
/**
|
|
120
|
+
* Start an animation loop with FPS limiting
|
|
121
|
+
*/
|
|
122
|
+
startAnimation(updateFn: (time: number, deltaTime: number) => ImageData | number[][], fps?: number): void;
|
|
123
|
+
/**
|
|
124
|
+
* Stop the animation loop
|
|
125
|
+
*/
|
|
126
|
+
stopAnimation(): void;
|
|
127
|
+
/**
|
|
128
|
+
* Check if animation is currently running
|
|
129
|
+
*/
|
|
130
|
+
isAnimating(): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Pause animation (can be resumed)
|
|
133
|
+
*/
|
|
134
|
+
pause(): void;
|
|
135
|
+
/**
|
|
136
|
+
* Clean up and destroy the renderer
|
|
137
|
+
*/
|
|
138
|
+
destroy(): void;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,kBAAkB,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACjE;AAeD;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,SAAS,CAAkB;IAGnC,OAAO,CAAC,SAAS,CAAoD;IACrE,OAAO,CAAC,eAAe,CAAc;gBAEzB,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAM;IAiBzF;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IA6C3B;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,GAAG,IAAI;IAiBjE;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAO3C;;OAEG;IACH,aAAa,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAOlD;;OAEG;IACH,YAAY,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAU9C;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAoBvC;;OAEG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAmBhD;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI;IAW1F;;;;;;;OAOG;IACH,gBAAgB,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAgDhF;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI;IAiCtC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;OAEG;IACH,cAAc,CACZ,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,GAAG,MAAM,EAAE,EAAE,EACrE,GAAG,GAAE,MAAW,GACf,IAAI;IAgCP;;OAEG;IACH,aAAa,IAAI,IAAI;IAQrB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb;;OAEG;IACH,OAAO,IAAI,IAAI;CAGhB"}
|
package/dist/style.css
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
|
|
2
|
+
.gossamer-clouds.svelte-sqd1fq {
|
|
3
|
+
position: absolute;
|
|
4
|
+
inset: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
overflow: hidden;
|
|
8
|
+
pointer-events: none;
|
|
9
|
+
z-index: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.gossamer-canvas.svelte-sqd1fq {
|
|
13
|
+
display: block;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.gossamer-image.svelte-1v5c3d1 {
|
|
19
|
+
position: relative;
|
|
20
|
+
display: inline-block;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.gossamer-image.hoverable.svelte-1v5c3d1 {
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.gossamer-canvas.svelte-1v5c3d1 {
|
|
29
|
+
display: block;
|
|
30
|
+
opacity: 1;
|
|
31
|
+
transition-property: opacity;
|
|
32
|
+
transition-timing-function: ease-in-out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.gossamer-canvas.hidden.svelte-1v5c3d1 {
|
|
36
|
+
opacity: 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.gossamer-original.svelte-1v5c3d1 {
|
|
40
|
+
position: absolute;
|
|
41
|
+
inset: 0;
|
|
42
|
+
width: 100%;
|
|
43
|
+
height: 100%;
|
|
44
|
+
object-fit: cover;
|
|
45
|
+
opacity: 0;
|
|
46
|
+
transition-property: opacity;
|
|
47
|
+
transition-timing-function: ease-in-out;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.gossamer-original.visible.svelte-1v5c3d1 {
|
|
51
|
+
opacity: 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.gossamer-image-loading.svelte-1v5c3d1,
|
|
55
|
+
.gossamer-image-error.svelte-1v5c3d1 {
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
justify-content: center;
|
|
59
|
+
width: 100%;
|
|
60
|
+
height: 100%;
|
|
61
|
+
min-height: 100px;
|
|
62
|
+
color: currentColor;
|
|
63
|
+
opacity: 0.5;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.gossamer-image-error.svelte-1v5c3d1 {
|
|
67
|
+
color: #ef4444;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.gossamer-text.svelte-fd3qw5 {
|
|
71
|
+
position: relative;
|
|
72
|
+
display: inline-block;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.gossamer-canvas.svelte-fd3qw5 {
|
|
76
|
+
display: block;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.gossamer-text-sr.svelte-fd3qw5 {
|
|
80
|
+
position: absolute;
|
|
81
|
+
width: 1px;
|
|
82
|
+
height: 1px;
|
|
83
|
+
padding: 0;
|
|
84
|
+
margin: -1px;
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
clip: rect(0, 0, 0, 0);
|
|
87
|
+
white-space: nowrap;
|
|
88
|
+
border: 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.gossamer-overlay.svelte-1oexqwo {
|
|
92
|
+
position: absolute;
|
|
93
|
+
inset: 0;
|
|
94
|
+
width: 100%;
|
|
95
|
+
height: 100%;
|
|
96
|
+
overflow: hidden;
|
|
97
|
+
pointer-events: none;
|
|
98
|
+
z-index: 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.gossamer-canvas.svelte-1oexqwo {
|
|
102
|
+
display: block;
|
|
103
|
+
width: 100%;
|
|
104
|
+
height: 100%;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.gossamer-border.svelte-qe7ze6 {
|
|
108
|
+
position: relative;
|
|
109
|
+
display: block;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.gossamer-border-canvas.svelte-qe7ze6 {
|
|
113
|
+
position: absolute;
|
|
114
|
+
inset: 0;
|
|
115
|
+
width: 100%;
|
|
116
|
+
height: 100%;
|
|
117
|
+
pointer-events: none;
|
|
118
|
+
z-index: 0;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.gossamer-border-content.svelte-qe7ze6 {
|
|
122
|
+
position: relative;
|
|
123
|
+
z-index: 1;
|
|
124
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SvelteComponentTyped as default } from 'svelte';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gossamer - Svelte 5 Components
|
|
3
|
+
*
|
|
4
|
+
* ASCII visual effects components for Svelte applications.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export { default as GossamerClouds } from './GossamerClouds.svelte';
|
|
9
|
+
export { default as GossamerImage } from './GossamerImage.svelte';
|
|
10
|
+
export { default as GossamerText } from './GossamerText.svelte';
|
|
11
|
+
export { default as GossamerOverlay } from './GossamerOverlay.svelte';
|
|
12
|
+
export { default as GossamerBorder } from './GossamerBorder.svelte';
|
|
13
|
+
export type { GossamerCloudsProps } from './GossamerClouds.svelte';
|
|
14
|
+
export type { GossamerImageProps } from './GossamerImage.svelte';
|
|
15
|
+
export type { GossamerTextProps } from './GossamerText.svelte';
|
|
16
|
+
export type { GossamerOverlayProps, BlendMode } from './GossamerOverlay.svelte';
|
|
17
|
+
export type { GossamerBorderProps, BorderStyle } from './GossamerBorder.svelte';
|
|
18
|
+
export { PRESETS, grovePresets, seasonalPresets, ambientPresets, getPreset, getPresetNames, getPresetsByCategory, } from './presets';
|
|
19
|
+
export { type GossamerConfig, type PresetConfig, type PatternConfig, type PatternType, type CharacterSet, DEFAULT_CHARACTERS, DEFAULT_CONFIG, CHARACTER_SETS, calculateBrightness, brightnessToChar, getCharacterSet, getCharacters, getCharacterSetNames, invertCharacters, prefersReducedMotion, VERSION, } from '../index';
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAMpE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAChF,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMhF,OAAO,EACL,OAAO,EACP,YAAY,EACZ,eAAe,EACf,cAAc,EACd,SAAS,EACT,cAAc,EACd,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAMnB,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EAGjB,kBAAkB,EAClB,cAAc,EACd,cAAc,EAGd,mBAAmB,EACnB,gBAAgB,EAGhB,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAGhB,oBAAoB,EAGpB,OAAO,GACR,MAAM,UAAU,CAAC"}
|