@ny4n/chord 0.0.0-stage → 1.0.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 (124) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -2
  3. package/dist/api.d.ts +20 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +77 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/bundler.d.ts +6 -0
  8. package/dist/bundler.d.ts.map +1 -0
  9. package/dist/bundler.js +3 -0
  10. package/dist/bundler.js.map +1 -0
  11. package/dist/context/index.d.ts +24 -0
  12. package/dist/context/index.d.ts.map +1 -0
  13. package/dist/context/index.js +97 -0
  14. package/dist/context/index.js.map +1 -0
  15. package/dist/delta/apply-immutable-trusted.d.ts +4 -0
  16. package/dist/delta/apply-immutable-trusted.d.ts.map +1 -0
  17. package/dist/delta/apply-immutable-trusted.js +127 -0
  18. package/dist/delta/apply-immutable-trusted.js.map +1 -0
  19. package/dist/delta/core.d.ts +108 -0
  20. package/dist/delta/core.d.ts.map +1 -0
  21. package/dist/delta/core.js +645 -0
  22. package/dist/delta/core.js.map +1 -0
  23. package/dist/delta/diff.d.ts +5 -0
  24. package/dist/delta/diff.d.ts.map +1 -0
  25. package/dist/delta/diff.js +433 -0
  26. package/dist/delta/diff.js.map +1 -0
  27. package/dist/delta/draft.d.ts +5 -0
  28. package/dist/delta/draft.d.ts.map +1 -0
  29. package/dist/delta/draft.js +2 -0
  30. package/dist/delta/draft.js.map +1 -0
  31. package/dist/delta/index.d.ts +5 -0
  32. package/dist/delta/index.d.ts.map +1 -0
  33. package/dist/delta/index.js +6 -0
  34. package/dist/delta/index.js.map +1 -0
  35. package/dist/delta/revision-validator.d.ts +7 -0
  36. package/dist/delta/revision-validator.d.ts.map +1 -0
  37. package/dist/delta/revision-validator.js +71 -0
  38. package/dist/delta/revision-validator.js.map +1 -0
  39. package/dist/delta/tracker.d.ts +26 -0
  40. package/dist/delta/tracker.d.ts.map +1 -0
  41. package/dist/delta/tracker.js +2069 -0
  42. package/dist/delta/tracker.js.map +1 -0
  43. package/dist/facets/host.d.ts +12 -0
  44. package/dist/facets/host.d.ts.map +1 -0
  45. package/dist/facets/host.js +763 -0
  46. package/dist/facets/host.js.map +1 -0
  47. package/dist/facets/loader.d.ts +3 -0
  48. package/dist/facets/loader.d.ts.map +1 -0
  49. package/dist/facets/loader.js +5 -0
  50. package/dist/facets/loader.js.map +1 -0
  51. package/dist/index.d.ts +12 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +10 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/json.d.ts +10 -0
  56. package/dist/json.d.ts.map +1 -0
  57. package/dist/json.js +124 -0
  58. package/dist/json.js.map +1 -0
  59. package/dist/node/bundle-loader.d.ts +30 -0
  60. package/dist/node/bundle-loader.d.ts.map +1 -0
  61. package/dist/node/bundle-loader.js +377 -0
  62. package/dist/node/bundle-loader.js.map +1 -0
  63. package/dist/node/bundle.d.ts +26 -0
  64. package/dist/node/bundle.d.ts.map +1 -0
  65. package/dist/node/bundle.js +183 -0
  66. package/dist/node/bundle.js.map +1 -0
  67. package/dist/node/manifest.d.ts +36 -0
  68. package/dist/node/manifest.d.ts.map +1 -0
  69. package/dist/node/manifest.js +6 -0
  70. package/dist/node/manifest.js.map +1 -0
  71. package/dist/node/package.d.ts +15 -0
  72. package/dist/node/package.d.ts.map +1 -0
  73. package/dist/node/package.js +199 -0
  74. package/dist/node/package.js.map +1 -0
  75. package/dist/node.d.ts +5 -0
  76. package/dist/node.d.ts.map +1 -0
  77. package/dist/node.js +3 -0
  78. package/dist/node.js.map +1 -0
  79. package/dist/services/consumer.d.ts +11 -0
  80. package/dist/services/consumer.d.ts.map +1 -0
  81. package/dist/services/consumer.js +585 -0
  82. package/dist/services/consumer.js.map +1 -0
  83. package/dist/services/errors.d.ts +8 -0
  84. package/dist/services/errors.d.ts.map +1 -0
  85. package/dist/services/errors.js +22 -0
  86. package/dist/services/errors.js.map +1 -0
  87. package/dist/services/handle.d.ts +15 -0
  88. package/dist/services/handle.d.ts.map +1 -0
  89. package/dist/services/handle.js +101 -0
  90. package/dist/services/handle.js.map +1 -0
  91. package/dist/services/instances.d.ts +26 -0
  92. package/dist/services/instances.d.ts.map +1 -0
  93. package/dist/services/instances.js +140 -0
  94. package/dist/services/instances.js.map +1 -0
  95. package/dist/services/loopback.d.ts +5 -0
  96. package/dist/services/loopback.d.ts.map +1 -0
  97. package/dist/services/loopback.js +15 -0
  98. package/dist/services/loopback.js.map +1 -0
  99. package/dist/services/provider.d.ts +37 -0
  100. package/dist/services/provider.d.ts.map +1 -0
  101. package/dist/services/provider.js +521 -0
  102. package/dist/services/provider.js.map +1 -0
  103. package/dist/services/state-codec.d.ts +15 -0
  104. package/dist/services/state-codec.d.ts.map +1 -0
  105. package/dist/services/state-codec.js +133 -0
  106. package/dist/services/state-codec.js.map +1 -0
  107. package/dist/services/state-internals.d.ts +13 -0
  108. package/dist/services/state-internals.d.ts.map +1 -0
  109. package/dist/services/state-internals.js +10 -0
  110. package/dist/services/state-internals.js.map +1 -0
  111. package/dist/services/state.d.ts +28 -0
  112. package/dist/services/state.d.ts.map +1 -0
  113. package/dist/services/state.js +397 -0
  114. package/dist/services/state.js.map +1 -0
  115. package/dist/services/wire.d.ts +63 -0
  116. package/dist/services/wire.d.ts.map +1 -0
  117. package/dist/services/wire.js +186 -0
  118. package/dist/services/wire.js.map +1 -0
  119. package/dist/types.d.ts +277 -0
  120. package/dist/types.d.ts.map +1 -0
  121. package/dist/types.js +2 -0
  122. package/dist/types.js.map +1 -0
  123. package/package.json +71 -5
  124. package/src/delta/README.md +191 -0
@@ -0,0 +1,127 @@
1
+ const DATA_DESCRIPTOR = {
2
+ value: undefined,
3
+ writable: true,
4
+ enumerable: true,
5
+ configurable: true,
6
+ };
7
+ /** Apply self-produced trusted operations while copying each touched container once. */
8
+ export function applyImmutableTrusted(target, operations) {
9
+ let root = target;
10
+ const owned = new WeakSet();
11
+ for (const operation of operations) {
12
+ if (operation[0] === "r") {
13
+ root = operation[1];
14
+ continue;
15
+ }
16
+ if (operation[0] === "p" || operation[0] === "m") {
17
+ const copied = copyPath(root, operation[1], operation[1].length, owned);
18
+ root = copied.root;
19
+ if (!Array.isArray(copied.target))
20
+ throw new TypeError("Trusted array operation target is not an array");
21
+ if (operation[0] === "p")
22
+ spliceTrusted(copied.target, operation[2], operation[3], operation[4]);
23
+ else
24
+ permuteTrusted(copied.target, operation[2]);
25
+ continue;
26
+ }
27
+ const path = operation[1];
28
+ const copied = copyPath(root, path, path.length - 1, owned);
29
+ root = copied.root;
30
+ const key = path[path.length - 1];
31
+ switch (operation[0]) {
32
+ case "s":
33
+ defineData(copied.target, key, operation[2]);
34
+ break;
35
+ case "d":
36
+ if (Array.isArray(copied.target)) {
37
+ if (typeof key !== "number")
38
+ throw new TypeError("Trusted array deletion key is not numeric");
39
+ spliceTrusted(copied.target, key, 1, []);
40
+ }
41
+ else
42
+ Reflect.deleteProperty(copied.target, key);
43
+ break;
44
+ case "a": {
45
+ const current = read(copied.target, key);
46
+ if (typeof current !== "string")
47
+ throw new TypeError("Trusted append target is not a string");
48
+ defineData(copied.target, key, `${current}${operation[2]}`);
49
+ break;
50
+ }
51
+ case "t": {
52
+ const current = read(copied.target, key);
53
+ if (typeof current !== "string")
54
+ throw new TypeError("Trusted truncate target is not a string");
55
+ defineData(copied.target, key, current.slice(operation[2]));
56
+ break;
57
+ }
58
+ }
59
+ }
60
+ return root;
61
+ }
62
+ function copyPath(root, path, length, owned) {
63
+ if (!isContainer(root))
64
+ throw new TypeError("Trusted operation root is not a container");
65
+ let copiedRoot = root;
66
+ if (!owned.has(root)) {
67
+ copiedRoot = shallowCopy(root);
68
+ owned.add(copiedRoot);
69
+ }
70
+ let destination = copiedRoot;
71
+ for (let index = 0; index < length; index++) {
72
+ const segment = path[index];
73
+ const child = read(destination, segment);
74
+ if (!isContainer(child))
75
+ throw new TypeError("Trusted operation path is not a container");
76
+ if (owned.has(child)) {
77
+ destination = child;
78
+ continue;
79
+ }
80
+ const copy = shallowCopy(child);
81
+ defineData(destination, segment, copy);
82
+ owned.add(copy);
83
+ destination = copy;
84
+ }
85
+ return { root: copiedRoot, target: destination };
86
+ }
87
+ function shallowCopy(value) {
88
+ if (Array.isArray(value))
89
+ return Array.from(value);
90
+ const result = Object.create(Object.getPrototypeOf(value) === null ? null : Object.prototype);
91
+ for (const key of Object.keys(value))
92
+ defineData(result, key, value[key]);
93
+ return result;
94
+ }
95
+ function read(target, key) {
96
+ return target[key];
97
+ }
98
+ function defineData(target, key, value) {
99
+ DATA_DESCRIPTOR.value = value;
100
+ Object.defineProperty(target, key, DATA_DESCRIPTOR);
101
+ DATA_DESCRIPTOR.value = undefined;
102
+ }
103
+ function spliceTrusted(target, start, remove, items) {
104
+ const oldLength = target.length;
105
+ const delta = items.length - remove;
106
+ if (delta > 0) {
107
+ target.length = oldLength + delta;
108
+ target.copyWithin(start + items.length, start + remove, oldLength);
109
+ }
110
+ else if (delta < 0) {
111
+ target.copyWithin(start + items.length, start + remove, oldLength);
112
+ target.length = oldLength + delta;
113
+ }
114
+ for (let index = 0; index < items.length; index++)
115
+ defineData(target, start + index, items[index]);
116
+ }
117
+ function permuteTrusted(target, permutation) {
118
+ if (target.length !== permutation.length)
119
+ throw new TypeError("Trusted permutation length mismatch");
120
+ const previous = target.slice();
121
+ for (let index = 0; index < permutation.length; index++)
122
+ target[index] = previous[permutation[index]];
123
+ }
124
+ function isContainer(value) {
125
+ return value !== null && typeof value === "object";
126
+ }
127
+ //# sourceMappingURL=apply-immutable-trusted.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply-immutable-trusted.js","sourceRoot":"","sources":["../../src/delta/apply-immutable-trusted.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JsonValue } from \"../types.ts\";\nimport type { Op, Path, Seg } from \"./index.ts\";\n\ntype JsonContainer = JsonValue[] | Record<string, JsonValue>;\ntype CopiedPath = { root: JsonValue; target: JsonContainer };\n\nconst DATA_DESCRIPTOR: PropertyDescriptor = {\n\tvalue: undefined,\n\twritable: true,\n\tenumerable: true,\n\tconfigurable: true,\n};\n\n/** Apply self-produced trusted operations while copying each touched container once. */\nexport function applyImmutableTrusted<T>(target: T, operations: readonly Op[]): T {\n\tlet root = target as unknown as JsonValue;\n\tconst owned = new WeakSet<object>();\n\tfor (const operation of operations) {\n\t\tif (operation[0] === \"r\") {\n\t\t\troot = operation[1];\n\t\t\tcontinue;\n\t\t}\n\t\tif (operation[0] === \"p\" || operation[0] === \"m\") {\n\t\t\tconst copied = copyPath(root, operation[1], operation[1].length, owned);\n\t\t\troot = copied.root;\n\t\t\tif (!Array.isArray(copied.target)) throw new TypeError(\"Trusted array operation target is not an array\");\n\t\t\tif (operation[0] === \"p\") spliceTrusted(copied.target, operation[2], operation[3], operation[4]);\n\t\t\telse permuteTrusted(copied.target, operation[2]);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst path = operation[1];\n\t\tconst copied = copyPath(root, path, path.length - 1, owned);\n\t\troot = copied.root;\n\t\tconst key = path[path.length - 1]!;\n\t\tswitch (operation[0]) {\n\t\t\tcase \"s\":\n\t\t\t\tdefineData(copied.target, key, operation[2]);\n\t\t\t\tbreak;\n\t\t\tcase \"d\":\n\t\t\t\tif (Array.isArray(copied.target)) {\n\t\t\t\t\tif (typeof key !== \"number\") throw new TypeError(\"Trusted array deletion key is not numeric\");\n\t\t\t\t\tspliceTrusted(copied.target, key, 1, []);\n\t\t\t\t} else Reflect.deleteProperty(copied.target, key);\n\t\t\t\tbreak;\n\t\t\tcase \"a\": {\n\t\t\t\tconst current = read(copied.target, key);\n\t\t\t\tif (typeof current !== \"string\") throw new TypeError(\"Trusted append target is not a string\");\n\t\t\t\tdefineData(copied.target, key, `${current}${operation[2]}`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"t\": {\n\t\t\t\tconst current = read(copied.target, key);\n\t\t\t\tif (typeof current !== \"string\") throw new TypeError(\"Trusted truncate target is not a string\");\n\t\t\t\tdefineData(copied.target, key, current.slice(operation[2]));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn root as unknown as T;\n}\n\nfunction copyPath(root: JsonValue, path: Path, length: number, owned: WeakSet<object>): CopiedPath {\n\tif (!isContainer(root)) throw new TypeError(\"Trusted operation root is not a container\");\n\tlet copiedRoot = root;\n\tif (!owned.has(root)) {\n\t\tcopiedRoot = shallowCopy(root);\n\t\towned.add(copiedRoot);\n\t}\n\tlet destination = copiedRoot as JsonContainer;\n\tfor (let index = 0; index < length; index++) {\n\t\tconst segment = path[index]!;\n\t\tconst child = read(destination, segment);\n\t\tif (!isContainer(child)) throw new TypeError(\"Trusted operation path is not a container\");\n\t\tif (owned.has(child)) {\n\t\t\tdestination = child;\n\t\t\tcontinue;\n\t\t}\n\t\tconst copy = shallowCopy(child);\n\t\tdefineData(destination, segment, copy);\n\t\towned.add(copy);\n\t\tdestination = copy;\n\t}\n\treturn { root: copiedRoot, target: destination };\n}\n\nfunction shallowCopy(value: JsonContainer): JsonContainer {\n\tif (Array.isArray(value)) return Array.from(value);\n\tconst result = Object.create(Object.getPrototypeOf(value) === null ? null : Object.prototype) as Record<\n\t\tstring,\n\t\tJsonValue\n\t>;\n\tfor (const key of Object.keys(value)) defineData(result, key, value[key]!);\n\treturn result;\n}\n\nfunction read(target: JsonContainer, key: Seg): JsonValue {\n\treturn (target as Record<Seg, JsonValue>)[key]!;\n}\n\nfunction defineData(target: JsonContainer, key: Seg, value: JsonValue): void {\n\tDATA_DESCRIPTOR.value = value;\n\tObject.defineProperty(target, key, DATA_DESCRIPTOR);\n\tDATA_DESCRIPTOR.value = undefined;\n}\n\nfunction spliceTrusted(target: JsonValue[], start: number, remove: number, items: readonly JsonValue[]): void {\n\tconst oldLength = target.length;\n\tconst delta = items.length - remove;\n\tif (delta > 0) {\n\t\ttarget.length = oldLength + delta;\n\t\ttarget.copyWithin(start + items.length, start + remove, oldLength);\n\t} else if (delta < 0) {\n\t\ttarget.copyWithin(start + items.length, start + remove, oldLength);\n\t\ttarget.length = oldLength + delta;\n\t}\n\tfor (let index = 0; index < items.length; index++) defineData(target, start + index, items[index]!);\n}\n\nfunction permuteTrusted(target: JsonValue[], permutation: readonly number[]): void {\n\tif (target.length !== permutation.length) throw new TypeError(\"Trusted permutation length mismatch\");\n\tconst previous = target.slice();\n\tfor (let index = 0; index < permutation.length; index++) target[index] = previous[permutation[index]!]!;\n}\n\nfunction isContainer(value: unknown): value is JsonContainer {\n\treturn value !== null && typeof value === \"object\";\n}\n"]}
@@ -0,0 +1,108 @@
1
+ import type { JsonValue } from "../types.ts";
2
+ export type { JsonValue } from "../types.ts";
3
+ export type Seg = string | number;
4
+ export type Path = readonly Seg[];
5
+ export type NonEmptyPath = readonly [Seg, ...Seg[]];
6
+ /** A path inline, or an id assigned by the encoder on second use. */
7
+ export type PathRef<P extends Path = Path> = P | number;
8
+ /**
9
+ * Tuples are the form — in memory, on the wire, on disk.
10
+ *
11
+ * `r` is the ONLY op that replaces a whole value. `s`/`d`/`a`/`t` cannot target
12
+ * the root: the type forbids it. `p` and `m` may, because a tracked value can
13
+ * itself be an array. Operation shape is not canonical: an array may be emptied by either
14
+ * a replacement or a root splice.
15
+ *
16
+ * `Op` knows nothing about the path dictionary. Interning, id references and
17
+ * omitted paths live in `WireOp` and exist only between `encode` and `decode`.
18
+ */
19
+ export type Op = readonly ["r", JsonValue] | readonly ["s", NonEmptyPath, JsonValue] | readonly ["d", NonEmptyPath] | readonly ["a", NonEmptyPath, string] | readonly ["t", NonEmptyPath, number] | readonly ["p", Path, number, number, JsonValue[]]
20
+ /** Reorder an array in place: `new[i] = old[permutation[i]]`. */
21
+ | readonly ["m", Path, number[]];
22
+ /**
23
+ * What crosses a boundary. Adds two compressions and nothing else:
24
+ *
25
+ * ["#", id, path] defines an id, emitted on a path's SECOND use
26
+ * a numeric PathRef references a previously defined id
27
+ * a shortened tuple reuses the previous op's path; arity disambiguates
28
+ *
29
+ * ["r", value] carries no path, so it encodes to itself — which is why isBase
30
+ * works unchanged on either vocabulary.
31
+ */
32
+ export type WireOp = readonly ["r", JsonValue] | readonly ["s", PathRef<NonEmptyPath>, JsonValue] | readonly ["s", JsonValue] | readonly ["d", PathRef<NonEmptyPath>] | readonly ["d"] | readonly ["a", PathRef<NonEmptyPath>, string] | readonly ["a", string] | readonly ["t", PathRef<NonEmptyPath>, number] | readonly ["t", number] | readonly ["p", PathRef, number, number, JsonValue[]] | readonly ["p", number, number, JsonValue[]] | readonly ["m", PathRef, number[]] | readonly ["m", number[]] | readonly ["#", number, Path];
33
+ export declare const isReplace: (op: Op | WireOp) => boolean;
34
+ /**
35
+ * A batch begins with a replacement. Flush guarantees `r` is at index 0 or absent,
36
+ * so this is exact rather than a heuristic.
37
+ */
38
+ export declare const isBase: (ops: readonly (Op | WireOp)[]) => boolean;
39
+ /**
40
+ * Longest suffix of `a` that is a prefix of `b`. Probes with indexOf and verifies
41
+ * exact substring equality, so the hot loops are native. A hand-written KMP is
42
+ * asymptotically equivalent and much slower in practice.
43
+ *
44
+ * Always correct: the returned n satisfies a.slice(a.length - n) === b.slice(0, n).
45
+ */
46
+ export declare function overlap(a: string, b: string, scan: number, probe?: number, maxCandidates?: number): number;
47
+ /**
48
+ * Segments that reach the prototype chain.
49
+ *
50
+ * `JSON.parse` is safe on its own — it makes `__proto__` an own property. What is
51
+ * not safe is `parent[key] = value`, which is exactly what an applier does, and
52
+ * paths are data: `["s", ["__proto__", "isAdmin"], true]` pollutes
53
+ * `Object.prototype` for the whole process.
54
+ *
55
+ * Ops arrive from a facet, a plugin compartment, or a tool whose details may echo
56
+ * model output, so none of it is trusted input.
57
+ */
58
+ export declare const RESERVED_SEGMENTS: ReadonlySet<string>;
59
+ export declare class UnsafePathError extends Error {
60
+ readonly segment: Seg;
61
+ constructor(segment: Seg);
62
+ }
63
+ /**
64
+ * Verb, arity and payload shape for a **decoded** op: paths inline, no `#`, no
65
+ * short forms. `apply` uses this.
66
+ *
67
+ * Validating `Op` against the wire grammar would be laxer than the type: a
68
+ * two-element `["s", value]` would pass, and `apply` would then read the value as
69
+ * a path. Each vocabulary gets the validator that matches it.
70
+ */
71
+ export declare function assertValidOp(op: unknown): asserts op is Op;
72
+ /** The same, for the wire grammar: ids and short forms are legal here. */
73
+ export declare function assertValidWireOp(op: unknown): asserts op is WireOp;
74
+ export declare function assertSafePath(path: Path): void;
75
+ export declare class PathError extends Error {
76
+ readonly path: Path | number;
77
+ constructor(path: Path | number);
78
+ }
79
+ /**
80
+ * Apply ops to a plain mutable value. Returns the value, because `r` replaces it
81
+ * outright and cannot be done in place.
82
+ *
83
+ * Takes decoded ops. Path ids and omitted paths are a wire concern — run
84
+ * `decode` first if the ops came from a boundary.
85
+ */
86
+ export declare function apply<T>(target: T | undefined, ops: readonly Op[]): T;
87
+ /** Apply one decoded operation batch without mutating the previous immutable value. */
88
+ export declare function applyImmutable<T>(target: T | undefined, ops: readonly Op[]): T;
89
+ /**
90
+ * Apply decoded operation batches as one final-result-only replay.
91
+ *
92
+ * Containers copied for an earlier batch may be mutated while applying a later
93
+ * batch, so this deliberately exposes no intermediate revisions.
94
+ */
95
+ export declare function applyImmutableBatches<T>(target: T | undefined, batches: Iterable<readonly Op[]>): T;
96
+ export interface Encoder {
97
+ encode(ops: readonly Op[]): WireOp[];
98
+ }
99
+ /**
100
+ * Intern on SECOND use. A definition costs more than the path it replaces, so
101
+ * interning on first use loses on the many paths written exactly once.
102
+ */
103
+ export declare function encoder(): Encoder;
104
+ export interface Decoder {
105
+ decode(wire: readonly WireOp[]): Op[];
106
+ }
107
+ export declare function decoder(): Decoder;
108
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/delta/core.ts"],"names":[],"mappings":"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"}