@digdir/designsystemet 1.12.0 → 1.13.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 (43) hide show
  1. package/dist/bin/config.d.ts +4 -4
  2. package/dist/bin/config.d.ts.map +1 -1
  3. package/dist/bin/config.js +133 -28
  4. package/dist/bin/designsystemet.d.ts.map +1 -1
  5. package/dist/bin/designsystemet.js +208 -149
  6. package/dist/src/config.d.ts +2 -2
  7. package/dist/src/config.d.ts.map +1 -1
  8. package/dist/src/config.js +4 -4
  9. package/dist/src/index.js +5 -5
  10. package/dist/src/migrations/beta-to-v1.js +122 -16
  11. package/dist/src/migrations/codemods/css/run.d.ts.map +1 -1
  12. package/dist/src/migrations/codemods/css/run.js +122 -16
  13. package/dist/src/migrations/color-rename-next49.js +122 -16
  14. package/dist/src/migrations/index.js +122 -16
  15. package/dist/src/scripts/update-preview-tokens.d.ts.map +1 -1
  16. package/dist/src/scripts/update-preview-tokens.js +122 -45
  17. package/dist/src/tokens/build.d.ts +2 -1
  18. package/dist/src/tokens/build.d.ts.map +1 -1
  19. package/dist/src/tokens/build.js +128 -62
  20. package/dist/src/tokens/create/files.d.ts +10 -0
  21. package/dist/src/tokens/create/files.d.ts.map +1 -0
  22. package/dist/src/tokens/create/{write.js → files.js} +143 -61
  23. package/dist/src/tokens/create/generators/$designsystemet.js +5 -5
  24. package/dist/src/tokens/format.js +5 -5
  25. package/dist/src/tokens/generate-config.d.ts +0 -1
  26. package/dist/src/tokens/generate-config.d.ts.map +1 -1
  27. package/dist/src/tokens/generate-config.js +145 -26
  28. package/dist/src/tokens/index.js +5 -5
  29. package/dist/src/tokens/process/output/declarations.js +5 -5
  30. package/dist/src/tokens/process/output/theme.js +5 -5
  31. package/dist/src/tokens/process/platform.d.ts +0 -4
  32. package/dist/src/tokens/process/platform.d.ts.map +1 -1
  33. package/dist/src/tokens/types.d.ts +2 -0
  34. package/dist/src/tokens/types.d.ts.map +1 -1
  35. package/dist/src/utils/filesystem.d.ts +40 -0
  36. package/dist/src/utils/filesystem.d.ts.map +1 -0
  37. package/dist/src/utils/filesystem.js +127 -0
  38. package/package.json +6 -6
  39. package/dist/src/tokens/create/write.d.ts +0 -12
  40. package/dist/src/tokens/create/write.d.ts.map +0 -1
  41. package/dist/src/utils.d.ts +0 -18
  42. package/dist/src/utils.d.ts.map +0 -1
  43. package/dist/src/utils.js +0 -70
@@ -1,5 +1,4 @@
1
1
  // src/scripts/update-preview-tokens.ts
2
- import path from "path";
3
2
  import pc4 from "picocolors";
4
3
 
5
4
  // ../../designsystemet.config.json
@@ -3143,54 +3142,133 @@ async function processPlatform(options) {
3143
3142
  return processedBuilds;
3144
3143
  }
3145
3144
 
3146
- // src/utils.ts
3145
+ // src/utils/filesystem.ts
3147
3146
  import fs from "fs/promises";
3147
+ import path from "path";
3148
3148
  import pc3 from "picocolors";
3149
- var mkdir = async (dir, dry) => {
3150
- if (dry) {
3151
- console.log(`${pc3.blue("mkdir")} ${dir}`);
3152
- return Promise.resolve();
3153
- }
3154
- const exists = await fs.access(dir, fs.constants.F_OK).then(() => true).catch(() => false);
3155
- if (exists) {
3156
- return Promise.resolve();
3157
- }
3158
- return fs.mkdir(dir, { recursive: true });
3159
- };
3160
- var writeFile = async (path2, data, dry) => {
3161
- if (dry) {
3162
- console.log(`${pc3.blue("writeFile")} ${path2}`);
3163
- return Promise.resolve();
3164
- }
3165
- return fs.writeFile(path2, data, { encoding: "utf-8" }).catch((error) => {
3166
- console.error(pc3.red(`Error writing file: ${path2}`));
3167
- console.error(pc3.red(error));
3168
- throw error;
3169
- });
3170
- };
3171
- var cleanDir = async (dir, dry) => {
3172
- if (dry) {
3173
- console.log(`${pc3.blue("cleanDir")} ${dir}`);
3174
- return Promise.resolve();
3149
+ var FileSystem = class {
3150
+ isInitialized = false;
3151
+ dry = false;
3152
+ verbose = false;
3153
+ /** Default working directory is where the process was started */
3154
+ workingDir = process.cwd();
3155
+ outDir = this.workingDir;
3156
+ /** Initialize the file system */
3157
+ init({ dry, outdir, verbose }) {
3158
+ if (this.isInitialized) {
3159
+ console.warn(pc3.yellow("FileSystem is already initialized. Ignoring subsequent init call."));
3160
+ return;
3161
+ }
3162
+ if (dry) {
3163
+ console.log(pc3.blue("Initializing FileSystem in dry-run mode. No files will be written."));
3164
+ }
3165
+ this.dry = dry ?? false;
3166
+ this.verbose = verbose ?? false;
3167
+ this.outDir = outdir ? path.isAbsolute(outdir) ? outdir : path.join(this.workingDir, outdir) : this.workingDir;
3168
+ if (this.verbose) {
3169
+ console.log(
3170
+ `FileSystem initialized with workingDir: ${pc3.green(this.workingDir)}, outDir: ${pc3.green(this.outDir)}`
3171
+ );
3172
+ }
3173
+ this.isInitialized = true;
3175
3174
  }
3176
- console.log(`
3175
+ /**
3176
+ * Creates a directory if it does not already exist.
3177
+ *
3178
+ * @param dir - The path of the directory to create.
3179
+ *
3180
+ * @returns A promise that resolves when the operation is complete.
3181
+ * If the directory already exists or `dry` is `true`, the promise resolves immediately.
3182
+ */
3183
+ mkdir = async (dir) => {
3184
+ if (this.dry) {
3185
+ console.log(`${pc3.blue("mkdir")} ${dir}`);
3186
+ return Promise.resolve();
3187
+ }
3188
+ const exists = await fs.access(dir, fs.constants.F_OK).then(() => true).catch(() => false);
3189
+ if (exists) {
3190
+ return Promise.resolve();
3191
+ }
3192
+ return fs.mkdir(dir, { recursive: true });
3193
+ };
3194
+ writeFile = async (path2, data) => {
3195
+ if (this.dry) {
3196
+ console.log(`${pc3.blue("writeFile")} ${path2}`);
3197
+ return Promise.resolve();
3198
+ }
3199
+ return fs.writeFile(path2, data, { encoding: "utf-8" }).catch((error) => {
3200
+ console.error(pc3.red(`Error writing file: ${path2}`));
3201
+ console.error(pc3.red(error));
3202
+ throw error;
3203
+ });
3204
+ };
3205
+ cp = async (src, dest, filter) => {
3206
+ if (this.dry) {
3207
+ console.log(`${pc3.blue("cp")} ${src} ${dest}`);
3208
+ return Promise.resolve();
3209
+ }
3210
+ return fs.cp(src, dest, { recursive: true, filter });
3211
+ };
3212
+ copyFile = async (src, dest) => {
3213
+ if (this.dry) {
3214
+ console.log(`${pc3.blue("copyFile")} ${src} to ${dest}`);
3215
+ return Promise.resolve();
3216
+ }
3217
+ return fs.copyFile(src, dest);
3218
+ };
3219
+ cleanDir = async (dir) => {
3220
+ if (this.dry) {
3221
+ console.log(`${pc3.blue("cleanDir")} ${dir}`);
3222
+ return Promise.resolve();
3223
+ }
3224
+ console.log(`
3177
3225
  \u{1F525} Cleaning dir ${pc3.red(`${dir.trim()}`)} `);
3178
- return fs.rm(dir, { recursive: true, force: true });
3226
+ return fs.rm(dir, { recursive: true, force: true });
3227
+ };
3228
+ readFile = async (path2, allowFileNotFound) => {
3229
+ if (this.dry) {
3230
+ console.log(`${pc3.blue("readFile")} ${path2}`);
3231
+ }
3232
+ try {
3233
+ return await fs.readFile(path2, "utf-8");
3234
+ } catch (error) {
3235
+ if (allowFileNotFound && error.code === "ENOENT") {
3236
+ return "";
3237
+ }
3238
+ throw error;
3239
+ }
3240
+ };
3241
+ readdir = async (path2) => {
3242
+ if (this.dry) {
3243
+ console.log(`${pc3.blue("readdir")} ${path2}`);
3244
+ }
3245
+ try {
3246
+ return await fs.readdir(path2);
3247
+ } catch (error) {
3248
+ if (error.code === "ENOENT") {
3249
+ return [];
3250
+ }
3251
+ throw error;
3252
+ }
3253
+ };
3254
+ writeFiles = async (files, outDir, log) => {
3255
+ for (const { destination: filename, output } of files) {
3256
+ if (filename) {
3257
+ const filePath = path.join(outDir, filename);
3258
+ const fileDir = path.dirname(filePath);
3259
+ if (log) {
3260
+ console.log(filename);
3261
+ }
3262
+ await this.mkdir(fileDir);
3263
+ await this.writeFile(filePath, output);
3264
+ }
3265
+ }
3266
+ };
3179
3267
  };
3268
+ var dsfs = new FileSystem();
3180
3269
 
3181
3270
  // src/scripts/update-preview-tokens.ts
3182
3271
  var OUTDIR = "../../internal/components/src/tokens/design-tokens";
3183
- async function write(files, outDir, dry) {
3184
- for (const { destination, output } of files) {
3185
- if (destination) {
3186
- const filePath = path.join(outDir, destination);
3187
- const fileDir = path.dirname(filePath);
3188
- console.log(`Writing file: ${pc4.green(filePath)}`);
3189
- await mkdir(fileDir, dry);
3190
- await writeFile(filePath, output, dry);
3191
- }
3192
- }
3193
- }
3194
3272
  var toPreviewToken = (tokens) => tokens.map(({ token, formatted }) => {
3195
3273
  const [variable, value] = formatted.split(":");
3196
3274
  return {
@@ -3213,7 +3291,7 @@ var formatTheme = async (themeConfig) => {
3213
3291
  verbose: false,
3214
3292
  buildTokenFormats: {}
3215
3293
  });
3216
- await cleanDir(OUTDIR, false);
3294
+ await dsfs.cleanDir(OUTDIR);
3217
3295
  console.log(
3218
3296
  buildOptions?.buildTokenFormats ? `
3219
3297
  \u{1F3D7}\uFE0F Start building preview tokens for ${pc4.blue("Designsystemet")}
@@ -3244,15 +3322,14 @@ var formatTheme = async (themeConfig) => {
3244
3322
  console.log(`
3245
3323
  \u{1F4BE} Writing preview tokens`);
3246
3324
  for (const [type, tokens] of Object.entries(tokensGroupedByType)) {
3247
- write(
3325
+ dsfs.writeFiles(
3248
3326
  [
3249
3327
  {
3250
3328
  destination: `${type}.json`,
3251
3329
  output: JSON.stringify(tokens, null, 2)
3252
3330
  }
3253
3331
  ],
3254
- OUTDIR,
3255
- false
3332
+ OUTDIR
3256
3333
  );
3257
3334
  }
3258
3335
  console.log(`
@@ -1,3 +1,4 @@
1
1
  import { type BuildOptions } from './process/platform.js';
2
- export declare const buildTokens: (options: Omit<BuildOptions, "type" | "processed$themes" | "buildTokenFormats">) => Promise<import("./process/platform.js").ProcessReturn>;
2
+ import type { OutputFile } from './types.js';
3
+ export declare const buildTokens: (options: Omit<BuildOptions, "type" | "processed$themes" | "buildTokenFormats">) => Promise<OutputFile[]>;
3
4
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/tokens/build.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,uBAAuB,CAAC;AAkB3E,eAAO,MAAM,WAAW,GAAU,SAAS,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG,mBAAmB,CAAC,2DAsD/G,CAAC"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/tokens/build.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,uBAAuB,CAAC;AAE3E,OAAO,KAAK,EAAwB,UAAU,EAAE,MAAM,YAAY,CAAC;AAEnE,eAAO,MAAM,WAAW,GAAU,SAAS,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG,mBAAmB,CAAC,0BAuC/G,CAAC"}
@@ -1,47 +1,131 @@
1
1
  // src/tokens/build.ts
2
- import path from "path";
3
2
  import pc6 from "picocolors";
4
3
  import * as R17 from "ramda";
5
4
 
6
- // src/utils.ts
5
+ // src/utils/filesystem.ts
7
6
  import fs from "fs/promises";
7
+ import path from "path";
8
8
  import pc from "picocolors";
9
- var mkdir = async (dir, dry) => {
10
- if (dry) {
11
- console.log(`${pc.blue("mkdir")} ${dir}`);
12
- return Promise.resolve();
13
- }
14
- const exists = await fs.access(dir, fs.constants.F_OK).then(() => true).catch(() => false);
15
- if (exists) {
16
- return Promise.resolve();
17
- }
18
- return fs.mkdir(dir, { recursive: true });
19
- };
20
- var writeFile = async (path2, data, dry) => {
21
- if (dry) {
22
- console.log(`${pc.blue("writeFile")} ${path2}`);
23
- return Promise.resolve();
24
- }
25
- return fs.writeFile(path2, data, { encoding: "utf-8" }).catch((error) => {
26
- console.error(pc.red(`Error writing file: ${path2}`));
27
- console.error(pc.red(error));
28
- throw error;
29
- });
30
- };
31
- var readFile = async (path2, dry, allowFileNotFound) => {
32
- if (dry) {
33
- console.log(`${pc.blue("readFile")} ${path2}`);
34
- return Promise.resolve("");
35
- }
36
- try {
37
- return await fs.readFile(path2, "utf-8");
38
- } catch (error) {
39
- if (allowFileNotFound && error.code === "ENOENT") {
40
- return "";
9
+ var FileSystem = class {
10
+ isInitialized = false;
11
+ dry = false;
12
+ verbose = false;
13
+ /** Default working directory is where the process was started */
14
+ workingDir = process.cwd();
15
+ outDir = this.workingDir;
16
+ /** Initialize the file system */
17
+ init({ dry, outdir, verbose }) {
18
+ if (this.isInitialized) {
19
+ console.warn(pc.yellow("FileSystem is already initialized. Ignoring subsequent init call."));
20
+ return;
21
+ }
22
+ if (dry) {
23
+ console.log(pc.blue("Initializing FileSystem in dry-run mode. No files will be written."));
41
24
  }
42
- throw error;
25
+ this.dry = dry ?? false;
26
+ this.verbose = verbose ?? false;
27
+ this.outDir = outdir ? path.isAbsolute(outdir) ? outdir : path.join(this.workingDir, outdir) : this.workingDir;
28
+ if (this.verbose) {
29
+ console.log(
30
+ `FileSystem initialized with workingDir: ${pc.green(this.workingDir)}, outDir: ${pc.green(this.outDir)}`
31
+ );
32
+ }
33
+ this.isInitialized = true;
43
34
  }
35
+ /**
36
+ * Creates a directory if it does not already exist.
37
+ *
38
+ * @param dir - The path of the directory to create.
39
+ *
40
+ * @returns A promise that resolves when the operation is complete.
41
+ * If the directory already exists or `dry` is `true`, the promise resolves immediately.
42
+ */
43
+ mkdir = async (dir) => {
44
+ if (this.dry) {
45
+ console.log(`${pc.blue("mkdir")} ${dir}`);
46
+ return Promise.resolve();
47
+ }
48
+ const exists = await fs.access(dir, fs.constants.F_OK).then(() => true).catch(() => false);
49
+ if (exists) {
50
+ return Promise.resolve();
51
+ }
52
+ return fs.mkdir(dir, { recursive: true });
53
+ };
54
+ writeFile = async (path2, data) => {
55
+ if (this.dry) {
56
+ console.log(`${pc.blue("writeFile")} ${path2}`);
57
+ return Promise.resolve();
58
+ }
59
+ return fs.writeFile(path2, data, { encoding: "utf-8" }).catch((error) => {
60
+ console.error(pc.red(`Error writing file: ${path2}`));
61
+ console.error(pc.red(error));
62
+ throw error;
63
+ });
64
+ };
65
+ cp = async (src, dest, filter) => {
66
+ if (this.dry) {
67
+ console.log(`${pc.blue("cp")} ${src} ${dest}`);
68
+ return Promise.resolve();
69
+ }
70
+ return fs.cp(src, dest, { recursive: true, filter });
71
+ };
72
+ copyFile = async (src, dest) => {
73
+ if (this.dry) {
74
+ console.log(`${pc.blue("copyFile")} ${src} to ${dest}`);
75
+ return Promise.resolve();
76
+ }
77
+ return fs.copyFile(src, dest);
78
+ };
79
+ cleanDir = async (dir) => {
80
+ if (this.dry) {
81
+ console.log(`${pc.blue("cleanDir")} ${dir}`);
82
+ return Promise.resolve();
83
+ }
84
+ console.log(`
85
+ \u{1F525} Cleaning dir ${pc.red(`${dir.trim()}`)} `);
86
+ return fs.rm(dir, { recursive: true, force: true });
87
+ };
88
+ readFile = async (path2, allowFileNotFound) => {
89
+ if (this.dry) {
90
+ console.log(`${pc.blue("readFile")} ${path2}`);
91
+ }
92
+ try {
93
+ return await fs.readFile(path2, "utf-8");
94
+ } catch (error) {
95
+ if (allowFileNotFound && error.code === "ENOENT") {
96
+ return "";
97
+ }
98
+ throw error;
99
+ }
100
+ };
101
+ readdir = async (path2) => {
102
+ if (this.dry) {
103
+ console.log(`${pc.blue("readdir")} ${path2}`);
104
+ }
105
+ try {
106
+ return await fs.readdir(path2);
107
+ } catch (error) {
108
+ if (error.code === "ENOENT") {
109
+ return [];
110
+ }
111
+ throw error;
112
+ }
113
+ };
114
+ writeFiles = async (files, outDir, log) => {
115
+ for (const { destination: filename, output } of files) {
116
+ if (filename) {
117
+ const filePath = path.join(outDir, filename);
118
+ const fileDir = path.dirname(filePath);
119
+ if (log) {
120
+ console.log(filename);
121
+ }
122
+ await this.mkdir(fileDir);
123
+ await this.writeFile(filePath, output);
124
+ }
125
+ }
126
+ };
44
127
  };
128
+ var dsfs = new FileSystem();
45
129
 
46
130
  // src/tokens/process/output/declarations.ts
47
131
  import pc4 from "picocolors";
@@ -49,11 +133,11 @@ import pc4 from "picocolors";
49
133
  // package.json
50
134
  var package_default = {
51
135
  name: "@digdir/designsystemet",
52
- version: "1.12.0",
136
+ version: "1.13.0",
53
137
  description: "CLI for Designsystemet",
54
138
  author: "Designsystemet team",
55
139
  engines: {
56
- node: ">=20 <25"
140
+ node: ">=20.20.1"
57
141
  },
58
142
  repository: {
59
143
  type: "git",
@@ -117,16 +201,16 @@ var package_default = {
117
201
  hsluv: "^1.0.1",
118
202
  "object-hash": "^3.0.0",
119
203
  picocolors: "^1.1.1",
120
- postcss: "^8.5.6",
204
+ postcss: "^8.5.8",
121
205
  ramda: "^0.32.0",
122
- "style-dictionary": "^5.3.0",
206
+ "style-dictionary": "^5.3.3",
123
207
  zod: "^4.3.6",
124
208
  "zod-validation-error": "^5.0.0"
125
209
  },
126
210
  devDependencies: {
127
211
  "@tokens-studio/types": "0.5.2",
128
212
  "@types/chroma-js": "^3.1.2",
129
- "@types/node": "^24.10.13",
213
+ "@types/node": "^24.12.0",
130
214
  "@types/object-hash": "^3.0.6",
131
215
  "@types/ramda": "^0.31.1",
132
216
  tsup: "^8.5.1",
@@ -1695,25 +1779,13 @@ ${fileHeader}
1695
1779
  };
1696
1780
 
1697
1781
  // src/tokens/build.ts
1698
- async function write(files, outDir, dry) {
1699
- for (const { destination, output } of files) {
1700
- if (destination) {
1701
- const filePath = path.join(outDir, destination);
1702
- const fileDir = path.dirname(filePath);
1703
- console.log(destination);
1704
- await mkdir(fileDir, dry);
1705
- await writeFile(filePath, output, dry);
1706
- }
1707
- }
1708
- }
1709
1782
  var buildTokens = async (options) => {
1710
- const outDir = path.resolve(options.outDir);
1711
- const tokensDir = path.resolve(options.tokensDir);
1712
- const $themes = JSON.parse(await readFile(`${tokensDir}/$themes.json`));
1783
+ const tokensDir = options.tokensDir;
1784
+ const $themes = JSON.parse(await dsfs.readFile(`${tokensDir}/$themes.json`));
1713
1785
  const processed$themes = $themes.map(processThemeObject);
1714
1786
  let $designsystemet;
1715
1787
  try {
1716
- const $designsystemetContent = await readFile(`${tokensDir}/$designsystemet.jsonc`);
1788
+ const $designsystemetContent = await dsfs.readFile(`${tokensDir}/$designsystemet.jsonc`);
1717
1789
  $designsystemet = JSON.parse($designsystemetContent);
1718
1790
  } catch (_error) {
1719
1791
  }
@@ -1721,7 +1793,6 @@ var buildTokens = async (options) => {
1721
1793
  \u{1F3D7}\uFE0F Start building tokens in ${pc6.green(tokensDir)}`);
1722
1794
  const processedBuilds = await processPlatform({
1723
1795
  ...options,
1724
- outDir,
1725
1796
  tokensDir,
1726
1797
  type: "build",
1727
1798
  processed$themes,
@@ -1740,12 +1811,7 @@ design-tokens: v${$designsystemet.version}` : ""
1740
1811
  const tailwindFiles = createTailwindCSSFiles(cssFiles);
1741
1812
  files = files.concat(tailwindFiles.filter(Boolean));
1742
1813
  }
1743
- console.log(`
1744
- \u{1F4BE} Writing build to ${pc6.green(outDir)}`);
1745
- await write(files, outDir, options.dry);
1746
- console.log(`
1747
- \u2705 Finished building tokens!`);
1748
- return processedBuilds;
1814
+ return files;
1749
1815
  };
1750
1816
  export {
1751
1817
  buildTokens
@@ -0,0 +1,10 @@
1
+ import type { OutputFile, Theme, TokenSets } from '../types.js';
2
+ export declare const stringify: (data: unknown) => string;
3
+ type CreateTokenFilesOptions = {
4
+ outDir: string;
5
+ theme: Theme;
6
+ tokenSets: TokenSets;
7
+ };
8
+ export declare const createTokenFiles: (options: CreateTokenFilesOptions) => Promise<OutputFile[]>;
9
+ export {};
10
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../../src/tokens/create/files.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAa,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK3E,eAAO,MAAM,SAAS,GAAI,MAAM,OAAO,WAAkC,CAAC;AAE1E,KAAK,uBAAuB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,SAAS,uBAAuB,0BAoDtE,CAAC"}