mindgraph 0.12.0 → 0.14.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/LICENSE +1 -1
- package/dist/index.d.mts +247 -16
- package/dist/index.d.ts +247 -16
- package/dist/index.js +107 -55
- package/dist/index.mjs +107 -55
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -26,6 +26,9 @@ __export(index_exports, {
|
|
|
26
26
|
module.exports = __toCommonJS(index_exports);
|
|
27
27
|
|
|
28
28
|
// src/client.ts
|
|
29
|
+
function seg(value) {
|
|
30
|
+
return encodeURIComponent(String(value));
|
|
31
|
+
}
|
|
29
32
|
var MindGraphError = class extends Error {
|
|
30
33
|
constructor(message, status, body) {
|
|
31
34
|
super(message);
|
|
@@ -46,15 +49,21 @@ var MindGraph = class {
|
|
|
46
49
|
if (config.orgId) {
|
|
47
50
|
this.headers["X-MindGraph-Org"] = config.orgId;
|
|
48
51
|
}
|
|
52
|
+
this.telemetrySurface = config.telemetrySurface;
|
|
49
53
|
this.maxRetries = config.maxRetries ?? 3;
|
|
50
54
|
this.retryBackoffMs = config.retryBackoffMs ?? 1e3;
|
|
51
55
|
}
|
|
52
56
|
// ---- HTTP helpers ----
|
|
53
57
|
async request(method, path, body) {
|
|
54
58
|
const url = `${this.baseUrl}${path}`;
|
|
59
|
+
const requestId = createRequestId();
|
|
55
60
|
const init = {
|
|
56
61
|
method,
|
|
57
|
-
headers:
|
|
62
|
+
headers: {
|
|
63
|
+
...this.headers,
|
|
64
|
+
"X-MindGraph-Request-ID": requestId,
|
|
65
|
+
...this.telemetrySurface ? { "X-MindGraph-Surface": this.telemetrySurface } : {}
|
|
66
|
+
}
|
|
58
67
|
};
|
|
59
68
|
if (body !== void 0) {
|
|
60
69
|
init.body = JSON.stringify(body);
|
|
@@ -289,6 +298,9 @@ var MindGraph = class {
|
|
|
289
298
|
async memoryConfig(req) {
|
|
290
299
|
return this.post("/memory/config", req);
|
|
291
300
|
}
|
|
301
|
+
async memorySync(req) {
|
|
302
|
+
return this.post("/memory/sync", req);
|
|
303
|
+
}
|
|
292
304
|
// ---- Agent Layer ----
|
|
293
305
|
async plan(req) {
|
|
294
306
|
return this.post("/agent/plan", req);
|
|
@@ -312,7 +324,7 @@ var MindGraph = class {
|
|
|
312
324
|
}
|
|
313
325
|
// ---- Node CRUD ----
|
|
314
326
|
async getNode(uid) {
|
|
315
|
-
return this.get(`/node/${uid}`);
|
|
327
|
+
return this.get(`/node/${seg(uid)}`);
|
|
316
328
|
}
|
|
317
329
|
/**
|
|
318
330
|
* Create a node via the low-level CRUD endpoint.
|
|
@@ -329,10 +341,10 @@ var MindGraph = class {
|
|
|
329
341
|
return this.post("/node", { ...body, props });
|
|
330
342
|
}
|
|
331
343
|
async updateNode(uid, body) {
|
|
332
|
-
return this.patch(`/node/${uid}`, body);
|
|
344
|
+
return this.patch(`/node/${seg(uid)}`, body);
|
|
333
345
|
}
|
|
334
346
|
async deleteNode(uid) {
|
|
335
|
-
await this.del(`/node/${uid}`);
|
|
347
|
+
await this.del(`/node/${seg(uid)}`);
|
|
336
348
|
}
|
|
337
349
|
async batchDeleteNodes(params) {
|
|
338
350
|
const body = {};
|
|
@@ -353,10 +365,10 @@ var MindGraph = class {
|
|
|
353
365
|
return this.post("/nodes/delete", body);
|
|
354
366
|
}
|
|
355
367
|
async getNodeHistory(uid) {
|
|
356
|
-
return this.get(`/node/${uid}/history`);
|
|
368
|
+
return this.get(`/node/${seg(uid)}/history`);
|
|
357
369
|
}
|
|
358
370
|
async getNodeAtVersion(uid, version) {
|
|
359
|
-
return this.get(`/node/${uid}/history/${version}`);
|
|
371
|
+
return this.get(`/node/${seg(uid)}/history/${seg(version)}`);
|
|
360
372
|
}
|
|
361
373
|
// ---- Edge CRUD ----
|
|
362
374
|
async addLink(body) {
|
|
@@ -377,13 +389,13 @@ var MindGraph = class {
|
|
|
377
389
|
return this.post("/edge", { ...body, props });
|
|
378
390
|
}
|
|
379
391
|
async updateEdge(uid, body) {
|
|
380
|
-
return this.patch(`/edge/${uid}`, body);
|
|
392
|
+
return this.patch(`/edge/${seg(uid)}`, body);
|
|
381
393
|
}
|
|
382
394
|
async deleteEdge(uid) {
|
|
383
|
-
await this.del(`/edge/${uid}`);
|
|
395
|
+
await this.del(`/edge/${seg(uid)}`);
|
|
384
396
|
}
|
|
385
397
|
async getEdgeHistory(uid) {
|
|
386
|
-
return this.get(`/edge/${uid}/history`);
|
|
398
|
+
return this.get(`/edge/${seg(uid)}/history`);
|
|
387
399
|
}
|
|
388
400
|
/**
|
|
389
401
|
* List edges filtered by source and/or target node.
|
|
@@ -432,7 +444,7 @@ var MindGraph = class {
|
|
|
432
444
|
return this.get(`/nodes?${qs}`);
|
|
433
445
|
}
|
|
434
446
|
async getAgentNodes(agentId) {
|
|
435
|
-
return this.get(`/agent/${agentId}/nodes`);
|
|
447
|
+
return this.get(`/agent/${seg(agentId)}/nodes`);
|
|
436
448
|
}
|
|
437
449
|
// ---- Batch ----
|
|
438
450
|
async batch(req) {
|
|
@@ -457,13 +469,13 @@ var MindGraph = class {
|
|
|
457
469
|
return this.post("/embeddings/search-text", body);
|
|
458
470
|
}
|
|
459
471
|
async getEmbedding(uid) {
|
|
460
|
-
return this.get(`/node/${uid}/embedding`);
|
|
472
|
+
return this.get(`/node/${seg(uid)}/embedding`);
|
|
461
473
|
}
|
|
462
474
|
async setEmbedding(uid, vector) {
|
|
463
|
-
await this.request("PUT", `/node/${uid}/embedding`, { vector });
|
|
475
|
+
await this.request("PUT", `/node/${seg(uid)}/embedding`, { vector });
|
|
464
476
|
}
|
|
465
477
|
async deleteEmbedding(uid) {
|
|
466
|
-
await this.del(`/node/${uid}/embedding`);
|
|
478
|
+
await this.del(`/node/${seg(uid)}/embedding`);
|
|
467
479
|
}
|
|
468
480
|
// ---- Entity resolution ----
|
|
469
481
|
async mergeEntities(body) {
|
|
@@ -473,7 +485,7 @@ var MindGraph = class {
|
|
|
473
485
|
return this.post("/alias", body);
|
|
474
486
|
}
|
|
475
487
|
async getAliases(uid) {
|
|
476
|
-
return this.get(`/aliases/${uid}`);
|
|
488
|
+
return this.get(`/aliases/${seg(uid)}`);
|
|
477
489
|
}
|
|
478
490
|
async resolveAlias(text) {
|
|
479
491
|
return this.get(`/resolve?text=${encodeURIComponent(text)}`);
|
|
@@ -596,18 +608,18 @@ var MindGraph = class {
|
|
|
596
608
|
return this.get("/jobs");
|
|
597
609
|
}
|
|
598
610
|
async getJob(id) {
|
|
599
|
-
return this.get(`/jobs/${id}`);
|
|
611
|
+
return this.get(`/jobs/${seg(id)}`);
|
|
600
612
|
}
|
|
601
613
|
async cancelJob(id) {
|
|
602
|
-
return this.post(`/jobs/${id}/cancel`, {});
|
|
614
|
+
return this.post(`/jobs/${seg(id)}/cancel`, {});
|
|
603
615
|
}
|
|
604
616
|
/** Resume ingestion of a document that has failed chunks. */
|
|
605
617
|
async resumeDocument(docUid, opts) {
|
|
606
|
-
return this.post(`/ingest/resume/${docUid}`, opts ?? {});
|
|
618
|
+
return this.post(`/ingest/resume/${seg(docUid)}`, opts ?? {});
|
|
607
619
|
}
|
|
608
620
|
/** Delete a document and all its chunks and extracted nodes. */
|
|
609
621
|
async deleteDocument(uid) {
|
|
610
|
-
return this.del(`/ingest/document/${uid}`);
|
|
622
|
+
return this.del(`/ingest/document/${seg(uid)}`);
|
|
611
623
|
}
|
|
612
624
|
async cleanupOrphans() {
|
|
613
625
|
return this.post("/ingest/cleanup", {});
|
|
@@ -631,27 +643,27 @@ var MindGraph = class {
|
|
|
631
643
|
}
|
|
632
644
|
/** Get a single wiki article by UID. */
|
|
633
645
|
async getArticle(uid) {
|
|
634
|
-
return this.get(`/wiki/article/${uid}`);
|
|
646
|
+
return this.get(`/wiki/article/${seg(uid)}`);
|
|
635
647
|
}
|
|
636
648
|
/** Find the article that covers or summarizes a given entity/document UID. */
|
|
637
649
|
async getArticleBySubject(subjectUid) {
|
|
638
650
|
try {
|
|
639
|
-
return await this.get(`/wiki/article/by-subject/${subjectUid}`);
|
|
651
|
+
return await this.get(`/wiki/article/by-subject/${seg(subjectUid)}`);
|
|
640
652
|
} catch {
|
|
641
653
|
return null;
|
|
642
654
|
}
|
|
643
655
|
}
|
|
644
656
|
/** Update an article's markdown content (user editing). */
|
|
645
657
|
async updateArticle(uid, content) {
|
|
646
|
-
return this.patch(`/wiki/article/${uid}`, { content });
|
|
658
|
+
return this.patch(`/wiki/article/${seg(uid)}`, { content });
|
|
647
659
|
}
|
|
648
660
|
/** Trigger wiki compilation for a specific document. */
|
|
649
661
|
async compileDocument(docUid) {
|
|
650
|
-
return this.post(`/wiki/compile/${docUid}`, {});
|
|
662
|
+
return this.post(`/wiki/compile/${seg(docUid)}`, {});
|
|
651
663
|
}
|
|
652
664
|
/** Trigger wiki compilation for a specific entity. */
|
|
653
665
|
async compileEntity(entityUid) {
|
|
654
|
-
return this.post(`/wiki/compile/entity/${entityUid}`, {});
|
|
666
|
+
return this.post(`/wiki/compile/entity/${seg(entityUid)}`, {});
|
|
655
667
|
}
|
|
656
668
|
/** Backfill: compile articles for all documents and eligible entities. */
|
|
657
669
|
async compileAll() {
|
|
@@ -672,7 +684,7 @@ var MindGraph = class {
|
|
|
672
684
|
if (opts?.signals) q.set("signals", opts.signals);
|
|
673
685
|
if (opts?.target_types) q.set("target_types", opts.target_types);
|
|
674
686
|
const qs = q.toString();
|
|
675
|
-
return this.get(`/synthesis/signals/${projectUid}${qs ? `?${qs}` : ""}`);
|
|
687
|
+
return this.get(`/synthesis/signals/${seg(projectUid)}${qs ? `?${qs}` : ""}`);
|
|
676
688
|
}
|
|
677
689
|
/**
|
|
678
690
|
* Spawn a background synthesis job for a project: mines signals,
|
|
@@ -682,7 +694,7 @@ var MindGraph = class {
|
|
|
682
694
|
* Returns a `job_id` immediately; poll `getJob(id)` for progress.
|
|
683
695
|
*/
|
|
684
696
|
async runSynthesis(projectUid) {
|
|
685
|
-
return this.post(`/synthesis/run/${projectUid}`, {});
|
|
697
|
+
return this.post(`/synthesis/run/${seg(projectUid)}`, {});
|
|
686
698
|
}
|
|
687
699
|
// ============================================================================
|
|
688
700
|
// Operational Ontology Layer (Layer 7)
|
|
@@ -692,22 +704,22 @@ var MindGraph = class {
|
|
|
692
704
|
return this.get("/v1/ontology/schemas");
|
|
693
705
|
}
|
|
694
706
|
async getOntologySchema(id) {
|
|
695
|
-
return this.get(`/v1/ontology/schemas/${id}`);
|
|
707
|
+
return this.get(`/v1/ontology/schemas/${seg(id)}`);
|
|
696
708
|
}
|
|
697
709
|
async createOntologySchema(req) {
|
|
698
710
|
return this.post("/v1/ontology/schemas", req);
|
|
699
711
|
}
|
|
700
712
|
async updateOntologySchema(id, req) {
|
|
701
|
-
return this.patch(`/v1/ontology/schemas/${id}`, req);
|
|
713
|
+
return this.patch(`/v1/ontology/schemas/${seg(id)}`, req);
|
|
702
714
|
}
|
|
703
715
|
async activateOntologySchema(id) {
|
|
704
|
-
return this.post(`/v1/ontology/schemas/${id}/activate`, {});
|
|
716
|
+
return this.post(`/v1/ontology/schemas/${seg(id)}/activate`, {});
|
|
705
717
|
}
|
|
706
718
|
async deprecateOntologySchema(id) {
|
|
707
|
-
return this.post(`/v1/ontology/schemas/${id}/deprecate`, {});
|
|
719
|
+
return this.post(`/v1/ontology/schemas/${seg(id)}/deprecate`, {});
|
|
708
720
|
}
|
|
709
721
|
async archiveOntologySchema(id) {
|
|
710
|
-
return this.del(`/v1/ontology/schemas/${id}`);
|
|
722
|
+
return this.del(`/v1/ontology/schemas/${seg(id)}`);
|
|
711
723
|
}
|
|
712
724
|
/**
|
|
713
725
|
* Kick off an LLM-driven schema proposal job.
|
|
@@ -718,47 +730,47 @@ var MindGraph = class {
|
|
|
718
730
|
return this.post("/v1/ontology/propose-schema", req);
|
|
719
731
|
}
|
|
720
732
|
async testOntologySchema(id, opts) {
|
|
721
|
-
return this.post(`/v1/ontology/schemas/${id}/test`, opts ?? {});
|
|
733
|
+
return this.post(`/v1/ontology/schemas/${seg(id)}/test`, opts ?? {});
|
|
722
734
|
}
|
|
723
735
|
// ---- Schema sub-resources ----
|
|
724
736
|
async addOntologyObjectType(schemaId, req) {
|
|
725
|
-
return this.post(`/v1/ontology/schemas/${schemaId}/object-types`, req);
|
|
737
|
+
return this.post(`/v1/ontology/schemas/${seg(schemaId)}/object-types`, req);
|
|
726
738
|
}
|
|
727
739
|
async updateOntologyObjectType(schemaId, typeId, req) {
|
|
728
740
|
return this.patch(
|
|
729
|
-
`/v1/ontology/schemas/${schemaId}/object-types/${typeId}`,
|
|
741
|
+
`/v1/ontology/schemas/${seg(schemaId)}/object-types/${seg(typeId)}`,
|
|
730
742
|
req
|
|
731
743
|
);
|
|
732
744
|
}
|
|
733
745
|
async deleteOntologyObjectType(schemaId, typeId) {
|
|
734
746
|
return this.del(
|
|
735
|
-
`/v1/ontology/schemas/${schemaId}/object-types/${typeId}`
|
|
747
|
+
`/v1/ontology/schemas/${seg(schemaId)}/object-types/${seg(typeId)}`
|
|
736
748
|
);
|
|
737
749
|
}
|
|
738
750
|
async addOntologyRelationType(schemaId, req) {
|
|
739
|
-
return this.post(`/v1/ontology/schemas/${schemaId}/relation-types`, req);
|
|
751
|
+
return this.post(`/v1/ontology/schemas/${seg(schemaId)}/relation-types`, req);
|
|
740
752
|
}
|
|
741
753
|
async updateOntologyRelationType(schemaId, typeId, req) {
|
|
742
754
|
return this.patch(
|
|
743
|
-
`/v1/ontology/schemas/${schemaId}/relation-types/${typeId}`,
|
|
755
|
+
`/v1/ontology/schemas/${seg(schemaId)}/relation-types/${seg(typeId)}`,
|
|
744
756
|
req
|
|
745
757
|
);
|
|
746
758
|
}
|
|
747
759
|
async deleteOntologyRelationType(schemaId, typeId) {
|
|
748
760
|
return this.del(
|
|
749
|
-
`/v1/ontology/schemas/${schemaId}/relation-types/${typeId}`
|
|
761
|
+
`/v1/ontology/schemas/${seg(schemaId)}/relation-types/${seg(typeId)}`
|
|
750
762
|
);
|
|
751
763
|
}
|
|
752
764
|
/** Generate inert semantic classifications for individual human review. */
|
|
753
765
|
async analyzeOntologySemanticGuidance(schemaId) {
|
|
754
766
|
return this.post(
|
|
755
|
-
`/v1/ontology/schemas/${schemaId}/semantic-guidance/analyze`,
|
|
767
|
+
`/v1/ontology/schemas/${seg(schemaId)}/semantic-guidance/analyze`,
|
|
756
768
|
{}
|
|
757
769
|
);
|
|
758
770
|
}
|
|
759
771
|
/** Read-only exact-identity collision audit; never merges graph data. */
|
|
760
772
|
async auditOntologyDuplicates(schemaId) {
|
|
761
|
-
return this.post(`/v1/ontology/schemas/${schemaId}/duplicates/audit`, {});
|
|
773
|
+
return this.post(`/v1/ontology/schemas/${seg(schemaId)}/duplicates/audit`, {});
|
|
762
774
|
}
|
|
763
775
|
// ---- Proposals ----
|
|
764
776
|
async listOntologyProposals(opts) {
|
|
@@ -774,19 +786,19 @@ var MindGraph = class {
|
|
|
774
786
|
return this.get(`/v1/ontology/proposals${qs ? `?${qs}` : ""}`);
|
|
775
787
|
}
|
|
776
788
|
async getOntologyProposal(id) {
|
|
777
|
-
return this.get(`/v1/ontology/proposals/${id}`);
|
|
789
|
+
return this.get(`/v1/ontology/proposals/${seg(id)}`);
|
|
778
790
|
}
|
|
779
791
|
async patchOntologyProposal(id, req) {
|
|
780
|
-
return this.patch(`/v1/ontology/proposals/${id}`, req);
|
|
792
|
+
return this.patch(`/v1/ontology/proposals/${seg(id)}`, req);
|
|
781
793
|
}
|
|
782
794
|
async approveOntologyProposal(id, opts) {
|
|
783
|
-
return this.post(`/v1/ontology/proposals/${id}/approve`, opts ?? {});
|
|
795
|
+
return this.post(`/v1/ontology/proposals/${seg(id)}/approve`, opts ?? {});
|
|
784
796
|
}
|
|
785
797
|
async rejectOntologyProposal(id, reason) {
|
|
786
|
-
return this.post(`/v1/ontology/proposals/${id}/reject`, { reason });
|
|
798
|
+
return this.post(`/v1/ontology/proposals/${seg(id)}/reject`, { reason });
|
|
787
799
|
}
|
|
788
800
|
async applyOntologyProposal(id) {
|
|
789
|
-
return this.post(`/v1/ontology/proposals/${id}/apply`, {});
|
|
801
|
+
return this.post(`/v1/ontology/proposals/${seg(id)}/apply`, {});
|
|
790
802
|
}
|
|
791
803
|
async batchApproveOntologyProposals(ids, feedback) {
|
|
792
804
|
return this.post("/v1/ontology/proposals/batch-approve", { ids, feedback });
|
|
@@ -798,24 +810,58 @@ var MindGraph = class {
|
|
|
798
810
|
async queryOntology(req) {
|
|
799
811
|
return this.post("/ontology/query", req);
|
|
800
812
|
}
|
|
813
|
+
async queryDomainStructured(req) {
|
|
814
|
+
return this.post("/ontology/query/structured", req);
|
|
815
|
+
}
|
|
816
|
+
async queryRelatedDomainObjects(req) {
|
|
817
|
+
return this.queryDomainStructured({
|
|
818
|
+
schema_id: req.schema_id,
|
|
819
|
+
select: req.far_type,
|
|
820
|
+
...req.project_uid ? { project_uid: req.project_uid } : {},
|
|
821
|
+
anchor: { type: req.entry_type, uid: req.uid },
|
|
822
|
+
path: [{
|
|
823
|
+
relation: req.relation,
|
|
824
|
+
entry_role: req.entry_role
|
|
825
|
+
}],
|
|
826
|
+
...req.where ? { where: req.where } : {},
|
|
827
|
+
...req.include_provenance ? { include: { provenance: true } } : {},
|
|
828
|
+
page: {
|
|
829
|
+
...req.limit != null ? { limit: req.limit } : {},
|
|
830
|
+
...req.offset != null ? { offset: req.offset } : {}
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
}
|
|
801
834
|
/**
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
*
|
|
805
|
-
* tools (`search_customers`, `summarize_customer`, …).
|
|
835
|
+
* Schema-qualified read-tool descriptors generated from every active
|
|
836
|
+
* ontology. Includes per-object discovery/point/context tools,
|
|
837
|
+
* relation-and-role-specific related tools, and one structured composite.
|
|
806
838
|
*/
|
|
807
839
|
async listOntologyTools() {
|
|
808
840
|
return this.get("/v1/ontology/tools");
|
|
809
841
|
}
|
|
810
|
-
async getDomainObject(uid) {
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
842
|
+
async getDomainObject(uid, binding) {
|
|
843
|
+
const query = new URLSearchParams();
|
|
844
|
+
if (binding) {
|
|
845
|
+
query.set("schema_id", binding.schema_id);
|
|
846
|
+
query.set("object_type", binding.object_type);
|
|
847
|
+
if (binding.project_uid) query.set("project_uid", binding.project_uid);
|
|
848
|
+
}
|
|
849
|
+
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
850
|
+
return this.get(`/ontology/object/${seg(uid)}${suffix}`);
|
|
851
|
+
}
|
|
852
|
+
async getDomainObjectContext(uid, depth, binding) {
|
|
853
|
+
const query = new URLSearchParams();
|
|
854
|
+
if (depth != null) query.set("depth", String(depth));
|
|
855
|
+
if (binding) {
|
|
856
|
+
query.set("schema_id", binding.schema_id);
|
|
857
|
+
query.set("object_type", binding.object_type);
|
|
858
|
+
if (binding.project_uid) query.set("project_uid", binding.project_uid);
|
|
859
|
+
}
|
|
860
|
+
const suffix = query.size > 0 ? `?${query.toString()}` : "";
|
|
861
|
+
return this.get(`/ontology/object/${seg(uid)}/context${suffix}`);
|
|
816
862
|
}
|
|
817
863
|
async getDomainObjectHistory(uid) {
|
|
818
|
-
return this.get(`/ontology/object/${uid}/history`);
|
|
864
|
+
return this.get(`/ontology/object/${seg(uid)}/history`);
|
|
819
865
|
}
|
|
820
866
|
async listDomainObjects(opts) {
|
|
821
867
|
const q = new URLSearchParams();
|
|
@@ -855,6 +901,12 @@ var MindGraph = class {
|
|
|
855
901
|
return this.post("/ontology/extract", req);
|
|
856
902
|
}
|
|
857
903
|
};
|
|
904
|
+
function createRequestId() {
|
|
905
|
+
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
906
|
+
return globalThis.crypto.randomUUID();
|
|
907
|
+
}
|
|
908
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
909
|
+
}
|
|
858
910
|
// Annotate the CommonJS export names for ESM import in node:
|
|
859
911
|
0 && (module.exports = {
|
|
860
912
|
MindGraph,
|