@jk2908/cxx 0.3.1 → 0.3.4

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.
@@ -14,6 +14,86 @@ var PKG_NAME = `@jk2908/${NAME}`;
14
14
  var GENERATED_DIR = `.${NAME}`;
15
15
  var AUTOGEN_MSG = `// auto-generated by ${NAME}`;
16
16
 
17
+ // src/logger.ts
18
+ var LEVELS = {
19
+ debug: 0,
20
+ info: 1,
21
+ warn: 2,
22
+ error: 3,
23
+ fatal: 4
24
+ };
25
+ var defaultLevel = process.env["NODE_ENV"] === "production" ? "error" : "info";
26
+
27
+ class Logger {
28
+ name;
29
+ #level = defaultLevel;
30
+ constructor(name) {
31
+ this.name = name;
32
+ }
33
+ static toError(err) {
34
+ return err instanceof Error ? err : new Error(String(err), { cause: err });
35
+ }
36
+ static print(err) {
37
+ if (err instanceof Error) {
38
+ return err.message + (err.stack ? `
39
+ ${err.stack}` : "");
40
+ }
41
+ if (typeof err === "object" && err !== null) {
42
+ try {
43
+ return JSON.stringify(err, null, 2);
44
+ } catch {
45
+ return String(err);
46
+ }
47
+ }
48
+ return String(err);
49
+ }
50
+ set level(level) {
51
+ this.#level = level;
52
+ }
53
+ get level() {
54
+ return this.#level;
55
+ }
56
+ log(level, message, error) {
57
+ if (LEVELS[level] < LEVELS[this.level])
58
+ return;
59
+ const entry = {
60
+ ts: Date.now(),
61
+ level,
62
+ message
63
+ };
64
+ if (level === "error" || level === "fatal") {
65
+ entry.error = error ? Logger.toError(error) : new Error(message);
66
+ }
67
+ const line = `${this.name ? `[${this.name}]` : ""} [${entry.ts}] [${level.toUpperCase()}] ${message}`;
68
+ const extra = entry.error ? `
69
+ ${Logger.print(entry.error)}` : "";
70
+ if (level === "warn") {
71
+ console.warn(line, extra);
72
+ return;
73
+ }
74
+ if (level === "error" || level === "fatal") {
75
+ console.error(line, extra);
76
+ return;
77
+ }
78
+ console.log(line, extra);
79
+ }
80
+ debug(...messages) {
81
+ this.log("debug", messages.join(" "));
82
+ }
83
+ info(...messages) {
84
+ this.log("info", messages.join(" "));
85
+ }
86
+ warn(...messages) {
87
+ this.log("warn", messages.join(" "));
88
+ }
89
+ error(message, error) {
90
+ this.log("error", message, error === undefined ? undefined : Logger.toError(error));
91
+ }
92
+ fatal(message, error) {
93
+ this.log("fatal", message, error === undefined ? undefined : Logger.toError(error));
94
+ }
95
+ }
96
+
17
97
  // src/lru.ts
18
98
  var CACHE_MAX_SIZE = 100;
19
99
 
@@ -56,51 +136,12 @@ function capitalise(str) {
56
136
  function pascalise(str) {
57
137
  return str.split(/[ _-]+/).map(capitalise).join("");
58
138
  }
59
- function createBatcher(wait, flush) {
60
- const pending = new Map;
61
- let timer = null;
62
- let running = false;
63
- async function drain() {
64
- if (running)
65
- return;
66
- running = true;
67
- try {
68
- while (pending.size > 0) {
69
- const batch = new Map(pending);
70
- pending.clear();
71
- await flush(batch);
72
- }
73
- } finally {
74
- running = false;
75
- }
76
- }
77
- function schedule() {
78
- if (timer)
79
- clearTimeout(timer);
80
- timer = setTimeout(() => {
81
- timer = null;
82
- drain();
83
- }, wait);
84
- }
85
- return {
86
- add(key, value) {
87
- pending.set(key, value);
88
- schedule();
89
- },
90
- flush() {
91
- if (timer) {
92
- clearTimeout(timer);
93
- timer = null;
94
- }
95
- return drain();
96
- }
97
- };
98
- }
99
139
 
100
140
  // src/build.ts
141
+ var logger = new Logger(NAME);
101
142
  var decoder = new TextDecoder;
143
+ var encoder = new TextEncoder;
102
144
  var collectCache = new LruCache;
103
- var fileCache = new LruCache;
104
145
  var writeChain = Promise.resolve();
105
146
  function isENOENT(err) {
106
147
  return err instanceof Error && "code" in err && err.code === "ENOENT";
@@ -108,7 +149,12 @@ function isENOENT(err) {
108
149
  async function writeFileAtomic(filePath, content) {
109
150
  const tmp = `${filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
110
151
  await fs.writeFile(tmp, content);
111
- await fs.rename(tmp, filePath);
152
+ try {
153
+ await fs.rename(tmp, filePath);
154
+ } catch (err) {
155
+ await fs.rm(tmp, { force: true });
156
+ throw err;
157
+ }
112
158
  }
113
159
  function enqueueWrite(task) {
114
160
  const run = writeChain.then(task, task);
@@ -120,20 +166,14 @@ function enqueueWrite(task) {
120
166
  return run;
121
167
  }
122
168
  async function maybeWrite(filePath, content) {
123
- const cached = fileCache.get(filePath);
124
- if (cached === content)
125
- return false;
126
169
  try {
127
- if (await fs.readFile(filePath, "utf-8") === content) {
128
- fileCache.set(filePath, content);
170
+ if (await fs.readFile(filePath, "utf-8") === content)
129
171
  return false;
130
- }
131
172
  } catch (err) {
132
173
  if (!isENOENT(err))
133
174
  throw err;
134
175
  }
135
176
  await writeFileAtomic(filePath, content);
136
- fileCache.set(filePath, content);
137
177
  return true;
138
178
  }
139
179
  var regex = /((?:export\s+)?)(?:const|var|let)\s*\[(\w*)\s*,?\s*(\w*)\s*,?\s*(\w*)\s*\]\s*=\s*cxx(?:\s*`([\s\S]*?)`|\s*\.\s*tag(?:\s*<[^>]+>)?\s*\(\s*(['"])(.*?)\6\s*\)\s*`([\s\S]*?)`)/gm;
@@ -169,14 +209,23 @@ function collect(source, id, config) {
169
209
  matched = true;
170
210
  const [, exp, varOne, varTwo, varThree, plainCss, , tag, taggedCss] = match;
171
211
  const css = plainCss ?? taggedCss;
172
- const { code, exports = {} } = transform({
173
- minify: true,
174
- cssModules: true,
175
- filename: id,
176
- code: new TextEncoder().encode(css)
177
- });
212
+ const matchIndex = match.index;
213
+ const { code, exports: classExports = {} } = (() => {
214
+ try {
215
+ return transform({
216
+ minify: true,
217
+ cssModules: true,
218
+ filename: id,
219
+ code: encoder.encode(css)
220
+ });
221
+ } catch (err) {
222
+ const line = source.slice(0, matchIndex).split(`
223
+ `).length;
224
+ throw new Error(`Failed to compile cxx CSS at ${id}:${line}`, { cause: err });
225
+ }
226
+ })();
178
227
  const href = hashCss(code);
179
- const styles = Object.fromEntries(Object.entries(exports).map(([k, v]) => [k, v.name]));
228
+ const styles = Object.fromEntries(Object.entries(classExports).map(([k, v]) => [k, v.name]));
180
229
  if (tag) {
181
230
  const suffix = typeof config.typeSuffix === "string" ? config.typeSuffix : config.typeSuffix === false ? "" : "Classes";
182
231
  const tagWithSuffix = pascalise(`${tag}${suffix}`);
@@ -196,7 +245,7 @@ function collect(source, id, config) {
196
245
  if (varThree) {
197
246
  statements.push(`${exp}const ${varThree} = ${JSON.stringify(href)}`);
198
247
  }
199
- magic.overwrite(match.index, match.index + match[0].length, statements.join(`
248
+ magic.overwrite(matchIndex, matchIndex + match[0].length, statements.join(`
200
249
  `));
201
250
  }
202
251
  const template = magic.toString();
@@ -222,16 +271,14 @@ async function writeRenderedTypes(tags) {
222
271
  const filePath = path.join(GENERATED_DIR, "index.d.ts");
223
272
  if (!tags.size) {
224
273
  await fs.rm(filePath, { force: true });
225
- fileCache.delete(filePath);
226
274
  return;
227
275
  }
228
276
  await fs.mkdir(GENERATED_DIR, { recursive: true });
229
277
  await maybeWrite(filePath, renderTypes(tags));
230
278
  }
231
- function writeTypes(tags) {
232
- return enqueueWrite(() => writeRenderedTypes(tags));
233
- }
234
279
  var PARTIAL_DIR = path.join(GENERATED_DIR, "tags");
280
+ var REBUILD_WAIT = 100;
281
+ var rebuildTimer = null;
235
282
  function partialPath(filePath) {
236
283
  return path.join(PARTIAL_DIR, `${createHash("sha1").update(filePath).digest("hex")}.json`);
237
284
  }
@@ -241,10 +288,12 @@ async function readPartials() {
241
288
  entries = await fs.readdir(PARTIAL_DIR);
242
289
  } catch (err) {
243
290
  if (isENOENT(err))
244
- return new Map;
291
+ return { tags: new Map, duplicates: [] };
245
292
  throw err;
246
293
  }
247
294
  const tags = new Map;
295
+ const fileByTag = new Map;
296
+ const duplicates = [];
248
297
  for (const entry of entries) {
249
298
  if (!entry.endsWith(".json"))
250
299
  continue;
@@ -255,19 +304,28 @@ async function readPartials() {
255
304
  } catch {
256
305
  continue;
257
306
  }
307
+ let source;
258
308
  try {
259
- await fs.access(parsed.file);
309
+ source = await fs.readFile(parsed.file, "utf-8");
260
310
  } catch {
261
311
  await fs.rm(partial, { force: true });
262
312
  continue;
263
313
  }
314
+ if (!source.includes("cxx")) {
315
+ await fs.rm(partial, { force: true });
316
+ continue;
317
+ }
264
318
  for (const [name, classes] of Object.entries(parsed.tags)) {
265
- if (tags.has(name))
266
- throw new DuplicateTagError(name);
319
+ const existing = fileByTag.get(name);
320
+ if (existing) {
321
+ duplicates.push({ tag: name, files: [existing, parsed.file] });
322
+ continue;
323
+ }
324
+ fileByTag.set(name, parsed.file);
267
325
  tags.set(name, classes);
268
326
  }
269
327
  }
270
- return tags;
328
+ return { tags, duplicates };
271
329
  }
272
330
  function writeTypesForFile(filePath, tags) {
273
331
  return enqueueWrite(async () => {
@@ -278,201 +336,149 @@ function writeTypesForFile(filePath, tags) {
278
336
  } else {
279
337
  await writeFileAtomic(partial, JSON.stringify({ file: filePath, tags: Object.fromEntries(tags) }));
280
338
  }
281
- await writeRenderedTypes(await readPartials());
339
+ }).then(() => scheduleRebuild()).catch((err) => {
340
+ logger.error(`failed to write types for ${filePath}`, err);
282
341
  });
283
342
  }
284
- function tagsToType(tags) {
285
- return [...tags].map(([tag, classes]) => {
286
- const union = classes.length > 0 ? classes.toSorted((a, b) => a.length - b.length).map((c) => `'${c}'`).join(" | ") : "never";
287
- return ` export type ${tag} = ${union}`;
288
- }).join(`
289
- `);
343
+ function scheduleRebuild() {
344
+ if (rebuildTimer)
345
+ clearTimeout(rebuildTimer);
346
+ rebuildTimer = setTimeout(() => {
347
+ rebuildTimer = null;
348
+ flushTypes().catch((err) => {
349
+ logger.error("failed to generate types", err);
350
+ });
351
+ }, REBUILD_WAIT);
290
352
  }
291
- function flattenTags(tagsByFile) {
292
- const tags = new Map;
293
- for (const fileTags of tagsByFile.values()) {
294
- for (const [name, classes] of fileTags) {
295
- if (tags.has(name))
296
- throw new DuplicateTagError(name);
297
- tags.set(name, classes);
298
- }
353
+ function flushTypes() {
354
+ if (rebuildTimer) {
355
+ clearTimeout(rebuildTimer);
356
+ rebuildTimer = null;
299
357
  }
300
- return tags;
301
- }
302
-
303
- // src/vite/index.ts
304
- import { realpathSync } from "node:fs";
305
- import fs2 from "node:fs/promises";
306
- import path2 from "node:path";
307
-
308
- // src/logger.ts
309
- var LEVELS = {
310
- debug: 0,
311
- info: 1,
312
- warn: 2,
313
- error: 3,
314
- fatal: 4
315
- };
316
- var defaultLevel = process.env["NODE_ENV"] === "production" ? "error" : "info";
317
-
318
- class Logger {
319
- name;
320
- #level;
321
- constructor(level, name) {
322
- this.name = name;
323
- this.#level = level ?? defaultLevel;
324
- }
325
- static toError(err) {
326
- return err instanceof Error ? err : new Error(String(err), { cause: err });
327
- }
328
- static print(err) {
329
- if (err instanceof Error) {
330
- return err.message + (err.stack ? `
331
- ${err.stack}` : "");
358
+ return enqueueWrite(async () => {
359
+ const { tags, duplicates } = await readPartials();
360
+ await writeRenderedTypes(tags);
361
+ for (const duplicate of duplicates) {
362
+ logger.error(`Tag "${duplicate.tag}" is defined in multiple files: ${duplicate.files.join(", ")}`);
332
363
  }
333
- if (typeof err === "object" && err !== null) {
334
- try {
335
- return JSON.stringify(err, null, 2);
336
- } catch {
337
- return String(err);
338
- }
364
+ });
365
+ }
366
+ var SOURCE_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx"]);
367
+ var SKIP_DIRS = new Set(["node_modules", "dist", "build", "coverage", "out"]);
368
+ async function runWithConcurrency(items, concurrency, fn) {
369
+ let cursor = 0;
370
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
371
+ while (cursor < items.length) {
372
+ const index = cursor++;
373
+ await fn(items[index]);
339
374
  }
340
- return String(err);
341
- }
342
- set level(level) {
343
- this.#level = level;
344
- }
345
- get level() {
346
- return this.#level;
375
+ });
376
+ await Promise.all(workers);
377
+ }
378
+ async function refreshFile(file, config) {
379
+ let source;
380
+ try {
381
+ source = await fs.readFile(file, "utf-8");
382
+ } catch (err) {
383
+ if (!isENOENT(err))
384
+ throw err;
385
+ await writeTypesForFile(file, new Map);
386
+ return;
347
387
  }
348
- log(level, message, error) {
349
- if (LEVELS[level] < LEVELS[this.level])
350
- return;
351
- const entry = {
352
- ts: Date.now(),
353
- level,
354
- message
355
- };
356
- if (level === "error" || level === "fatal") {
357
- entry.error = error ? Logger.toError(error) : new Error(message);
358
- }
359
- const line = `${this.name ? `[${this.name}]` : ""} [${entry.ts}] [${level.toUpperCase()}] ${message}`;
360
- const extra = entry.error ? `
361
- ${Logger.print(entry.error)}` : "";
362
- if (level === "warn") {
363
- console.warn(line, extra);
364
- return;
365
- }
366
- if (level === "error" || level === "fatal") {
367
- console.error(line, extra);
388
+ const tags = source.includes("cxx") ? collect(source, file, config).tags : new Map;
389
+ await writeTypesForFile(file, tags);
390
+ }
391
+ async function seedTypes(root, config) {
392
+ async function scan(dir) {
393
+ let entries;
394
+ try {
395
+ entries = await fs.readdir(dir, { withFileTypes: true });
396
+ } catch {
368
397
  return;
369
398
  }
370
- console.log(line, extra);
371
- }
372
- debug(...messages) {
373
- this.log("debug", messages.join(" "));
374
- }
375
- info(...messages) {
376
- this.log("info", messages.join(" "));
377
- }
378
- warn(...messages) {
379
- this.log("warn", messages.join(" "));
380
- }
381
- error(message, error) {
382
- this.log("error", message, error === undefined ? undefined : Logger.toError(error));
383
- }
384
- fatal(message, error) {
385
- this.log("fatal", message, error === undefined ? undefined : Logger.toError(error));
399
+ await runWithConcurrency(entries, 8, async (entry) => {
400
+ if (entry.name.startsWith(".") || SKIP_DIRS.has(entry.name))
401
+ return;
402
+ const full = path.join(dir, entry.name);
403
+ if (entry.isDirectory()) {
404
+ await scan(full);
405
+ return;
406
+ }
407
+ if (!SOURCE_EXTENSIONS.has(path.extname(entry.name)))
408
+ return;
409
+ await refreshFile(full, config);
410
+ });
386
411
  }
412
+ await scan(root);
413
+ await flushTypes();
414
+ }
415
+ function tagsToType(tags) {
416
+ return [...tags].toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([tag, classes]) => {
417
+ const union = classes.length > 0 ? classes.toSorted((a, b) => a.length - b.length).map((c) => `'${c}'`).join(" | ") : "never";
418
+ return ` export type ${tag} = ${union}`;
419
+ }).join(`
420
+ `);
387
421
  }
388
422
 
389
423
  // src/vite/index.ts
390
- var ACCEPTED_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx"]);
424
+ import { realpathSync } from "node:fs";
425
+ import path2 from "node:path";
391
426
  function normaliseWatchPath(p) {
392
427
  return p.replace(/\\/g, "/");
393
428
  }
394
429
  function cxx(pluginConfig = {}) {
395
- const buildContext = {
396
- tagsByFile: new Map
397
- };
398
- const logger = new Logger;
430
+ const logger2 = new Logger;
399
431
  let watchRoot = normaliseWatchPath(process.cwd());
432
+ let seeded = false;
433
+ const realpaths = new Map;
400
434
  function resolveWatchFile(filePath) {
401
435
  const absolutePath = path2.resolve(watchRoot, filePath);
402
436
  const parentPath = path2.dirname(absolutePath);
403
- try {
404
- const resolvedParentPath = normaliseWatchPath(realpathSync.native(parentPath));
405
- return normaliseWatchPath(path2.join(resolvedParentPath, path2.basename(absolutePath)));
406
- } catch {
407
- return normaliseWatchPath(absolutePath);
437
+ let resolvedParentPath = realpaths.get(parentPath);
438
+ if (resolvedParentPath === undefined) {
439
+ try {
440
+ resolvedParentPath = normaliseWatchPath(realpathSync.native(parentPath));
441
+ } catch {
442
+ resolvedParentPath = normaliseWatchPath(parentPath);
443
+ }
444
+ realpaths.set(parentPath, resolvedParentPath);
408
445
  }
446
+ return normaliseWatchPath(path2.join(resolvedParentPath, path2.basename(absolutePath)));
409
447
  }
410
448
  function watchedFile(filePath) {
411
449
  const resolvedPath = resolveWatchFile(filePath);
412
- if (resolvedPath.startsWith(`${watchRoot}/`) && !resolvedPath.includes(`/${GENERATED_DIR}/`) && ACCEPTED_EXTENSIONS.has(path2.extname(resolvedPath))) {
450
+ if (resolvedPath.startsWith(`${watchRoot}/`) && !resolvedPath.includes(`/${GENERATED_DIR}/`) && SOURCE_EXTENSIONS.has(path2.extname(resolvedPath))) {
413
451
  return resolvedPath;
414
452
  }
415
453
  return null;
416
454
  }
417
- async function onEvent(event, file) {
418
- const hadTags = buildContext.tagsByFile.has(file);
455
+ async function handleEvent(event, file) {
419
456
  if (event === "unlink") {
420
- if (!hadTags)
421
- return;
422
- buildContext.tagsByFile.delete(file);
423
- await writeTypes(flattenTags(buildContext.tagsByFile));
424
- logger.info(`updated types from ${file}`);
425
- return;
426
- }
427
- let source;
428
- try {
429
- source = await fs2.readFile(file, "utf-8");
430
- } catch (err) {
431
- if (!isENOENT(err))
432
- throw err;
433
- if (!hadTags)
434
- return;
435
- buildContext.tagsByFile.delete(file);
436
- await writeTypes(flattenTags(buildContext.tagsByFile));
437
- logger.info(`updated types from ${file}`);
438
- return;
439
- }
440
- const { tags } = collect(source, file, pluginConfig);
441
- const hasTags = tags.size > 0;
442
- if (hasTags) {
443
- buildContext.tagsByFile.set(file, tags);
457
+ await writeTypesForFile(file, new Map);
444
458
  } else {
445
- buildContext.tagsByFile.delete(file);
459
+ await refreshFile(file, pluginConfig);
446
460
  }
447
- if (!hadTags && !hasTags)
461
+ logger2.info(`updated types from ${file}`);
462
+ }
463
+ function onWatch(event) {
464
+ return (p) => {
465
+ const file = watchedFile(p);
466
+ if (!file)
467
+ return;
468
+ handleEvent(event, file).catch((err) => {
469
+ logger2.error(`failed to update types from ${file}`, err);
470
+ });
471
+ };
472
+ }
473
+ async function seed() {
474
+ if (seeded)
448
475
  return;
449
- await writeTypes(flattenTags(buildContext.tagsByFile));
450
- logger.info(`updated types from ${file}`);
476
+ seeded = true;
477
+ await seedTypes(watchRoot, pluginConfig);
451
478
  }
452
- const queue = createBatcher(75, async (batch) => {
453
- for (const [file, event] of batch) {
454
- try {
455
- await onEvent(event, file);
456
- } catch (err) {
457
- logger.error(`failed to update types from ${file}`, err);
458
- }
459
- }
460
- });
461
479
  return {
462
480
  name: "cxx",
463
481
  enforce: "pre",
464
- config() {
465
- const ignore = pluginConfig.watch?.ignore;
466
- if (!ignore?.length)
467
- return null;
468
- return {
469
- server: {
470
- watch: {
471
- ignored: ignore
472
- }
473
- }
474
- };
475
- },
476
482
  configResolved(config) {
477
483
  const root = pluginConfig.watch?.root ?? config.root;
478
484
  try {
@@ -480,6 +486,10 @@ function cxx(pluginConfig = {}) {
480
486
  } catch {
481
487
  watchRoot = normaliseWatchPath(root);
482
488
  }
489
+ realpaths.clear();
490
+ },
491
+ async buildStart() {
492
+ await seed();
483
493
  },
484
494
  transform(code, id) {
485
495
  if (id.startsWith("\x00") || id.includes("/node_modules/"))
@@ -487,40 +497,23 @@ function cxx(pluginConfig = {}) {
487
497
  if (!code.includes("cxx"))
488
498
  return null;
489
499
  const cleanId = id.split("?")[0];
490
- if (!ACCEPTED_EXTENSIONS.has(path2.extname(cleanId)))
500
+ if (!SOURCE_EXTENSIONS.has(path2.extname(cleanId)))
491
501
  return null;
492
502
  const { template, tags, map } = collect(code, cleanId, pluginConfig);
493
503
  if (template === code)
494
504
  return null;
495
- const resolved = resolveWatchFile(cleanId);
496
- if (tags.size) {
497
- buildContext.tagsByFile.set(resolved, tags);
498
- } else {
499
- buildContext.tagsByFile.delete(resolved);
500
- }
505
+ writeTypesForFile(resolveWatchFile(cleanId), tags);
501
506
  return {
502
507
  code: template,
503
508
  map
504
509
  };
505
510
  },
506
511
  configureServer(server) {
507
- logger.info("Watching for changes...");
508
- server.watcher.on("add", (p) => {
509
- const file = watchedFile(p);
510
- if (file)
511
- queue.add(file, "add");
512
- }).on("change", (p) => {
513
- const file = watchedFile(p);
514
- if (file)
515
- queue.add(file, "change");
516
- }).on("unlink", (p) => {
517
- const file = watchedFile(p);
518
- if (file)
519
- queue.add(file, "unlink");
520
- });
512
+ logger2.info("Watching for changes...");
513
+ server.watcher.on("add", onWatch("add")).on("change", onWatch("change")).on("unlink", onWatch("unlink"));
521
514
  },
522
515
  async writeBundle() {
523
- await writeTypes(flattenTags(buildContext.tagsByFile));
516
+ await flushTypes();
524
517
  }
525
518
  };
526
519
  }
@@ -528,4 +521,4 @@ export {
528
521
  cxx as default
529
522
  };
530
523
 
531
- //# debugId=8BACD1ACA42BF59D64756E2164756E21
524
+ //# debugId=294541A31A244C8364756E2164756E21