@veryfront/ext-content-mdx 0.1.1189 → 0.1.1191

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 (86) hide show
  1. package/esm/deno.d.ts +5 -0
  2. package/esm/deno.js +13 -5
  3. package/esm/src/errors/error-registry/agent.d.ts +2 -0
  4. package/esm/src/errors/error-registry/agent.d.ts.map +1 -1
  5. package/esm/src/errors/error-registry/agent.js +8 -0
  6. package/esm/src/errors/error-registry/module.d.ts +4 -0
  7. package/esm/src/errors/error-registry/module.d.ts.map +1 -1
  8. package/esm/src/errors/error-registry/module.js +16 -0
  9. package/esm/src/errors/error-registry/server.d.ts +6 -0
  10. package/esm/src/errors/error-registry/server.d.ts.map +1 -1
  11. package/esm/src/errors/error-registry/server.js +18 -0
  12. package/esm/src/errors/error-registry.d.ts +5 -0
  13. package/esm/src/errors/error-registry.d.ts.map +1 -1
  14. package/esm/src/errors/types.d.ts.map +1 -1
  15. package/esm/src/errors/types.js +5 -2
  16. package/esm/src/extensions/websocket/node-websocket-server-provider.d.ts +4 -4
  17. package/esm/src/extensions/websocket/node-websocket-server-provider.d.ts.map +1 -1
  18. package/esm/src/extensions/websocket/node-websocket-server-provider.js +4 -4
  19. package/esm/src/platform/adapters/file-snapshot-error.d.ts +7 -0
  20. package/esm/src/platform/adapters/file-snapshot-error.d.ts.map +1 -1
  21. package/esm/src/platform/adapters/file-snapshot-error.js +13 -0
  22. package/esm/src/platform/adapters/path-containment.d.ts +9 -0
  23. package/esm/src/platform/adapters/path-containment.d.ts.map +1 -0
  24. package/esm/src/platform/adapters/path-containment.js +13 -0
  25. package/esm/src/platform/adapters/runtime/shared/native-snapshot-identity.d.ts +13 -0
  26. package/esm/src/platform/adapters/runtime/shared/native-snapshot-identity.d.ts.map +1 -0
  27. package/esm/src/platform/adapters/runtime/shared/native-snapshot-identity.js +12 -0
  28. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts +7 -0
  29. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts.map +1 -1
  30. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.js +62 -18
  31. package/esm/src/platform/compat/error-introspection.d.ts +12 -1
  32. package/esm/src/platform/compat/error-introspection.d.ts.map +1 -1
  33. package/esm/src/platform/compat/error-introspection.js +40 -5
  34. package/esm/src/platform/compat/path/basic-operations.d.ts.map +1 -1
  35. package/esm/src/platform/compat/path/basic-operations.js +6 -2
  36. package/esm/src/platform/compat/path/portable.d.ts.map +1 -1
  37. package/esm/src/platform/compat/path/portable.js +98 -54
  38. package/esm/src/platform/compat/path/resolution.d.ts.map +1 -1
  39. package/esm/src/platform/compat/path/resolution.js +14 -5
  40. package/esm/src/platform/compat/primordials/array.d.ts +8 -0
  41. package/esm/src/platform/compat/primordials/array.d.ts.map +1 -0
  42. package/esm/src/platform/compat/primordials/array.js +33 -0
  43. package/esm/src/transforms/import-rewriter/url-builder.d.ts.map +1 -1
  44. package/esm/src/transforms/import-rewriter/url-builder.js +40 -14
  45. package/esm/src/utils/base64url.d.ts.map +1 -1
  46. package/esm/src/utils/base64url.js +10 -4
  47. package/esm/src/utils/bundle-manifest.d.ts +19 -1
  48. package/esm/src/utils/bundle-manifest.d.ts.map +1 -1
  49. package/esm/src/utils/bundle-manifest.js +124 -27
  50. package/esm/src/utils/constants/limits.d.ts +3 -1
  51. package/esm/src/utils/constants/limits.d.ts.map +1 -1
  52. package/esm/src/utils/constants/limits.js +3 -1
  53. package/esm/src/utils/hash-utils.d.ts.map +1 -1
  54. package/esm/src/utils/hash-utils.js +32 -6
  55. package/esm/src/utils/id.d.ts +16 -0
  56. package/esm/src/utils/id.d.ts.map +1 -0
  57. package/esm/src/utils/id.js +69 -0
  58. package/esm/src/utils/import-lockfile.d.ts +52 -1
  59. package/esm/src/utils/import-lockfile.d.ts.map +1 -1
  60. package/esm/src/utils/import-lockfile.js +1042 -58
  61. package/esm/src/utils/index.d.ts +1 -1
  62. package/esm/src/utils/index.d.ts.map +1 -1
  63. package/esm/src/utils/index.js +1 -1
  64. package/esm/src/utils/logger/logger.d.ts +1 -0
  65. package/esm/src/utils/logger/logger.d.ts.map +1 -1
  66. package/esm/src/utils/logger/logger.js +359 -78
  67. package/esm/src/utils/logger/redact.d.ts +4 -2
  68. package/esm/src/utils/logger/redact.d.ts.map +1 -1
  69. package/esm/src/utils/logger/redact.js +300 -112
  70. package/esm/src/utils/logger/serialization.d.ts +3 -0
  71. package/esm/src/utils/logger/serialization.d.ts.map +1 -0
  72. package/esm/src/utils/logger/serialization.js +81 -0
  73. package/esm/src/utils/memoize.d.ts +1 -1
  74. package/esm/src/utils/memoize.d.ts.map +1 -1
  75. package/esm/src/utils/memoize.js +16 -5
  76. package/esm/src/utils/path-utils.d.ts.map +1 -1
  77. package/esm/src/utils/path-utils.js +4 -2
  78. package/esm/src/utils/sleep.d.ts +8 -0
  79. package/esm/src/utils/sleep.d.ts.map +1 -1
  80. package/esm/src/utils/sleep.js +11 -2
  81. package/esm/src/utils/timer.d.ts +10 -0
  82. package/esm/src/utils/timer.d.ts.map +1 -0
  83. package/esm/src/utils/timer.js +19 -0
  84. package/esm/src/utils/version-constant.d.ts +1 -1
  85. package/esm/src/utils/version-constant.js +1 -1
  86. package/package.json +2 -2
@@ -1,3 +1,4 @@
1
+ import * as dntShim from "../../../../../_dnt.shims.js";
1
2
  import { createFileWatcher, createWatcherIterator, setupNodeFsWatcher } from "./shared-watcher.js";
2
3
  import { makeNodeTempDir } from "./temp-dir.js";
3
4
  import { isProxyWithoutHooks } from "../../../compat/error-introspection.js";
@@ -5,8 +6,11 @@ import { isCanonicalNotFoundError } from "../../../compat/not-found-error.js";
5
6
  import { readBoundedFilePrefix, readFileWithinLimit, withFileHandle, } from "../../bounded-file-read.js";
6
7
  import { markNativeFileSystemAdapter } from "../../native-file-system-provenance.js";
7
8
  import { constants as nodeFsConstants } from "node:fs";
8
- import { isAbsolute, relative, resolve, sep } from "../../../compat/path/index.js";
9
- import { FileSnapshotChangedError } from "../../file-snapshot-error.js";
9
+ import { resolve } from "../../../compat/path/index.js";
10
+ import { runtimeUsesWindowsPaths } from "../../../compat/path/portable.js";
11
+ import { FileSnapshotChangedError, FileSnapshotPathError } from "../../file-snapshot-error.js";
12
+ import { hasUsableNativeFileIdentity, } from "./native-snapshot-identity.js";
13
+ import { isPathContainedBy } from "../../path-containment.js";
10
14
  const silentLogger = {
11
15
  error: () => { },
12
16
  debug: () => { },
@@ -56,10 +60,25 @@ const nodeFileSystemOperations = {
56
60
  function hasOwn(value, property) {
57
61
  return Object.prototype.hasOwnProperty.call(value, property);
58
62
  }
59
- function isContainedPath(path, root) {
60
- const relation = relative(root, path);
61
- return relation === "" ||
62
- (relation !== ".." && !relation.startsWith(`..${sep}`) && !isAbsolute(relation));
63
+ function detectNodeCompatibleRuntime() {
64
+ const runtime = dntShim.dntGlobalThis;
65
+ const versions = runtime.process?.versions;
66
+ if (typeof versions?.deno === "string" || runtime.Deno !== undefined)
67
+ return "deno";
68
+ if (typeof versions?.bun === "string" || runtime.Bun !== undefined)
69
+ return "bun";
70
+ if (runtime.process?.release?.name === "node" &&
71
+ typeof versions?.node === "string") {
72
+ return "node";
73
+ }
74
+ return "unknown";
75
+ }
76
+ export function hasUsableWindowsSnapshotIdentity(runtime) {
77
+ // Node exposes bigint file identity and generation fields on Windows. Each
78
+ // snapshot still validates that the native identity is present and usable.
79
+ // Bun and Deno do not currently document an equivalent contract, so their
80
+ // Windows adapters must fail closed.
81
+ return runtime === "node";
63
82
  }
64
83
  function requirePositiveSafeInteger(value) {
65
84
  if (!Number.isSafeInteger(value) || value <= 0) {
@@ -75,6 +94,11 @@ function sameGeneration(left, right) {
75
94
  left.mtimeNs === right.mtimeNs &&
76
95
  left.ctimeNs === right.ctimeNs;
77
96
  }
97
+ function requireUsableIdentity(stat, message) {
98
+ if (!hasUsableNativeFileIdentity(stat)) {
99
+ throw changed(message);
100
+ }
101
+ }
78
102
  function changed(message, cause) {
79
103
  const error = new FileSnapshotChangedError(message);
80
104
  if (cause !== undefined) {
@@ -108,24 +132,36 @@ function throwSnapshotChangeForPathRace(message, cause) {
108
132
  }
109
133
  throwSnapshotChangeForMissingPath(message, cause);
110
134
  }
111
- async function readNodeFileSnapshotWithinLimit(operations, noFollow, path, containmentRoot, byteLimit) {
135
+ export async function readNodeFileSnapshotWithinLimit(operations, platform, noFollow, path, containmentRoot, byteLimit) {
112
136
  requirePositiveSafeInteger(byteLimit);
137
+ let openFlags;
138
+ if (platform === "windows") {
139
+ openFlags = "r";
140
+ }
141
+ else {
142
+ if (typeof noFollow !== "number" || noFollow === 0) {
143
+ throw new TypeError("This runtime cannot guarantee no-follow snapshot opens");
144
+ }
145
+ openFlags = nodeFsConstants.O_RDONLY | noFollow;
146
+ }
113
147
  const lexicalRoot = resolve(containmentRoot);
114
148
  const candidate = resolve(path);
115
- if (!isContainedPath(candidate, lexicalRoot)) {
116
- throw new TypeError("Snapshot path must be contained by the requested root");
117
- }
118
149
  const canonicalRoot = await operations.realpath(lexicalRoot);
150
+ if (!isPathContainedBy(candidate, lexicalRoot) &&
151
+ !isPathContainedBy(candidate, canonicalRoot)) {
152
+ throw new FileSnapshotPathError("Snapshot path must be contained by the requested root");
153
+ }
119
154
  const pathnameBefore = await operations.lstat(candidate);
120
155
  if (pathnameBefore.isSymbolicLink()) {
121
- throw new TypeError("Snapshot path must not be a symbolic link");
156
+ throw new FileSnapshotPathError("Snapshot path must not be a symbolic link");
122
157
  }
123
158
  if (!pathnameBefore.isFile()) {
124
- throw new TypeError("Snapshot path must identify a regular file");
159
+ throw new FileSnapshotPathError("Snapshot path must identify a regular file");
125
160
  }
161
+ requireUsableIdentity(pathnameBefore, "Stable native file identity is unavailable for the snapshot path");
126
162
  return await withFileHandle(async () => {
127
163
  try {
128
- return await operations.open(candidate, nodeFsConstants.O_RDONLY | noFollow);
164
+ return await operations.open(candidate, openFlags);
129
165
  }
130
166
  catch (cause) {
131
167
  throwSnapshotChangeForPathRace("File identity became uncertain while opening the snapshot", cause);
@@ -138,6 +174,7 @@ async function readNodeFileSnapshotWithinLimit(operations, noFollow, path, conta
138
174
  catch (cause) {
139
175
  throwSnapshotChangeForMissingPath("Opened file identity could not be verified", cause);
140
176
  }
177
+ requireUsableIdentity(handleBefore, "Stable native file identity is unavailable for the opened snapshot");
141
178
  if (!handleBefore.isFile() || !sameGeneration(pathnameBefore, handleBefore)) {
142
179
  throw changed("File identity changed while opening the snapshot");
143
180
  }
@@ -157,8 +194,9 @@ async function readNodeFileSnapshotWithinLimit(operations, noFollow, path, conta
157
194
  !sameGeneration(handleBefore, pathnameOpened)) {
158
195
  throw changed("File identity changed while opening the snapshot");
159
196
  }
160
- if (!isContainedPath(canonicalTarget, canonicalRoot)) {
161
- throw new TypeError("Snapshot target must be contained by the canonical root");
197
+ requireUsableIdentity(pathnameOpened, "Stable native file identity is unavailable while verifying the snapshot");
198
+ if (!isPathContainedBy(canonicalTarget, canonicalRoot)) {
199
+ throw new FileSnapshotPathError("Snapshot target must be contained by the canonical root");
162
200
  }
163
201
  if (handleBefore.size < 0n) {
164
202
  throw changed("File size became uncertain while opening the snapshot");
@@ -200,12 +238,14 @@ async function readNodeFileSnapshotWithinLimit(operations, noFollow, path, conta
200
238
  catch (cause) {
201
239
  throwSnapshotChangeForPathRace("File identity became uncertain after reading the snapshot", cause);
202
240
  }
241
+ requireUsableIdentity(handleAfter, "Stable native file identity is unavailable after reading the snapshot");
242
+ requireUsableIdentity(pathnameAfter, "Stable native file identity is unavailable after reading the snapshot path");
203
243
  if (!pathnameAfter.isFile() ||
204
244
  pathnameAfter.isSymbolicLink() ||
205
245
  !sameGeneration(handleBefore, handleAfter) ||
206
246
  !sameGeneration(handleBefore, pathnameAfter) ||
207
247
  canonicalTargetAfter !== canonicalTarget ||
208
- !isContainedPath(canonicalTargetAfter, canonicalRoot)) {
248
+ !isPathContainedBy(canonicalTargetAfter, canonicalRoot)) {
209
249
  throw changed("File snapshot changed during the read");
210
250
  }
211
251
  return bytes;
@@ -227,9 +267,13 @@ export class NodeCompatibleFileSystemAdapter {
227
267
  ...options.operations,
228
268
  };
229
269
  const noFollow = hasOwn(options, "noFollow") ? options.noFollow : nodeFsConstants.O_NOFOLLOW;
230
- if (typeof noFollow === "number" && noFollow !== 0) {
270
+ const platform = options.platform ?? (runtimeUsesWindowsPaths() ? "windows" : "posix");
271
+ const canOpenExactSnapshot = platform === "windows"
272
+ ? hasUsableWindowsSnapshotIdentity(detectNodeCompatibleRuntime())
273
+ : typeof noFollow === "number" && noFollow !== 0;
274
+ if (canOpenExactSnapshot) {
231
275
  Object.defineProperty(this, "readFileSnapshotWithinLimit", {
232
- value: (path, containmentRoot, byteLimit) => readNodeFileSnapshotWithinLimit(operations, noFollow, path, containmentRoot, byteLimit),
276
+ value: (path, containmentRoot, byteLimit) => readNodeFileSnapshotWithinLimit(operations, platform, noFollow, path, containmentRoot, byteLimit),
233
277
  enumerable: true,
234
278
  });
235
279
  }
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Whether this runtime can distinguish Proxy values without evaluating a trap.
3
+ * Callers that need a fail-closed guarantee must not treat a `false` result
4
+ * from {@link isProxyWithoutHooks} as proof when this capability is absent.
5
+ */
6
+ export declare const canIdentifyProxyWithoutHooks: boolean;
1
7
  /** True when own stack descriptors can be inspected without formatting them. */
2
8
  export declare const canInspectErrorStackDescriptorWithoutHooks: boolean;
3
9
  /**
@@ -22,7 +28,12 @@ export declare function isNativeErrorWithoutHooks(value: unknown): value is Erro
22
28
  * prototype name or constructor name; unreadable/exotic shapes fail closed.
23
29
  */
24
30
  export declare function readNativeErrorNameWithoutHooks(error: Error): string;
25
- /** Identify a Proxy without evaluating any trap on the proxied value. */
31
+ /**
32
+ * Identify a Proxy without evaluating any trap on the proxied value.
33
+ *
34
+ * Returns `false` without inspecting `value` when
35
+ * {@link canIdentifyProxyWithoutHooks} is false.
36
+ */
26
37
  export declare function isProxyWithoutHooks(value: unknown): boolean;
27
38
  /** Identify a genuine Uint8Array without evaluating project-owned hooks. */
28
39
  export declare function isUint8ArrayWithoutHooks(value: unknown): value is Uint8Array;
@@ -1 +1 @@
1
- {"version":3,"file":"error-introspection.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/error-introspection.ts"],"names":[],"mappings":"AA2HA,gFAAgF;AAChF,eAAO,MAAM,0CAA0C,SAA0C,CAAC;AAgClG;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAuBjF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAExE;AA6BD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAkBpE;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED,4EAA4E;AAC5E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAE5E;AAED,gFAAgF;AAChF,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAE3B;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAgBnD"}
1
+ {"version":3,"file":"error-introspection.d.ts","sourceRoot":"","sources":["../../../../src/src/platform/compat/error-introspection.ts"],"names":[],"mappings":"AA0DA;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,SAAkC,CAAC;AA8F5E,gFAAgF;AAChF,eAAO,MAAM,0CAA0C,SAA0C,CAAC;AAgClG;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAuBjF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAExE;AA6BD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAkBpE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE3D;AAED,4EAA4E;AAC5E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAE5E;AAED,gFAAgF;AAChF,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAE3B;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAgBnD"}
@@ -16,15 +16,45 @@ const apply = Reflect.apply;
16
16
  const NativeError = Error;
17
17
  const NativeAsyncFunctionPrototype = getPrototypeOf(async function () { });
18
18
  const toStringTagSymbol = Symbol.toStringTag;
19
+ function hasOwn(object, key) {
20
+ return apply(objectHasOwnProperty, object, [key]);
21
+ }
22
+ /**
23
+ * Capture the portable Error brand primitive during trusted framework
24
+ * bootstrap, before tenant code can replace mutable globals. Edge runtimes do
25
+ * not expose an immutable host-module equivalent, so this capture boundary is
26
+ * the authority for later no-hook Error checks.
27
+ */
28
+ function captureErrorIsError() {
29
+ const descriptor = getOwnPropertyDescriptor(NativeError, "isError");
30
+ return descriptor && hasOwn(descriptor, "value") &&
31
+ typeof descriptor.value === "function"
32
+ ? descriptor.value
33
+ : undefined;
34
+ }
35
+ const capturedErrorIsError = captureErrorIsError();
19
36
  const unavailableBrandCheck = (_value) => false;
37
+ function portableErrorBrandCheck(value) {
38
+ if (!capturedErrorIsError)
39
+ return false;
40
+ try {
41
+ return apply(capturedErrorIsError, NativeError, [value]) === true;
42
+ }
43
+ catch (_) {
44
+ return false;
45
+ }
46
+ }
20
47
  const nativeAsyncFunctionBrandCheck = nativeBrandChecks?.isAsyncFunction ?? unavailableBrandCheck;
21
- const nativeErrorBrandCheck = nativeBrandChecks?.isNativeError ?? unavailableBrandCheck;
48
+ const nativeErrorBrandCheck = nativeBrandChecks?.isNativeError ?? portableErrorBrandCheck;
22
49
  const nativePromiseBrandCheck = nativeBrandChecks?.isPromise ?? unavailableBrandCheck;
23
50
  const nativeProxyBrandCheck = nativeBrandChecks?.isProxy ?? unavailableBrandCheck;
24
51
  const nativeUint8ArrayBrandCheck = nativeBrandChecks?.isUint8Array ?? unavailableBrandCheck;
25
- function hasOwn(object, key) {
26
- return apply(objectHasOwnProperty, object, [key]);
27
- }
52
+ /**
53
+ * Whether this runtime can distinguish Proxy values without evaluating a trap.
54
+ * Callers that need a fail-closed guarantee must not treat a `false` result
55
+ * from {@link isProxyWithoutHooks} as proof when this capability is absent.
56
+ */
57
+ export const canIdentifyProxyWithoutHooks = nativeBrandChecks !== undefined;
28
58
  function createDataDescriptor(value) {
29
59
  const descriptor = createObject(null);
30
60
  descriptor.configurable = true;
@@ -219,7 +249,12 @@ export function readNativeErrorNameWithoutHooks(error) {
219
249
  return "Error";
220
250
  }
221
251
  }
222
- /** Identify a Proxy without evaluating any trap on the proxied value. */
252
+ /**
253
+ * Identify a Proxy without evaluating any trap on the proxied value.
254
+ *
255
+ * Returns `false` without inspecting `value` when
256
+ * {@link canIdentifyProxyWithoutHooks} is false.
257
+ */
223
258
  export function isProxyWithoutHooks(value) {
224
259
  return nativeProxyBrandCheck(value);
225
260
  }
@@ -1 +1 @@
1
- {"version":3,"file":"basic-operations.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/basic-operations.ts"],"names":[],"mappings":"AAgBA,yEAAyE;AACzE,wBAAgB,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAQ/C;AAED,wCAAwC;AACxC,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED,oCAAoC;AACpC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5C"}
1
+ {"version":3,"file":"basic-operations.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/basic-operations.ts"],"names":[],"mappings":"AAqBA,yEAAyE;AACzE,wBAAgB,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAU/C;AAED,wCAAwC;AACxC,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED,oCAAoC;AACpC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,4CAA4C;AAC5C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5C"}
@@ -1,11 +1,15 @@
1
1
  import { hasWindowsLikePath, portableBasename, portableDirname, portableExtname, portableJoin, removeTrailingSeparatorsExceptRoot, runtimeUsesWindowsPaths, toPortableSeparators, } from "./portable.js";
2
2
  import { getNativePathImplementation } from "./runtime.js";
3
+ const ArrayPrototypeEvery = Array.prototype.every;
4
+ const ArrayPrototypeSome = Array.prototype.some;
5
+ const ReflectApply = Reflect.apply;
3
6
  function usesWindowsFlavor(paths) {
4
- return runtimeUsesWindowsPaths() || paths.some(hasWindowsLikePath);
7
+ return runtimeUsesWindowsPaths() ||
8
+ ReflectApply(ArrayPrototypeSome, paths, [hasWindowsLikePath]);
5
9
  }
6
10
  /** Join and normalize path segments using their detected path flavor. */
7
11
  export function join(...paths) {
8
- if (paths.every((path) => path.length === 0))
12
+ if (ReflectApply(ArrayPrototypeEvery, paths, [(path) => path.length === 0]))
9
13
  return "/";
10
14
  const windows = usesWindowsFlavor(paths);
11
15
  const pathApi = getNativePathImplementation(windows);
@@ -1 +1 @@
1
- {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/portable.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAS7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAmFD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,MAAM,CAUR;AAOD,wBAAgB,uBAAuB,IAAI,OAAO,CASjD;AAyBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAkBxE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAI/E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAqBtE;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,OAAO,GACf,MAAM,CAuCR;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAKtE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAE1E;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,OAAO,GACf,MAAM,CAiCR;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,GACf,MAAM,CA2BR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,CAiCxE;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,GACf,MAAM,CAeR"}
1
+ {"version":3,"file":"portable.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/portable.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAoD7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AA2FD,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,MAAM,CAUR;AAOD,wBAAgB,uBAAuB,IAAI,OAAO,CASjD;AAyBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAkBxE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAI/E;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAqBtE;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,OAAO,GACf,MAAM,CAuCR;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAKtE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAE1E;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,OAAO,GACf,MAAM,CAkCR;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,GACf,MAAM,CAiCR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU,CAiCxE;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,OAAO,GACf,MAAM,CAeR"}
@@ -1,15 +1,44 @@
1
1
  import * as dntShim from "../../../../_dnt.shims.js";
2
+ import { primordialArrayAt as arrayAt, primordialArrayFilter as arrayFilter, primordialArrayJoin as arrayJoin, primordialArrayPop as arrayPop, primordialArrayPush as arrayPush, } from "../primordials/array.js";
3
+ const apply = Reflect.apply;
4
+ const arraySlice = Array.prototype.slice;
5
+ const regExpExec = RegExp.prototype.exec;
6
+ const stringEndsWith = String.prototype.endsWith;
7
+ const stringIncludes = String.prototype.includes;
8
+ const stringLastIndexOf = String.prototype.lastIndexOf;
9
+ const stringReplaceAll = String.prototype.replaceAll;
10
+ const stringSlice = String.prototype.slice;
11
+ const stringSplit = String.prototype.split;
12
+ const stringStartsWith = String.prototype.startsWith;
13
+ const stringToLowerCase = String.prototype.toLowerCase;
14
+ function includes(value, search) {
15
+ return apply(stringIncludes, value, [search]);
16
+ }
17
+ function startsWith(value, search) {
18
+ return apply(stringStartsWith, value, [search]);
19
+ }
20
+ function endsWith(value, search) {
21
+ return apply(stringEndsWith, value, [search]);
22
+ }
23
+ function slice(value, start, end) {
24
+ return apply(stringSlice, value, end === undefined ? [start] : [start, end]);
25
+ }
26
+ function lastIndexOf(value, search) {
27
+ return apply(stringLastIndexOf, value, [search]);
28
+ }
29
+ function matches(pattern, value) {
30
+ return apply(regExpExec, pattern, [value]);
31
+ }
2
32
  export function hasWindowsLikePath(path) {
3
- return path.includes("\\") ||
4
- /^[A-Za-z]:/.test(path);
33
+ return includes(path, "\\") || matches(/^[A-Za-z]:/, path) !== null;
5
34
  }
6
35
  export function toPortableSeparators(path) {
7
- return path.replaceAll("\\", "/");
36
+ return apply(stringReplaceAll, path, ["\\", "/"]);
8
37
  }
9
38
  function analyzeRoot(path, windows) {
10
39
  const portable = toPortableSeparators(path);
11
40
  if (windows) {
12
- const unc = portable.match(/^\/\/([^/]+)\/+([^/]+)(\/+(.*))?$/);
41
+ const unc = matches(/^\/\/([^/]+)\/+([^/]+)(\/+(.*))?$/, portable);
13
42
  if (unc?.[1] && unc[2]) {
14
43
  const device = `//${unc[1]}/${unc[2]}`;
15
44
  return {
@@ -19,7 +48,7 @@ function analyzeRoot(path, windows) {
19
48
  root: unc[3] === undefined ? device : `${device}/`,
20
49
  };
21
50
  }
22
- const drive = portable.match(/^([A-Za-z]:)(\/+)?(.*)$/);
51
+ const drive = matches(/^([A-Za-z]:)(\/+)?(.*)$/, portable);
23
52
  if (drive?.[1] !== undefined) {
24
53
  const absolute = drive[2] !== undefined;
25
54
  return {
@@ -30,11 +59,14 @@ function analyzeRoot(path, windows) {
30
59
  };
31
60
  }
32
61
  }
33
- if (portable.startsWith("/")) {
62
+ if (startsWith(portable, "/")) {
63
+ let restStart = 0;
64
+ while (portable[restStart] === "/")
65
+ restStart++;
34
66
  return {
35
67
  absolute: true,
36
68
  device: "",
37
- rest: portable.replace(/^\/+/, ""),
69
+ rest: slice(portable, restStart),
38
70
  root: "/",
39
71
  };
40
72
  }
@@ -51,25 +83,30 @@ function appendRoot(root, tail) {
51
83
  if (!root.absolute)
52
84
  return `${root.root}${tail || "."}`;
53
85
  if (!tail) {
54
- return root.device.startsWith("//") ? `${root.device}/` : root.root;
86
+ return startsWith(root.device, "//") ? `${root.device}/` : root.root;
55
87
  }
56
- return root.root.endsWith("/") ? `${root.root}${tail}` : `${root.root}/${tail}`;
88
+ return endsWith(root.root, "/") ? `${root.root}${tail}` : `${root.root}/${tail}`;
57
89
  }
58
90
  function normalizeTail(rest, absolute) {
59
91
  const normalized = [];
60
- for (const segment of rest.split("/")) {
92
+ const segments = apply(stringSplit, rest, ["/"]);
93
+ // Path normalization is reached by shared-runtime coordination after tenant
94
+ // code has loaded. Avoid the live Array iterator so post-import prototype
95
+ // mutation cannot turn canonical lockfile lookup into a process-wide outage.
96
+ for (let index = 0; index < segments.length; index++) {
97
+ const segment = segments[index];
61
98
  if (segment === "" || segment === ".")
62
99
  continue;
63
100
  if (segment !== "..") {
64
- normalized.push(segment);
101
+ arrayPush(normalized, segment);
65
102
  continue;
66
103
  }
67
- const previous = normalized.at(-1);
104
+ const previous = arrayAt(normalized, -1);
68
105
  if (previous !== undefined && previous !== "..") {
69
- normalized.pop();
106
+ arrayPop(normalized);
70
107
  }
71
108
  else if (!absolute) {
72
- normalized.push("..");
109
+ arrayPush(normalized, "..");
73
110
  }
74
111
  }
75
112
  return normalized;
@@ -80,15 +117,15 @@ function canonicalPath(path, windows) {
80
117
  export function removeTrailingSeparatorsExceptRoot(path, windows) {
81
118
  const root = analyzeRoot(path, windows);
82
119
  let canonical = canonicalPath(path, windows);
83
- while (canonical.endsWith("/") &&
120
+ while (endsWith(canonical, "/") &&
84
121
  canonical.length > root.root.length) {
85
- canonical = canonical.slice(0, -1);
122
+ canonical = slice(canonical, 0, -1);
86
123
  }
87
124
  return canonical;
88
125
  }
89
126
  function rootKey(root, windows) {
90
127
  const value = root.device || root.root;
91
- return windows ? value.toLowerCase() : value;
128
+ return windows ? apply(stringToLowerCase, value, []) : value;
92
129
  }
93
130
  export function runtimeUsesWindowsPaths() {
94
131
  const runtime = dntShim.dntGlobalThis;
@@ -121,44 +158,44 @@ export function portableNormalize(path, windows) {
121
158
  if (path === "")
122
159
  return ".";
123
160
  const root = analyzeRoot(path, windows);
124
- const tail = normalizeTail(root.rest, root.absolute).join("/");
161
+ const tail = arrayJoin(normalizeTail(root.rest, root.absolute), "/");
125
162
  let result = appendRoot(root, tail);
126
- const hadTrailingSeparator = /[\\/]$/.test(path);
163
+ const hadTrailingSeparator = matches(/[\\/]$/, path) !== null;
127
164
  if (hadTrailingSeparator && result === ".")
128
165
  return "./";
129
166
  if (hadTrailingSeparator &&
130
167
  result !== root.root &&
131
- !result.endsWith("/")) {
168
+ !endsWith(result, "/")) {
132
169
  result += "/";
133
170
  }
134
171
  return result;
135
172
  }
136
173
  export function portableJoin(paths, windows) {
137
- const nonempty = paths.filter((path) => path.length > 0);
174
+ const nonempty = arrayFilter(paths, (path) => path.length > 0);
138
175
  if (nonempty.length === 0)
139
176
  return "/";
140
- return portableNormalize(nonempty.join("/"), windows);
177
+ return portableNormalize(arrayJoin(nonempty, "/"), windows);
141
178
  }
142
179
  export function portableDirname(path, windows) {
143
180
  if (path.length === 0)
144
181
  return ".";
145
182
  const root = analyzeRoot(path, windows);
146
183
  let canonical = canonicalPath(path, windows);
147
- while (canonical.endsWith("/") &&
184
+ while (endsWith(canonical, "/") &&
148
185
  canonical.length > root.root.length) {
149
- canonical = canonical.slice(0, -1);
186
+ canonical = slice(canonical, 0, -1);
150
187
  }
151
188
  if (canonical === root.root || canonical === root.device) {
152
189
  return root.root || root.device || ".";
153
190
  }
154
- const lastSeparator = canonical.lastIndexOf("/");
191
+ const lastSeparator = lastIndexOf(canonical, "/");
155
192
  if (lastSeparator === -1)
156
193
  return root.device || ".";
157
194
  if (lastSeparator < root.root.length)
158
195
  return root.root || "/";
159
196
  if (lastSeparator === 0)
160
197
  return "/";
161
- return canonical.slice(0, lastSeparator);
198
+ return slice(canonical, 0, lastSeparator);
162
199
  }
163
200
  export function portableBasename(path, ext, windows) {
164
201
  if (path.length === 0)
@@ -168,44 +205,45 @@ export function portableBasename(path, ext, windows) {
168
205
  const originalPath = canonical;
169
206
  if (ext !== undefined && ext !== "" && ext === originalPath)
170
207
  return "";
171
- while (canonical.endsWith("/") &&
208
+ while (endsWith(canonical, "/") &&
172
209
  canonical.length > root.root.length) {
173
- canonical = canonical.slice(0, -1);
210
+ canonical = slice(canonical, 0, -1);
174
211
  }
175
212
  if (windows &&
176
- root.device.startsWith("//") &&
213
+ startsWith(root.device, "//") &&
177
214
  root.rest === "") {
178
- return root.device.slice(root.device.lastIndexOf("/") + 1);
215
+ return slice(root.device, lastIndexOf(root.device, "/") + 1);
179
216
  }
180
217
  if (canonical === root.root || canonical === root.device)
181
218
  return "";
182
- const lastSeparator = canonical.lastIndexOf("/");
183
- let base = canonical.slice(lastSeparator + 1);
219
+ const lastSeparator = lastIndexOf(canonical, "/");
220
+ let base = slice(canonical, lastSeparator + 1);
184
221
  if (!root.absolute &&
185
222
  root.device &&
186
223
  lastSeparator === -1 &&
187
- base.startsWith(root.device)) {
188
- base = base.slice(root.device.length);
224
+ startsWith(base, root.device)) {
225
+ base = slice(base, root.device.length);
189
226
  }
190
- if (ext !== undefined && ext !== "" && base.endsWith(ext)) {
227
+ if (ext !== undefined && ext !== "" && endsWith(base, ext)) {
191
228
  if (ext.length < base.length)
192
- return base.slice(0, -ext.length);
229
+ return slice(base, 0, -ext.length);
193
230
  }
194
231
  return base;
195
232
  }
196
233
  export function portableExtname(path, windows) {
197
234
  const base = portableBasename(path, undefined, windows);
198
- const lastDot = base.lastIndexOf(".");
235
+ const lastDot = lastIndexOf(base, ".");
199
236
  if (lastDot <= 0 || base === "." || base === "..")
200
237
  return "";
201
- return base.slice(lastDot);
238
+ return slice(base, lastDot);
202
239
  }
203
240
  export function portableIsAbsolute(path, windows) {
204
241
  return analyzeRoot(path, windows).absolute;
205
242
  }
206
243
  export function portableResolve(paths, windows) {
207
244
  let resolved = runtimeCwd();
208
- for (const rawPath of paths) {
245
+ for (let index = 0; index < paths.length; index++) {
246
+ const rawPath = paths[index];
209
247
  if (rawPath.length === 0)
210
248
  continue;
211
249
  const path = toPortableSeparators(rawPath);
@@ -228,10 +266,10 @@ export function portableResolve(paths, windows) {
228
266
  }
229
267
  const normalized = portableNormalize(resolved, windows);
230
268
  const root = analyzeRoot(normalized, windows);
231
- if (normalized.endsWith("/") &&
269
+ if (endsWith(normalized, "/") &&
232
270
  normalized !== root.root &&
233
271
  normalized !== `${root.device}/`) {
234
- return normalized.slice(0, -1);
272
+ return slice(normalized, 0, -1);
235
273
  }
236
274
  return normalized;
237
275
  }
@@ -249,34 +287,40 @@ export function portableRelative(from, to, windows) {
249
287
  while (common < fromParts.length && common < toParts.length) {
250
288
  const fromPart = fromParts[common];
251
289
  const toPart = toParts[common];
252
- const equal = windows ? fromPart.toLowerCase() === toPart.toLowerCase() : fromPart === toPart;
290
+ const equal = windows
291
+ ? apply(stringToLowerCase, fromPart, []) === apply(stringToLowerCase, toPart, [])
292
+ : fromPart === toPart;
253
293
  if (!equal)
254
294
  break;
255
295
  common++;
256
296
  }
257
- const result = [
258
- ...Array.from({ length: fromParts.length - common }, () => ".."),
259
- ...toParts.slice(common),
260
- ];
261
- return result.join("/") || ".";
297
+ const result = [];
298
+ for (let index = common; index < fromParts.length; index++) {
299
+ arrayPush(result, "..");
300
+ }
301
+ const remainingToParts = apply(arraySlice, toParts, [common]);
302
+ for (let index = 0; index < remainingToParts.length; index++) {
303
+ arrayPush(result, remainingToParts[index]);
304
+ }
305
+ return arrayJoin(result, "/") || ".";
262
306
  }
263
307
  export function portableParse(path, windows) {
264
308
  const root = analyzeRoot(path, windows);
265
309
  let canonical = canonicalPath(path, windows);
266
- while (canonical.endsWith("/") &&
310
+ while (endsWith(canonical, "/") &&
267
311
  canonical.length > root.root.length) {
268
- canonical = canonical.slice(0, -1);
312
+ canonical = slice(canonical, 0, -1);
269
313
  }
270
- const base = windows && root.device.startsWith("//") && root.rest === ""
314
+ const base = windows && startsWith(root.device, "//") && root.rest === ""
271
315
  ? ""
272
316
  : portableBasename(canonical, undefined, windows);
273
317
  const ext = portableExtname(base, windows);
274
- const name = base.slice(0, base.length - ext.length);
318
+ const name = slice(base, 0, base.length - ext.length);
275
319
  let dir = "";
276
320
  if (base === "") {
277
321
  dir = root.root;
278
322
  }
279
- else if (canonical.includes("/") ||
323
+ else if (includes(canonical, "/") ||
280
324
  (windows && root.device !== "")) {
281
325
  dir = portableDirname(canonical, windows);
282
326
  }
@@ -292,7 +336,7 @@ export function portableFormat(pathObject, windows) {
292
336
  const root = toPortableSeparators(pathObject.root ?? "");
293
337
  const dir = toPortableSeparators(pathObject.dir ?? "");
294
338
  const rawExt = pathObject.ext ?? "";
295
- const ext = rawExt && !rawExt.startsWith(".") ? `.${rawExt}` : rawExt;
339
+ const ext = rawExt && !startsWith(rawExt, ".") ? `.${rawExt}` : rawExt;
296
340
  const base = pathObject.base ||
297
341
  `${pathObject.name ?? ""}${ext}`;
298
342
  const directory = dir || root;
@@ -300,7 +344,7 @@ export function portableFormat(pathObject, windows) {
300
344
  return base;
301
345
  if (!base)
302
346
  return directory;
303
- if (directory.endsWith("/") || (windows && /^[A-Za-z]:$/.test(directory))) {
347
+ if (endsWith(directory, "/") || (windows && matches(/^[A-Za-z]:$/, directory) !== null)) {
304
348
  return `${directory}${base}`;
305
349
  }
306
350
  return `${directory}/${base}`;
@@ -1 +1 @@
1
- {"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/resolution.ts"],"names":[],"mappings":"AAgBA,6DAA6D;AAC7D,wBAAgB,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAMlD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIhD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW9C"}
1
+ {"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/path/resolution.ts"],"names":[],"mappings":"AAsBA,6DAA6D;AAC7D,wBAAgB,OAAO,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAMlD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMhD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAW9C"}