@aigne/afs-fs 1.11.0-beta.11 → 1.11.0-beta.12

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/index.cjs CHANGED
@@ -9,6 +9,7 @@ let node_os = require("node:os");
9
9
  let node_path = require("node:path");
10
10
  let _aigne_afs = require("@aigne/afs");
11
11
  let _aigne_afs_utils_zod = require("@aigne/afs/utils/zod");
12
+ let _aigne_afs_provider_utils = require("@aigne/afs-provider-utils");
12
13
  let ignore = require("ignore");
13
14
  ignore = require_rolldown_runtime.__toESM(ignore);
14
15
  let js_yaml = require("js-yaml");
@@ -53,7 +54,49 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
53
54
  uriTemplate: "fs://{localPath+}",
54
55
  category: "storage",
55
56
  schema: zod.z.object({ localPath: zod.z.string() }),
56
- tags: ["local", "filesystem"]
57
+ tags: ["local", "filesystem"],
58
+ capabilityTags: [
59
+ "read-write",
60
+ "crud",
61
+ "search",
62
+ "auth:none",
63
+ "local"
64
+ ],
65
+ security: {
66
+ riskLevel: "local",
67
+ resourceAccess: ["local-filesystem"],
68
+ dataSensitivity: ["code"],
69
+ notes: ["Exposes a local directory — scope is limited to the configured localPath"]
70
+ },
71
+ capabilities: { filesystem: {
72
+ read: true,
73
+ write: true,
74
+ allowedPaths: ["${localPath}/**"]
75
+ } }
76
+ };
77
+ }
78
+ static treeSchema() {
79
+ return {
80
+ operations: [
81
+ "list",
82
+ "read",
83
+ "write",
84
+ "delete",
85
+ "search",
86
+ "stat",
87
+ "explain"
88
+ ],
89
+ tree: {
90
+ "/": { kind: "fs:directory" },
91
+ "/{path}": { kind: "fs:file" }
92
+ },
93
+ auth: { type: "none" },
94
+ bestFor: [
95
+ "local file access",
96
+ "project source code",
97
+ "config files"
98
+ ],
99
+ notFor: ["remote storage", "large binary files"]
57
100
  };
58
101
  }
59
102
  static async load({ basePath, config } = {}) {
@@ -69,14 +112,7 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
69
112
  super();
70
113
  this.options = options;
71
114
  (0, _aigne_afs_utils_zod.zodParse)(afsFSOptionsSchema, options);
72
- let localPath;
73
- if (options.localPath === ".") localPath = process.cwd();
74
- else {
75
- localPath = options.localPath.replaceAll("${CWD}", process.cwd());
76
- if (localPath.startsWith("~/")) localPath = (0, node_path.join)(process.env.HOME || "", localPath.slice(2));
77
- if (!(0, node_path.isAbsolute)(localPath)) localPath = (0, node_path.join)(options.cwd || process.cwd(), localPath);
78
- }
79
- if (!(0, node_fs.existsSync)(localPath)) (0, node_fs.mkdirSync)(localPath, { recursive: true });
115
+ const localPath = (0, _aigne_afs_provider_utils.resolveLocalPath)(options.localPath, { cwd: options.cwd });
80
116
  this.name = options.name || (0, node_path.basename)(localPath) || "fs";
81
117
  this.description = options.description;
82
118
  this.agentSkills = options.agentSkills;
@@ -86,62 +122,51 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
86
122
  this.useAfsignore = options.useAfsignore ?? true;
87
123
  }
88
124
  agentSkills;
125
+ afsRoot;
126
+ onMount(afs) {
127
+ this.afsRoot = afs;
128
+ this.scanAshScripts().catch(() => {});
129
+ }
130
+ /** Recursively scan for .ash files and emit script:registered events */
131
+ async scanAshScripts(dir) {
132
+ const scanDir = dir ?? this.options.localPath;
133
+ let items;
134
+ try {
135
+ items = await (0, node_fs_promises.readdir)(scanDir);
136
+ } catch {
137
+ return;
138
+ }
139
+ for (const item of items) {
140
+ if (this.isHiddenAfsDir(item)) continue;
141
+ const fullPath = (0, node_path.join)(scanDir, item);
142
+ try {
143
+ if ((await (0, node_fs_promises.stat)(fullPath)).isDirectory()) await this.scanAshScripts(fullPath);
144
+ else if (item.endsWith(".ash")) {
145
+ const relPath = (0, node_path.join)("/", (0, node_path.relative)(this.options.localPath, fullPath));
146
+ this.emit({
147
+ type: "script:registered",
148
+ path: relPath,
149
+ data: { runtime: "ash" }
150
+ });
151
+ }
152
+ } catch {}
153
+ }
154
+ }
155
+ async ready() {
156
+ const { localPath } = this.options;
157
+ if (!(0, node_fs.existsSync)(localPath)) (0, node_fs.mkdirSync)(localPath, { recursive: true });
158
+ }
89
159
  /** Whether to apply .gitignore rules (default: false) */
90
160
  useGitignore;
91
161
  /** Whether to apply .afsignore rules (default: true) */
92
162
  useAfsignore;
163
+ async assertWithinMount(fullPath) {
164
+ return (0, _aigne_afs_provider_utils.assertPathWithinRoot)(fullPath, this.options.localPath);
165
+ }
93
166
  get localPathExists() {
94
167
  return (0, node_fs_promises.stat)(this.options.localPath).then(() => true).catch(() => false);
95
168
  }
96
169
  /**
97
- * Detect MIME type based on file extension
98
- */
99
- getMimeType(filePath) {
100
- return {
101
- png: "image/png",
102
- jpg: "image/jpeg",
103
- jpeg: "image/jpeg",
104
- gif: "image/gif",
105
- bmp: "image/bmp",
106
- webp: "image/webp",
107
- svg: "image/svg+xml",
108
- ico: "image/x-icon",
109
- pdf: "application/pdf",
110
- txt: "text/plain",
111
- md: "text/markdown",
112
- js: "text/javascript",
113
- ts: "text/typescript",
114
- json: "application/json",
115
- html: "text/html",
116
- css: "text/css",
117
- xml: "text/xml"
118
- }[(0, node_path.basename)(filePath).split(".").pop()?.toLowerCase() || ""] || "application/octet-stream";
119
- }
120
- /**
121
- * Check if file is likely binary based on extension
122
- */
123
- isBinaryFile(filePath) {
124
- const ext = (0, node_path.basename)(filePath).split(".").pop()?.toLowerCase();
125
- return [
126
- "png",
127
- "jpg",
128
- "jpeg",
129
- "gif",
130
- "bmp",
131
- "webp",
132
- "ico",
133
- "pdf",
134
- "zip",
135
- "tar",
136
- "gz",
137
- "exe",
138
- "dll",
139
- "so",
140
- "dylib",
141
- "wasm"
142
- ].includes(ext || "");
143
- }
144
- /**
145
170
  * Check if a segment is the hidden .afs directory
146
171
  */
147
172
  isHiddenAfsDir(segment) {
@@ -272,7 +297,7 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
272
297
  for (const childName of itemsToProcess) {
273
298
  if (entries.length >= limit) break;
274
299
  const childFullPath = (0, node_path.join)(fullPath, childName);
275
- const childRelativePath = (0, node_path.join)(path, childName);
300
+ const childRelativePath = (0, ufo.joinURL)(path, childName);
276
301
  const itemRelativePath = (0, node_path.relative)(ignoreBase, childFullPath);
277
302
  let isIgnored = false;
278
303
  if (this.isIgnoredByMountPatterns(itemRelativePath, mountIgnorePatterns)) isIgnored = true;
@@ -306,7 +331,7 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
306
331
  size: childStats.size,
307
332
  kind: nodeMeta?.kind ?? (childIsDirectory ? "fs:directory" : "fs:file")
308
333
  };
309
- if (!childIsDirectory) meta.mimeType = this.getMimeType(childFullPath);
334
+ if (!childIsDirectory) meta.mimeType = (0, _aigne_afs_provider_utils.getMimeType)(childFullPath);
310
335
  const entry = {
311
336
  id: childRelativePath,
312
337
  path: childRelativePath,
@@ -336,6 +361,7 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
336
361
  stats = mountStats;
337
362
  } else {
338
363
  fullPath = (0, node_path.join)(mountRoot, path);
364
+ await this.assertWithinMount(fullPath);
339
365
  stats = await (0, node_fs_promises.stat)(fullPath);
340
366
  }
341
367
  } catch (error) {
@@ -350,8 +376,8 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
350
376
  };
351
377
  if (stats.isDirectory()) meta.childrenCount = (await (0, node_fs_promises.readdir)(fullPath)).filter((c) => !this.isHiddenAfsDir(c)).length;
352
378
  else if (stats.isFile()) {
353
- const mimeType = this.getMimeType(fullPath);
354
- const isBinary = this.isBinaryFile(fullPath);
379
+ const mimeType = (0, _aigne_afs_provider_utils.getMimeType)(fullPath);
380
+ const isBinary = (0, _aigne_afs_provider_utils.isBinaryFile)(fullPath);
355
381
  meta.mimeType = mimeType;
356
382
  if (isBinary) {
357
383
  content = (await (0, node_fs_promises.readFile)(fullPath)).toString("base64");
@@ -372,7 +398,8 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
372
398
  const normalizedPath = (0, node_path.join)("/", path);
373
399
  const options = ctx.options;
374
400
  const fullPath = (0, node_path.join)(this.options.localPath, path);
375
- const append = options?.append ?? false;
401
+ await this.assertWithinMount(fullPath);
402
+ const mode = options?.mode ?? "replace";
376
403
  await (0, node_fs_promises.mkdir)((0, node_path.dirname)(fullPath), { recursive: true });
377
404
  if (entry.content !== void 0) {
378
405
  let contentToWrite;
@@ -380,7 +407,7 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
380
407
  else contentToWrite = JSON.stringify(entry.content, null, 2);
381
408
  await (0, node_fs_promises.writeFile)(fullPath, contentToWrite, {
382
409
  encoding: "utf8",
383
- flag: append ? "a" : "w"
410
+ flag: mode === "append" ? "a" : "w"
384
411
  });
385
412
  }
386
413
  if (entry.meta && Object.keys(entry.meta).length > 0) {
@@ -394,7 +421,7 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
394
421
  ...meta,
395
422
  size: stats.size
396
423
  };
397
- return { data: {
424
+ const writtenEntry = {
398
425
  id: normalizedPath,
399
426
  path: normalizedPath,
400
427
  createdAt: stats.birthtime,
@@ -405,13 +432,20 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
405
432
  userId: entry.userId,
406
433
  sessionId: entry.sessionId,
407
434
  linkTo: entry.linkTo
408
- } };
435
+ };
436
+ if (normalizedPath.endsWith(".ash")) this.emit({
437
+ type: "script:registered",
438
+ path: normalizedPath,
439
+ data: { runtime: "ash" }
440
+ });
441
+ return { data: writtenEntry };
409
442
  }
410
443
  async deleteHandler(ctx) {
411
444
  const path = ctx.path;
412
445
  const displayPath = path === "/" ? "/" : path.slice(1);
413
446
  const options = ctx.options;
414
447
  const fullPath = (0, node_path.join)(this.options.localPath, path);
448
+ await this.assertWithinMount(fullPath);
415
449
  const recursive = options?.recursive ?? false;
416
450
  let stats;
417
451
  try {
@@ -420,10 +454,19 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
420
454
  wrapNotFoundError(error, path);
421
455
  }
422
456
  if (stats.isDirectory() && !recursive) throw new Error(`Cannot delete directory '${displayPath}' without recursive option. Set recursive: true to delete directories.`);
457
+ const isAshScript = !stats.isDirectory() && path.endsWith(".ash");
423
458
  await (0, node_fs_promises.rm)(fullPath, {
424
459
  recursive,
425
460
  force: true
426
461
  });
462
+ if (isAshScript) {
463
+ const normalizedPath = (0, node_path.join)("/", path);
464
+ this.emit({
465
+ type: "script:unregistered",
466
+ path: normalizedPath,
467
+ data: { runtime: "ash" }
468
+ });
469
+ }
427
470
  return { message: `Successfully deleted: ${displayPath}` };
428
471
  }
429
472
  async renameHandler(ctx, newPath) {
@@ -432,6 +475,8 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
432
475
  const overwrite = ctx.options?.overwrite ?? false;
433
476
  const oldFullPath = (0, node_path.join)(this.options.localPath, oldPath);
434
477
  const newFullPath = (0, node_path.join)(this.options.localPath, newPath);
478
+ await this.assertWithinMount(oldFullPath);
479
+ await this.assertWithinMount(newFullPath);
435
480
  try {
436
481
  await (0, node_fs_promises.stat)(oldFullPath);
437
482
  } catch (error) {
@@ -466,7 +511,7 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
466
511
  let hasMoreFiles = false;
467
512
  for (const match of matches) if (match.type === "match" && match.data.path) {
468
513
  const absolutePath = match.data.path.text;
469
- const itemRelativePath = (0, node_path.join)(path, (0, node_path.relative)(basePath, absolutePath));
514
+ const itemRelativePath = (0, ufo.joinURL)(path, (0, node_path.relative)(basePath, absolutePath));
470
515
  const pathFromRoot = (0, node_path.relative)(mountRoot, absolutePath);
471
516
  if (this.isIgnoredByMountPatterns(pathFromRoot, mountIgnorePatterns)) continue;
472
517
  if (ig && (ig.ignores(pathFromRoot) || ig.ignores(`${pathFromRoot}/`))) continue;
@@ -807,6 +852,57 @@ var AFSFS = class AFSFS extends _aigne_afs.AFSBaseProvider {
807
852
  };
808
853
  }
809
854
  }
855
+ async execHandler(ctx, args) {
856
+ const path = ctx.path;
857
+ if (path.includes("/.actions/")) throw new Error(`No actions available for path: ${path}`);
858
+ if (!path.endsWith(".ash")) return {
859
+ success: false,
860
+ error: {
861
+ code: "UNSUPPORTED",
862
+ message: `Exec not supported for non-.ash files: ${path}`
863
+ }
864
+ };
865
+ const fullPath = (0, node_path.join)(this.options.localPath, path);
866
+ await this.assertWithinMount(fullPath);
867
+ let source;
868
+ try {
869
+ source = await (0, node_fs_promises.readFile)(fullPath, "utf-8");
870
+ } catch (error) {
871
+ wrapNotFoundError(error, path);
872
+ }
873
+ const afs = this.afsRoot;
874
+ if (!afs?.exec) return {
875
+ success: false,
876
+ error: {
877
+ code: "ASH_UNAVAILABLE",
878
+ message: "ASH provider is not mounted or does not support exec"
879
+ }
880
+ };
881
+ const ashRunPath = this.resolveAshRunPath();
882
+ if (!ashRunPath) return {
883
+ success: false,
884
+ error: {
885
+ code: "ASH_UNAVAILABLE",
886
+ message: "ASH provider not found. No provider with URI 'ash://' is mounted."
887
+ }
888
+ };
889
+ const ashArgs = {
890
+ ...args,
891
+ source
892
+ };
893
+ return afs.exec(ashRunPath, ashArgs, {});
894
+ }
895
+ /**
896
+ * Resolve the ASH run action path by finding the ASH provider via URI.
897
+ * Returns the full path to /.actions/run on the ASH provider, or undefined if not found.
898
+ */
899
+ resolveAshRunPath() {
900
+ const afs = this.afsRoot;
901
+ if (!afs) return void 0;
902
+ const matches = (0, _aigne_afs.findMountByURI)(afs, "ash://");
903
+ if (matches.length !== 1) return void 0;
904
+ return (0, ufo.joinURL)(matches[0].path, ".actions", "run");
905
+ }
810
906
  /**
811
907
  * Recursively collect files for archiving.
812
908
  * Excludes .afs directories and respects optional glob pattern.
@@ -1094,6 +1190,7 @@ require_decorate.__decorate([(0, _aigne_afs.Explain)("/:path*")], AFSFS.prototyp
1094
1190
  require_decorate.__decorate([(0, _aigne_afs.Read)("/.meta/.capabilities")], AFSFS.prototype, "readCapabilitiesHandler", null);
1095
1191
  require_decorate.__decorate([_aigne_afs.Actions.Exec("/:path*", "archive")], AFSFS.prototype, "archiveAction", null);
1096
1192
  require_decorate.__decorate([_aigne_afs.Actions.Exec("/:path*", "checksum")], AFSFS.prototype, "checksumAction", null);
1193
+ require_decorate.__decorate([(0, _aigne_afs.Exec)("/:path*")], AFSFS.prototype, "execHandler", null);
1097
1194
  var src_default = AFSFS;
1098
1195
 
1099
1196
  //#endregion
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { AFSAccessMode, AFSBaseProvider, AFSDeleteResult, AFSEntry, AFSExecResult, AFSExplainResult, AFSModuleLoadParams, AFSRenameResult, AFSSearchOptions, AFSSearchResult, AFSStatResult, AFSWriteEntryPayload, AFSWriteResult, ProviderManifest, RouteContext } from "@aigne/afs";
1
+ import { AFSAccessMode, AFSBaseProvider, AFSDeleteResult, AFSEntry, AFSExecResult, AFSExplainResult, AFSModuleLoadParams, AFSRenameResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSStatResult, AFSWriteEntryPayload, AFSWriteResult, ProviderManifest, ProviderTreeSchema, RouteContext } from "@aigne/afs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/index.d.ts
@@ -55,6 +55,7 @@ declare class AFSFS extends AFSBaseProvider {
55
55
  agentSkills: boolean | undefined;
56
56
  }, unknown>>;
57
57
  static manifest(): ProviderManifest;
58
+ static treeSchema(): ProviderTreeSchema;
58
59
  static load({
59
60
  basePath,
60
61
  config
@@ -66,19 +67,17 @@ declare class AFSFS extends AFSBaseProvider {
66
67
  cwd?: string;
67
68
  });
68
69
  agentSkills?: boolean;
70
+ private afsRoot?;
71
+ onMount(afs: AFSRoot): void;
72
+ /** Recursively scan for .ash files and emit script:registered events */
73
+ private scanAshScripts;
74
+ ready(): Promise<void>;
69
75
  /** Whether to apply .gitignore rules (default: false) */
70
76
  private useGitignore;
71
77
  /** Whether to apply .afsignore rules (default: true) */
72
78
  private useAfsignore;
79
+ private assertWithinMount;
73
80
  private get localPathExists();
74
- /**
75
- * Detect MIME type based on file extension
76
- */
77
- private getMimeType;
78
- /**
79
- * Check if file is likely binary based on extension
80
- */
81
- private isBinaryFile;
82
81
  /**
83
82
  * Check if a segment is the hidden .afs directory
84
83
  */
@@ -148,6 +147,14 @@ declare class AFSFS extends AFSBaseProvider {
148
147
  checksumAction(ctx: RouteContext<{
149
148
  path?: string;
150
149
  }>, args: Record<string, unknown>): Promise<AFSExecResult>;
150
+ execHandler(ctx: RouteContext<{
151
+ path?: string;
152
+ }>, args: Record<string, unknown>): Promise<AFSExecResult>;
153
+ /**
154
+ * Resolve the ASH run action path by finding the ASH provider via URI.
155
+ * Returns the full path to /.actions/run on the ASH provider, or undefined if not found.
156
+ */
157
+ private resolveAshRunPath;
151
158
  /**
152
159
  * Recursively collect files for archiving.
153
160
  * Excludes .afs directories and respects optional glob pattern.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { AFSAccessMode, AFSBaseProvider, AFSDeleteResult, AFSEntry, AFSExecResult, AFSExplainResult, AFSModuleLoadParams, AFSRenameResult, AFSSearchOptions, AFSSearchResult, AFSStatResult, AFSWriteEntryPayload, AFSWriteResult, ProviderManifest, RouteContext } from "@aigne/afs";
1
+ import { AFSAccessMode, AFSBaseProvider, AFSDeleteResult, AFSEntry, AFSExecResult, AFSExplainResult, AFSModuleLoadParams, AFSRenameResult, AFSRoot, AFSSearchOptions, AFSSearchResult, AFSStatResult, AFSWriteEntryPayload, AFSWriteResult, ProviderManifest, ProviderTreeSchema, RouteContext } from "@aigne/afs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/index.d.ts
@@ -55,6 +55,7 @@ declare class AFSFS extends AFSBaseProvider {
55
55
  agentSkills: boolean | undefined;
56
56
  }, unknown>>;
57
57
  static manifest(): ProviderManifest;
58
+ static treeSchema(): ProviderTreeSchema;
58
59
  static load({
59
60
  basePath,
60
61
  config
@@ -66,19 +67,17 @@ declare class AFSFS extends AFSBaseProvider {
66
67
  cwd?: string;
67
68
  });
68
69
  agentSkills?: boolean;
70
+ private afsRoot?;
71
+ onMount(afs: AFSRoot): void;
72
+ /** Recursively scan for .ash files and emit script:registered events */
73
+ private scanAshScripts;
74
+ ready(): Promise<void>;
69
75
  /** Whether to apply .gitignore rules (default: false) */
70
76
  private useGitignore;
71
77
  /** Whether to apply .afsignore rules (default: true) */
72
78
  private useAfsignore;
79
+ private assertWithinMount;
73
80
  private get localPathExists();
74
- /**
75
- * Detect MIME type based on file extension
76
- */
77
- private getMimeType;
78
- /**
79
- * Check if file is likely binary based on extension
80
- */
81
- private isBinaryFile;
82
81
  /**
83
82
  * Check if a segment is the hidden .afs directory
84
83
  */
@@ -148,6 +147,14 @@ declare class AFSFS extends AFSBaseProvider {
148
147
  checksumAction(ctx: RouteContext<{
149
148
  path?: string;
150
149
  }>, args: Record<string, unknown>): Promise<AFSExecResult>;
150
+ execHandler(ctx: RouteContext<{
151
+ path?: string;
152
+ }>, args: Record<string, unknown>): Promise<AFSExecResult>;
153
+ /**
154
+ * Resolve the ASH run action path by finding the ASH provider via URI.
155
+ * Returns the full path to /.actions/run on the ASH provider, or undefined if not found.
156
+ */
157
+ private resolveAshRunPath;
151
158
  /**
152
159
  * Recursively collect files for archiving.
153
160
  * Excludes .afs directories and respects optional glob pattern.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}