@astrasyncai/verification-gateway 4.5.1 → 5.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.
- package/README.md +1 -1
- package/dist/adapter-interface/interface.d.mts +2 -2
- package/dist/adapter-interface/interface.d.ts +2 -2
- package/dist/adapters/express.d.mts +2 -2
- package/dist/adapters/express.d.ts +2 -2
- package/dist/adapters/express.js +11 -33
- package/dist/adapters/express.js.map +1 -1
- package/dist/adapters/express.mjs +11 -33
- package/dist/adapters/express.mjs.map +1 -1
- package/dist/adapters/mcp.d.mts +2 -2
- package/dist/adapters/mcp.d.ts +2 -2
- package/dist/adapters/mcp.js +28 -65
- package/dist/adapters/mcp.js.map +1 -1
- package/dist/adapters/mcp.mjs +27 -64
- package/dist/adapters/mcp.mjs.map +1 -1
- package/dist/adapters/nextjs.d.mts +2 -2
- package/dist/adapters/nextjs.d.ts +2 -2
- package/dist/adapters/nextjs.js +9 -30
- package/dist/adapters/nextjs.js.map +1 -1
- package/dist/adapters/nextjs.mjs +9 -30
- package/dist/adapters/nextjs.mjs.map +1 -1
- package/dist/adapters/sdk.d.mts +2 -2
- package/dist/adapters/sdk.d.ts +2 -2
- package/dist/adapters/sdk.js +8 -124
- package/dist/adapters/sdk.js.map +1 -1
- package/dist/adapters/sdk.mjs +8 -122
- package/dist/adapters/sdk.mjs.map +1 -1
- package/dist/agent/index.d.mts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/index.mjs +1 -1
- package/dist/agent/index.mjs.map +1 -1
- package/dist/bin/astrasync-claude-hook.js +63 -41
- package/dist/bin/astrasync-codex-hook.js +63 -41
- package/dist/bin/astrasync-guard.js +63 -41
- package/dist/bin/astrasync.js +75 -48
- package/dist/browser/background.js +63 -41
- package/dist/browser/background.js.map +1 -1
- package/dist/browser/background.mjs +63 -41
- package/dist/browser/background.mjs.map +1 -1
- package/dist/browser/browser-adapter.d.mts +2 -2
- package/dist/browser/browser-adapter.d.ts +2 -2
- package/dist/claude-code/claude-code-adapter.d.mts +2 -2
- package/dist/claude-code/claude-code-adapter.d.ts +2 -2
- package/dist/cli/index.d.mts +2 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +33 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +33 -6
- package/dist/cli/index.mjs.map +1 -1
- package/dist/codex/index.d.mts +2 -2
- package/dist/codex/index.d.ts +2 -2
- package/dist/codex/index.js +63 -41
- package/dist/codex/index.js.map +1 -1
- package/dist/codex/index.mjs +63 -41
- package/dist/codex/index.mjs.map +1 -1
- package/dist/cursor/cursor-adapter.d.mts +2 -2
- package/dist/cursor/cursor-adapter.d.ts +2 -2
- package/dist/cursor/extension.d.mts +2 -2
- package/dist/cursor/extension.d.ts +2 -2
- package/dist/cursor/extension.js +63 -41
- package/dist/cursor/extension.js.map +1 -1
- package/dist/cursor/extension.mjs +63 -41
- package/dist/cursor/extension.mjs.map +1 -1
- package/dist/edge-config.d.mts +1 -1
- package/dist/edge-config.d.ts +1 -1
- package/dist/edge-config.js +1 -1
- package/dist/edge-config.js.map +1 -1
- package/dist/edge-config.mjs +1 -1
- package/dist/edge-config.mjs.map +1 -1
- package/dist/edge-core/index.d.mts +1 -3
- package/dist/edge-core/index.d.ts +1 -3
- package/dist/edge-core/index.js +11 -33
- package/dist/edge-core/index.js.map +1 -1
- package/dist/edge-core/index.mjs +11 -33
- package/dist/edge-core/index.mjs.map +1 -1
- package/dist/{express-DaqL11tx.d.ts → express-B5lWuemA.d.ts} +1 -1
- package/dist/{express-CR6F3njD.d.mts → express-Dm-snUuY.d.mts} +1 -1
- package/dist/gateway/gateway.d.mts +2 -2
- package/dist/gateway/gateway.d.ts +2 -2
- package/dist/gateway/gateway.js +63 -41
- package/dist/gateway/gateway.js.map +1 -1
- package/dist/gateway/gateway.mjs +63 -41
- package/dist/gateway/gateway.mjs.map +1 -1
- package/dist/git-trigger/git-hooks.d.mts +2 -2
- package/dist/git-trigger/git-hooks.d.ts +2 -2
- package/dist/{index-Cub7lK-T.d.mts → index-B5k_vUmK.d.mts} +1 -1
- package/dist/{index-BfIxCYIZ.d.ts → index-BOzM6xUq.d.mts} +1 -2
- package/dist/{index-CwAh7Tln.d.mts → index-dRfxUdFA.d.ts} +1 -2
- package/dist/{index-B5Ts1WtM.d.ts → index-y8xToocF.d.ts} +1 -1
- package/dist/index.d.mts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +30 -217
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +30 -210
- package/dist/index.mjs.map +1 -1
- package/dist/local-evaluator/evaluator.d.mts +2 -2
- package/dist/local-evaluator/evaluator.d.ts +2 -2
- package/dist/local-evaluator/evaluator.js +22 -7
- package/dist/local-evaluator/evaluator.js.map +1 -1
- package/dist/local-evaluator/evaluator.mjs +22 -7
- package/dist/local-evaluator/evaluator.mjs.map +1 -1
- package/dist/{mcp-BgBJu4Jl.d.mts → mcp-DgsyQiQq.d.mts} +53 -52
- package/dist/{mcp--DgKOwfu.d.ts → mcp-OosmAcKf.d.ts} +53 -52
- package/dist/{nextjs-DlX6xwbU.d.mts → nextjs-B1sBdEav.d.mts} +1 -1
- package/dist/{nextjs-DL6uE1ye.d.ts → nextjs-DoRmhV_Z.d.ts} +1 -1
- package/dist/registration/index.d.mts +5 -1
- package/dist/registration/index.d.ts +5 -1
- package/dist/registration/index.js +1 -1
- package/dist/registration/index.js.map +1 -1
- package/dist/registration/index.mjs +1 -1
- package/dist/registration/index.mjs.map +1 -1
- package/dist/sdk-B83N3xKc.d.mts +142 -0
- package/dist/sdk-H_9BTNBS.d.ts +142 -0
- package/dist/transport/index.d.mts +2 -2
- package/dist/transport/index.d.ts +2 -2
- package/dist/transport/index.js +1 -1
- package/dist/transport/index.js.map +1 -1
- package/dist/transport/index.mjs +1 -1
- package/dist/transport/index.mjs.map +1 -1
- package/dist/{types-DwSfO7Sb.d.ts → types-BK2POWNc.d.ts} +23 -50
- package/dist/{types-C0zfSXMB.d.mts → types-CJjZvPr9.d.mts} +23 -50
- package/dist/{types-C7Rb-w0d.d.mts → types-CXf3q4kZ.d.ts} +14 -3
- package/dist/{types-nIh3HtuA.d.ts → types-DQmop7ZW.d.mts} +14 -3
- package/dist/ui/index.d.mts +2 -17
- package/dist/ui/index.d.ts +2 -17
- package/dist/ui/index.js +1 -43
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/index.mjs +1 -42
- package/dist/ui/index.mjs.map +1 -1
- package/dist/verify.d.mts +3 -4
- package/dist/verify.d.ts +3 -4
- package/dist/verify.js +8 -28
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +8 -28
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/sdk-Bbh9B_dw.d.mts +0 -215
- package/dist/sdk-C6SASmsh.d.ts +0 -215
package/dist/adapters/sdk.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import '../types-
|
|
2
|
-
export { V as VerificationGatewayClient, c as createClient,
|
|
1
|
+
import '../types-CJjZvPr9.mjs';
|
|
2
|
+
export { V as VerificationGatewayClient, c as createClient, g as getTrustLevel, v as verifyOnce } from '../sdk-B83N3xKc.mjs';
|
|
3
3
|
import '../metadata-capture.mjs';
|
package/dist/adapters/sdk.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import '../types-
|
|
2
|
-
export { V as VerificationGatewayClient, c as createClient,
|
|
1
|
+
import '../types-BK2POWNc.js';
|
|
2
|
+
export { V as VerificationGatewayClient, c as createClient, g as getTrustLevel, v as verifyOnce } from '../sdk-H_9BTNBS.js';
|
|
3
3
|
import '../metadata-capture.js';
|
package/dist/adapters/sdk.js
CHANGED
|
@@ -22,15 +22,13 @@ var sdk_exports = {};
|
|
|
22
22
|
__export(sdk_exports, {
|
|
23
23
|
VerificationGatewayClient: () => VerificationGatewayClient,
|
|
24
24
|
createClient: () => createClient,
|
|
25
|
-
getCapabilities: () => getCapabilities,
|
|
26
25
|
getTrustLevel: () => getTrustLevel,
|
|
27
|
-
hasMinimumAccess: () => hasMinimumAccess,
|
|
28
26
|
verifyOnce: () => verifyOnce
|
|
29
27
|
});
|
|
30
28
|
module.exports = __toCommonJS(sdk_exports);
|
|
31
29
|
|
|
32
30
|
// src/version.ts
|
|
33
|
-
var SDK_VERSION = "
|
|
31
|
+
var SDK_VERSION = "5.0.0";
|
|
34
32
|
|
|
35
33
|
// src/http.ts
|
|
36
34
|
var SDK_USER_AGENT = `astrasync-sdk/${SDK_VERSION}`;
|
|
@@ -50,84 +48,13 @@ function withUserAgent(initHeaders) {
|
|
|
50
48
|
}
|
|
51
49
|
var sdkFetch = (input, init) => fetch(input, { ...init, headers: withUserAgent(init?.headers) });
|
|
52
50
|
|
|
53
|
-
// src/
|
|
54
|
-
var ACCESS_LEVEL_HIERARCHY = {
|
|
55
|
-
none: 0,
|
|
56
|
-
restricted: 1,
|
|
57
|
-
"read-only": 2,
|
|
58
|
-
standard: 3,
|
|
59
|
-
full: 4,
|
|
60
|
-
internal: 5
|
|
61
|
-
};
|
|
51
|
+
// src/trust-levels.ts
|
|
62
52
|
function getTrustLevel(score) {
|
|
63
53
|
if (score >= 80) return "PLATINUM";
|
|
64
54
|
if (score >= 60) return "GOLD";
|
|
65
55
|
if (score >= 40) return "SILVER";
|
|
66
56
|
return "BRONZE";
|
|
67
57
|
}
|
|
68
|
-
function hasMinimumAccess(actual, required) {
|
|
69
|
-
return ACCESS_LEVEL_HIERARCHY[actual] >= ACCESS_LEVEL_HIERARCHY[required];
|
|
70
|
-
}
|
|
71
|
-
function getCapabilities(accessLevel) {
|
|
72
|
-
switch (accessLevel) {
|
|
73
|
-
case "none":
|
|
74
|
-
return {
|
|
75
|
-
canRead: false,
|
|
76
|
-
canWrite: false,
|
|
77
|
-
canDelete: false,
|
|
78
|
-
canAdmin: false,
|
|
79
|
-
canAccessInternal: false
|
|
80
|
-
};
|
|
81
|
-
case "restricted":
|
|
82
|
-
return {
|
|
83
|
-
canRead: false,
|
|
84
|
-
canWrite: false,
|
|
85
|
-
canDelete: false,
|
|
86
|
-
canAdmin: false,
|
|
87
|
-
canAccessInternal: false
|
|
88
|
-
};
|
|
89
|
-
case "read-only":
|
|
90
|
-
return {
|
|
91
|
-
canRead: true,
|
|
92
|
-
canWrite: false,
|
|
93
|
-
canDelete: false,
|
|
94
|
-
canAdmin: false,
|
|
95
|
-
canAccessInternal: false
|
|
96
|
-
};
|
|
97
|
-
case "standard":
|
|
98
|
-
return {
|
|
99
|
-
canRead: true,
|
|
100
|
-
canWrite: true,
|
|
101
|
-
canDelete: false,
|
|
102
|
-
canAdmin: false,
|
|
103
|
-
canAccessInternal: false
|
|
104
|
-
};
|
|
105
|
-
case "full":
|
|
106
|
-
return {
|
|
107
|
-
canRead: true,
|
|
108
|
-
canWrite: true,
|
|
109
|
-
canDelete: true,
|
|
110
|
-
canAdmin: false,
|
|
111
|
-
canAccessInternal: false
|
|
112
|
-
};
|
|
113
|
-
case "internal":
|
|
114
|
-
return {
|
|
115
|
-
canRead: true,
|
|
116
|
-
canWrite: true,
|
|
117
|
-
canDelete: true,
|
|
118
|
-
canAdmin: true,
|
|
119
|
-
canAccessInternal: true
|
|
120
|
-
};
|
|
121
|
-
default:
|
|
122
|
-
return {
|
|
123
|
-
canRead: false,
|
|
124
|
-
canWrite: false,
|
|
125
|
-
canDelete: false,
|
|
126
|
-
canAdmin: false,
|
|
127
|
-
canAccessInternal: false
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
58
|
|
|
132
59
|
// src/well-known.ts
|
|
133
60
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
@@ -139,11 +66,6 @@ function getCachedWellKnownUrls(apiBaseUrl) {
|
|
|
139
66
|
// src/verify.ts
|
|
140
67
|
var DEFAULT_CONFIG = {
|
|
141
68
|
apiBaseUrl: "https://astrasync.ai/api",
|
|
142
|
-
// v2.3.9 (defect #30): default for unconfigured callers is `'none'` (no
|
|
143
|
-
// access). Pre-rename this defaulted to `'guidance'`, which combined with
|
|
144
|
-
// a route gated at `'guidance'` to silently let unverified traffic
|
|
145
|
-
// through (`hasMinimumAccess('guidance', 'guidance') === true`).
|
|
146
|
-
defaultAccessLevel: "none",
|
|
147
69
|
// minTrustScore + minTrustScoreForFull deprecated in v2.3.0 — server decides.
|
|
148
70
|
// cacheTtl deliberately unset. When undefined, cacheResult applies the 60s
|
|
149
71
|
// default; the caller's explicit value is honoured for cacheable results.
|
|
@@ -307,13 +229,6 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
307
229
|
// policy is not evaluated (we never reached the gate).
|
|
308
230
|
identityVerified: false,
|
|
309
231
|
policyAllowed: false,
|
|
310
|
-
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
311
|
-
// Adapters additionally short-circuit on `!identityVerified ||
|
|
312
|
-
// !policyAllowed` before the gate check, but the access level still has
|
|
313
|
-
// to be honest at the data layer so downstream consumers (SDK adapters
|
|
314
|
-
// in other languages, custom integrations) inherit the correct
|
|
315
|
-
// semantics.
|
|
316
|
-
accessLevel: "none",
|
|
317
232
|
guidance,
|
|
318
233
|
denialReasons: reason ? [reason] : ["No valid agent credentials provided"],
|
|
319
234
|
// Round-10 (#47, O5): on API-error fallback, surface a typed failure so
|
|
@@ -336,6 +251,11 @@ function createGuidanceResponse(_config, reason, options = {}) {
|
|
|
336
251
|
// 4.0.0: typed marker so adapters render the misconfig envelope (503 +
|
|
337
252
|
// MERCHANT_VERIFICATION_MISCONFIGURED) without string-matching.
|
|
338
253
|
...isMisconfig && { misconfigured: true },
|
|
254
|
+
// 4.6.0: a transient api_error is retryable — mark it so consumers surface
|
|
255
|
+
// "temporarily unavailable, retry" (recommendation 'error') instead of
|
|
256
|
+
// coercing the absent recommendation to a policy 'deny'. Misconfig is
|
|
257
|
+
// deterministic and intentionally NOT marked retryable.
|
|
258
|
+
...isApiError && { retryable: true },
|
|
339
259
|
correlationId: options.correlationId,
|
|
340
260
|
attemptId: options.attemptId,
|
|
341
261
|
verifiedAt: /* @__PURE__ */ new Date()
|
|
@@ -402,7 +322,6 @@ async function callVerifyAccessAPI(config, request) {
|
|
|
402
322
|
attemptId: typeof data?.attemptId === "string" ? data.attemptId : void 0,
|
|
403
323
|
access: {
|
|
404
324
|
allowed: false,
|
|
405
|
-
accessLevel: "none",
|
|
406
325
|
reason: "endpoint_deactivated",
|
|
407
326
|
failures: [
|
|
408
327
|
{
|
|
@@ -465,7 +384,7 @@ async function verify(config, request, options) {
|
|
|
465
384
|
if (!deprecationWarningShown && (config.minTrustScore !== void 0 || config.minTrustScoreForFull !== void 0)) {
|
|
466
385
|
deprecationWarningShown = true;
|
|
467
386
|
console.warn(
|
|
468
|
-
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access
|
|
387
|
+
"[VerificationGateway] minTrustScore / minTrustScoreForFull are deprecated in v2.3.0 and have no effect. Server is now the single source of truth for access decisions (verified ID + runtime challenge + PDLSS + trust score). To gate access to an endpoint, configure the endpoint's trust_score_requirement server-side."
|
|
469
388
|
);
|
|
470
389
|
}
|
|
471
390
|
if (mergedConfig.cacheTtl !== 0 && !options?.bypassCache) {
|
|
@@ -511,14 +430,6 @@ async function verify(config, request, options) {
|
|
|
511
430
|
const result2 = {
|
|
512
431
|
identityVerified: idVerifiedFromBackend,
|
|
513
432
|
policyAllowed: false,
|
|
514
|
-
// v2.3.9 (defect #30): denials grant `'none'`, NEVER a positive band.
|
|
515
|
-
// Pre-rename this hardcoded `'guidance'`, which conflated with the
|
|
516
|
-
// colocated `guidance: {...}` help-payload object below and let
|
|
517
|
-
// denied requests pass any route gated at `'guidance'` because
|
|
518
|
-
// `hasMinimumAccess('guidance', 'guidance') === true`. Adapters now
|
|
519
|
-
// ALSO short-circuit on `!identityVerified || !policyAllowed` before
|
|
520
|
-
// the gate check — belt-and-braces.
|
|
521
|
-
accessLevel: "none",
|
|
522
433
|
// 3.6.0: the server now emits top-level denialReasons on every deny
|
|
523
434
|
// path — prefer it verbatim; the failure-message reconstruction remains
|
|
524
435
|
// as the fallback for older backends.
|
|
@@ -567,7 +478,6 @@ async function verify(config, request, options) {
|
|
|
567
478
|
trustScore: apiResponse.organization.trustScore
|
|
568
479
|
} : void 0;
|
|
569
480
|
const verificationContext = apiResponse.verificationContext;
|
|
570
|
-
const accessLevel = apiResponse.access?.accessLevel ?? "standard";
|
|
571
481
|
const result = {
|
|
572
482
|
// 4.5.0 (probe F1): read idVerified from verificationContext with the
|
|
573
483
|
// SAME absent⇒false default as the deny branch. The previous `!== false`
|
|
@@ -579,7 +489,6 @@ async function verify(config, request, options) {
|
|
|
579
489
|
// this load-bearing must never be defaulted on.
|
|
580
490
|
identityVerified: apiResponse.verificationContext?.idVerified === true,
|
|
581
491
|
policyAllowed: true,
|
|
582
|
-
accessLevel,
|
|
583
492
|
agent,
|
|
584
493
|
developer,
|
|
585
494
|
organization,
|
|
@@ -606,7 +515,6 @@ async function verify(config, request, options) {
|
|
|
606
515
|
};
|
|
607
516
|
if (result.recommendation === "deny") {
|
|
608
517
|
result.policyAllowed = false;
|
|
609
|
-
result.accessLevel = "none";
|
|
610
518
|
result.denialReasons = serverDenialReasons ?? result.recommendationReasons ?? ["Access denied by AstraSync recommendation"];
|
|
611
519
|
result.guidance = result.runtimeChallenge ? {
|
|
612
520
|
message: `Verification failed: ${result.runtimeChallenge.reason || "runtime challenge failed"}`,
|
|
@@ -635,7 +543,6 @@ async function quickVerify(config, credentials) {
|
|
|
635
543
|
return {
|
|
636
544
|
identityVerified: result.identityVerified,
|
|
637
545
|
policyAllowed: result.policyAllowed,
|
|
638
|
-
accessLevel: result.accessLevel,
|
|
639
546
|
reason: result.denialReasons?.[0]
|
|
640
547
|
};
|
|
641
548
|
}
|
|
@@ -646,7 +553,6 @@ var VerificationGatewayClient = class {
|
|
|
646
553
|
this.config = {
|
|
647
554
|
apiBaseUrl: options.apiBaseUrl,
|
|
648
555
|
apiKey: options.apiKey,
|
|
649
|
-
defaultAccessLevel: options.defaultAccessLevel,
|
|
650
556
|
minTrustScore: options.minTrustScore,
|
|
651
557
|
minTrustScoreForFull: options.minTrustScoreForFull,
|
|
652
558
|
cacheTtl: options.cacheTtl,
|
|
@@ -695,26 +601,6 @@ var VerificationGatewayClient = class {
|
|
|
695
601
|
async quickVerify(credentials) {
|
|
696
602
|
return this.executeWithRetry(() => quickVerify(this.config, credentials));
|
|
697
603
|
}
|
|
698
|
-
/**
|
|
699
|
-
* Check if an agent has a specific access level.
|
|
700
|
-
*
|
|
701
|
-
* @deprecated 3.2.0 — the access-level band is informational only; it no
|
|
702
|
-
* longer gates in the middleware adapters (post-3.1.0 feedback #1). This
|
|
703
|
-
* explicit opt-in query still works, but prefer gating on the server-side
|
|
704
|
-
* policy decision (identity + policy + trust) or per-route `minTrustScore`.
|
|
705
|
-
* Explicit per-route condition→constraint rules are the Phase-2 successor.
|
|
706
|
-
*/
|
|
707
|
-
async hasAccess(credentials, requiredLevel) {
|
|
708
|
-
const result = await this.quickVerify(credentials);
|
|
709
|
-
return hasMinimumAccess(result.accessLevel, requiredLevel);
|
|
710
|
-
}
|
|
711
|
-
/**
|
|
712
|
-
* Get capabilities for a verified agent
|
|
713
|
-
*/
|
|
714
|
-
async getCapabilities(credentials) {
|
|
715
|
-
const result = await this.quickVerify(credentials);
|
|
716
|
-
return getCapabilities(result.accessLevel);
|
|
717
|
-
}
|
|
718
604
|
/**
|
|
719
605
|
* Verify a specific ASTRA-ID
|
|
720
606
|
*/
|
|
@@ -777,9 +663,7 @@ async function verifyOnce(options) {
|
|
|
777
663
|
0 && (module.exports = {
|
|
778
664
|
VerificationGatewayClient,
|
|
779
665
|
createClient,
|
|
780
|
-
getCapabilities,
|
|
781
666
|
getTrustLevel,
|
|
782
|
-
hasMinimumAccess,
|
|
783
667
|
verifyOnce
|
|
784
668
|
});
|
|
785
669
|
//# sourceMappingURL=sdk.js.map
|