@ch4p/cli 0.1.5 → 0.2.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/dist/agent-AD6BNMQL.js +767 -0
- package/dist/agent-B46FPCBU.js +767 -0
- package/dist/canvas-GNDHSAGO.js +313 -0
- package/dist/canvas-KQCJ3HTX.js +313 -0
- package/dist/canvas-QHWTRFYK.js +313 -0
- package/dist/canvas-UPKEO32X.js +313 -0
- package/dist/chunk-3CYOOHMM.js +4412 -0
- package/dist/chunk-73DREVNL.js +1801 -0
- package/dist/chunk-F7E5NKMH.js +1835 -0
- package/dist/chunk-MABLWEGE.js +3409 -0
- package/dist/chunk-QDH3EMTH.js +4406 -0
- package/dist/chunk-TTAYQS7P.js +1854 -0
- package/dist/chunk-UNF4S4CA.js +1880 -0
- package/dist/chunk-WYXCGS55.js +1845 -0
- package/dist/dist-FJHVC7OP.js +25 -0
- package/dist/dist-FVYO37XH.js +25 -0
- package/dist/gateway-4EXQDINT.js +2259 -0
- package/dist/gateway-GCLV27HQ.js +2255 -0
- package/dist/gateway-OP2LW3H6.js +2165 -0
- package/dist/gateway-TK4BJRU6.js +2176 -0
- package/dist/index.js +6 -6
- package/dist/message-LTVKYQKB.js +189 -0
- package/dist/message-RLOYZWHL.js +189 -0
- package/dist/pairing-73HTMAVW.js +147 -0
- package/dist/pairing-GVBOSGP7.js +147 -0
- package/dist/pairing-NIC5WWBX.js +147 -0
- package/dist/tools-ORNZA5W6.js +50 -0
- package/package.json +17 -17
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PairingManager
|
|
3
|
+
} from "./chunk-F7E5NKMH.js";
|
|
4
|
+
import "./chunk-YSCX2QQQ.js";
|
|
5
|
+
import {
|
|
6
|
+
loadConfig
|
|
7
|
+
} from "./chunk-AORLXQHZ.js";
|
|
8
|
+
import {
|
|
9
|
+
BOLD,
|
|
10
|
+
DIM,
|
|
11
|
+
GREEN,
|
|
12
|
+
RED,
|
|
13
|
+
RESET,
|
|
14
|
+
TEAL,
|
|
15
|
+
YELLOW,
|
|
16
|
+
separator
|
|
17
|
+
} from "./chunk-NMGPBPNU.js";
|
|
18
|
+
|
|
19
|
+
// src/commands/pairing.ts
|
|
20
|
+
var manager = null;
|
|
21
|
+
function getManager() {
|
|
22
|
+
if (!manager) {
|
|
23
|
+
manager = new PairingManager();
|
|
24
|
+
}
|
|
25
|
+
return manager;
|
|
26
|
+
}
|
|
27
|
+
function handleGenerate(args) {
|
|
28
|
+
const label = args[0] ?? "CLI";
|
|
29
|
+
const pm = getManager();
|
|
30
|
+
try {
|
|
31
|
+
const code = pm.generateCode(label);
|
|
32
|
+
console.log(` ${GREEN}${BOLD}Pairing code generated${RESET}
|
|
33
|
+
`);
|
|
34
|
+
console.log(` ${BOLD}Code${RESET} ${TEAL}${BOLD}${code.code}${RESET}`);
|
|
35
|
+
console.log(` ${BOLD}Label${RESET} ${code.label ?? DIM + "none" + RESET}`);
|
|
36
|
+
console.log(` ${BOLD}Expires${RESET} ${code.expiresAt.toLocaleTimeString()}`);
|
|
37
|
+
console.log("");
|
|
38
|
+
console.log(` ${DIM}Share this code with the client. It can only be used once.${RESET}`);
|
|
39
|
+
console.log(` ${DIM}Exchange via: POST /pair { "code": "${code.code}" }${RESET}`);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
42
|
+
console.log(` ${RED}Failed to generate code:${RESET} ${message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function handleList() {
|
|
46
|
+
const pm = getManager();
|
|
47
|
+
const codes = pm.listCodes();
|
|
48
|
+
const clients = pm.listClients();
|
|
49
|
+
const stats = pm.stats();
|
|
50
|
+
console.log(` ${BOLD}Active Codes${RESET} ${DIM}(${stats.activeCodes})${RESET}`);
|
|
51
|
+
if (codes.length === 0) {
|
|
52
|
+
console.log(` ${DIM}No active pairing codes.${RESET}`);
|
|
53
|
+
} else {
|
|
54
|
+
for (const code of codes) {
|
|
55
|
+
const remaining = Math.max(0, Math.ceil((code.expiresAt.getTime() - Date.now()) / 1e3));
|
|
56
|
+
console.log(
|
|
57
|
+
` ${TEAL}${code.code}${RESET} ${DIM}label=${code.label ?? "none"} expires in ${remaining}s${RESET}`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
console.log("");
|
|
62
|
+
console.log(` ${BOLD}Paired Clients${RESET} ${DIM}(${stats.pairedClients})${RESET}`);
|
|
63
|
+
if (clients.length === 0) {
|
|
64
|
+
console.log(` ${DIM}No paired clients.${RESET}`);
|
|
65
|
+
} else {
|
|
66
|
+
for (const client of clients) {
|
|
67
|
+
console.log(
|
|
68
|
+
` ${GREEN}${client.tokenPreview}${RESET} ${DIM}label=${client.label ?? "none"} paired=${client.pairedAt.toLocaleTimeString()} seen=${client.lastSeenAt.toLocaleTimeString()}${RESET}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function handleRevoke(args) {
|
|
74
|
+
const target = args[0];
|
|
75
|
+
if (!target) {
|
|
76
|
+
console.log(` ${RED}Usage:${RESET} ch4p pairing revoke <code-or-token-hash>`);
|
|
77
|
+
console.log(` ${DIM}Use 'ch4p pairing list' to see active codes and clients.${RESET}`);
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const pm = getManager();
|
|
82
|
+
if (pm.revokeCode(target)) {
|
|
83
|
+
console.log(` ${GREEN}Revoked pairing code:${RESET} ${target}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (pm.revokeClient(target)) {
|
|
87
|
+
console.log(` ${GREEN}Revoked paired client:${RESET} ${target.slice(0, 16)}...`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
console.log(` ${YELLOW}Not found:${RESET} ${target}`);
|
|
91
|
+
console.log(` ${DIM}No active code or client matched. Use 'ch4p pairing list' to see current state.${RESET}`);
|
|
92
|
+
}
|
|
93
|
+
function handleStatus(requirePairing, port) {
|
|
94
|
+
const pm = getManager();
|
|
95
|
+
const stats = pm.stats();
|
|
96
|
+
console.log(` ${BOLD}Configuration${RESET}`);
|
|
97
|
+
console.log(` ${BOLD} Pairing required${RESET} ${requirePairing ? `${GREEN}yes${RESET}` : `${YELLOW}no${RESET}`}`);
|
|
98
|
+
console.log(` ${BOLD} Gateway port${RESET} ${port}`);
|
|
99
|
+
console.log("");
|
|
100
|
+
console.log(` ${BOLD}Local State${RESET}`);
|
|
101
|
+
console.log(` ${BOLD} Active codes${RESET} ${stats.activeCodes}`);
|
|
102
|
+
console.log(` ${BOLD} Paired clients${RESET} ${stats.pairedClients}`);
|
|
103
|
+
console.log("");
|
|
104
|
+
console.log(` ${DIM}Subcommands: generate [label], list, revoke <target>, status${RESET}`);
|
|
105
|
+
}
|
|
106
|
+
async function pairing(args) {
|
|
107
|
+
let config;
|
|
108
|
+
try {
|
|
109
|
+
config = loadConfig();
|
|
110
|
+
} catch (err) {
|
|
111
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
112
|
+
console.error(`
|
|
113
|
+
${RED}Failed to load config:${RESET} ${message}`);
|
|
114
|
+
console.error(` ${DIM}Run ${TEAL}ch4p onboard${DIM} to set up ch4p.${RESET}
|
|
115
|
+
`);
|
|
116
|
+
process.exitCode = 1;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const subcommand = args[0] ?? "status";
|
|
120
|
+
const subArgs = args.slice(1);
|
|
121
|
+
console.log(`
|
|
122
|
+
${TEAL}${BOLD}ch4p Pairing${RESET}`);
|
|
123
|
+
console.log(separator());
|
|
124
|
+
console.log("");
|
|
125
|
+
switch (subcommand) {
|
|
126
|
+
case "generate":
|
|
127
|
+
handleGenerate(subArgs);
|
|
128
|
+
break;
|
|
129
|
+
case "list":
|
|
130
|
+
handleList();
|
|
131
|
+
break;
|
|
132
|
+
case "revoke":
|
|
133
|
+
handleRevoke(subArgs);
|
|
134
|
+
break;
|
|
135
|
+
case "status":
|
|
136
|
+
handleStatus(config.gateway.requirePairing, config.gateway.port);
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
console.log(` ${RED}Unknown subcommand: ${subcommand}${RESET}`);
|
|
140
|
+
console.log(` ${DIM}Available: generate, list, revoke, status${RESET}`);
|
|
141
|
+
process.exitCode = 1;
|
|
142
|
+
}
|
|
143
|
+
console.log("");
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
pairing
|
|
147
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PairingManager
|
|
3
|
+
} from "./chunk-73DREVNL.js";
|
|
4
|
+
import "./chunk-YSCX2QQQ.js";
|
|
5
|
+
import {
|
|
6
|
+
loadConfig
|
|
7
|
+
} from "./chunk-AORLXQHZ.js";
|
|
8
|
+
import {
|
|
9
|
+
BOLD,
|
|
10
|
+
DIM,
|
|
11
|
+
GREEN,
|
|
12
|
+
RED,
|
|
13
|
+
RESET,
|
|
14
|
+
TEAL,
|
|
15
|
+
YELLOW,
|
|
16
|
+
separator
|
|
17
|
+
} from "./chunk-NMGPBPNU.js";
|
|
18
|
+
|
|
19
|
+
// src/commands/pairing.ts
|
|
20
|
+
var manager = null;
|
|
21
|
+
function getManager() {
|
|
22
|
+
if (!manager) {
|
|
23
|
+
manager = new PairingManager();
|
|
24
|
+
}
|
|
25
|
+
return manager;
|
|
26
|
+
}
|
|
27
|
+
function handleGenerate(args) {
|
|
28
|
+
const label = args[0] ?? "CLI";
|
|
29
|
+
const pm = getManager();
|
|
30
|
+
try {
|
|
31
|
+
const code = pm.generateCode(label);
|
|
32
|
+
console.log(` ${GREEN}${BOLD}Pairing code generated${RESET}
|
|
33
|
+
`);
|
|
34
|
+
console.log(` ${BOLD}Code${RESET} ${TEAL}${BOLD}${code.code}${RESET}`);
|
|
35
|
+
console.log(` ${BOLD}Label${RESET} ${code.label ?? DIM + "none" + RESET}`);
|
|
36
|
+
console.log(` ${BOLD}Expires${RESET} ${code.expiresAt.toLocaleTimeString()}`);
|
|
37
|
+
console.log("");
|
|
38
|
+
console.log(` ${DIM}Share this code with the client. It can only be used once.${RESET}`);
|
|
39
|
+
console.log(` ${DIM}Exchange via: POST /pair { "code": "${code.code}" }${RESET}`);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
42
|
+
console.log(` ${RED}Failed to generate code:${RESET} ${message}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function handleList() {
|
|
46
|
+
const pm = getManager();
|
|
47
|
+
const codes = pm.listCodes();
|
|
48
|
+
const clients = pm.listClients();
|
|
49
|
+
const stats = pm.stats();
|
|
50
|
+
console.log(` ${BOLD}Active Codes${RESET} ${DIM}(${stats.activeCodes})${RESET}`);
|
|
51
|
+
if (codes.length === 0) {
|
|
52
|
+
console.log(` ${DIM}No active pairing codes.${RESET}`);
|
|
53
|
+
} else {
|
|
54
|
+
for (const code of codes) {
|
|
55
|
+
const remaining = Math.max(0, Math.ceil((code.expiresAt.getTime() - Date.now()) / 1e3));
|
|
56
|
+
console.log(
|
|
57
|
+
` ${TEAL}${code.code}${RESET} ${DIM}label=${code.label ?? "none"} expires in ${remaining}s${RESET}`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
console.log("");
|
|
62
|
+
console.log(` ${BOLD}Paired Clients${RESET} ${DIM}(${stats.pairedClients})${RESET}`);
|
|
63
|
+
if (clients.length === 0) {
|
|
64
|
+
console.log(` ${DIM}No paired clients.${RESET}`);
|
|
65
|
+
} else {
|
|
66
|
+
for (const client of clients) {
|
|
67
|
+
console.log(
|
|
68
|
+
` ${GREEN}${client.tokenPreview}${RESET} ${DIM}label=${client.label ?? "none"} paired=${client.pairedAt.toLocaleTimeString()} seen=${client.lastSeenAt.toLocaleTimeString()}${RESET}`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function handleRevoke(args) {
|
|
74
|
+
const target = args[0];
|
|
75
|
+
if (!target) {
|
|
76
|
+
console.log(` ${RED}Usage:${RESET} ch4p pairing revoke <code-or-token-hash>`);
|
|
77
|
+
console.log(` ${DIM}Use 'ch4p pairing list' to see active codes and clients.${RESET}`);
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const pm = getManager();
|
|
82
|
+
if (pm.revokeCode(target)) {
|
|
83
|
+
console.log(` ${GREEN}Revoked pairing code:${RESET} ${target}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (pm.revokeClient(target)) {
|
|
87
|
+
console.log(` ${GREEN}Revoked paired client:${RESET} ${target.slice(0, 16)}...`);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
console.log(` ${YELLOW}Not found:${RESET} ${target}`);
|
|
91
|
+
console.log(` ${DIM}No active code or client matched. Use 'ch4p pairing list' to see current state.${RESET}`);
|
|
92
|
+
}
|
|
93
|
+
function handleStatus(requirePairing, port) {
|
|
94
|
+
const pm = getManager();
|
|
95
|
+
const stats = pm.stats();
|
|
96
|
+
console.log(` ${BOLD}Configuration${RESET}`);
|
|
97
|
+
console.log(` ${BOLD} Pairing required${RESET} ${requirePairing ? `${GREEN}yes${RESET}` : `${YELLOW}no${RESET}`}`);
|
|
98
|
+
console.log(` ${BOLD} Gateway port${RESET} ${port}`);
|
|
99
|
+
console.log("");
|
|
100
|
+
console.log(` ${BOLD}Local State${RESET}`);
|
|
101
|
+
console.log(` ${BOLD} Active codes${RESET} ${stats.activeCodes}`);
|
|
102
|
+
console.log(` ${BOLD} Paired clients${RESET} ${stats.pairedClients}`);
|
|
103
|
+
console.log("");
|
|
104
|
+
console.log(` ${DIM}Subcommands: generate [label], list, revoke <target>, status${RESET}`);
|
|
105
|
+
}
|
|
106
|
+
async function pairing(args) {
|
|
107
|
+
let config;
|
|
108
|
+
try {
|
|
109
|
+
config = loadConfig();
|
|
110
|
+
} catch (err) {
|
|
111
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
112
|
+
console.error(`
|
|
113
|
+
${RED}Failed to load config:${RESET} ${message}`);
|
|
114
|
+
console.error(` ${DIM}Run ${TEAL}ch4p onboard${DIM} to set up ch4p.${RESET}
|
|
115
|
+
`);
|
|
116
|
+
process.exitCode = 1;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const subcommand = args[0] ?? "status";
|
|
120
|
+
const subArgs = args.slice(1);
|
|
121
|
+
console.log(`
|
|
122
|
+
${TEAL}${BOLD}ch4p Pairing${RESET}`);
|
|
123
|
+
console.log(separator());
|
|
124
|
+
console.log("");
|
|
125
|
+
switch (subcommand) {
|
|
126
|
+
case "generate":
|
|
127
|
+
handleGenerate(subArgs);
|
|
128
|
+
break;
|
|
129
|
+
case "list":
|
|
130
|
+
handleList();
|
|
131
|
+
break;
|
|
132
|
+
case "revoke":
|
|
133
|
+
handleRevoke(subArgs);
|
|
134
|
+
break;
|
|
135
|
+
case "status":
|
|
136
|
+
handleStatus(config.gateway.requirePairing, config.gateway.port);
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
console.log(` ${RED}Unknown subcommand: ${subcommand}${RESET}`);
|
|
140
|
+
console.log(` ${DIM}Available: generate, list, revoke, status${RESET}`);
|
|
141
|
+
process.exitCode = 1;
|
|
142
|
+
}
|
|
143
|
+
console.log("");
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
pairing
|
|
147
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ToolRegistry
|
|
3
|
+
} from "./chunk-MABLWEGE.js";
|
|
4
|
+
import "./chunk-YSCX2QQQ.js";
|
|
5
|
+
import {
|
|
6
|
+
BOLD,
|
|
7
|
+
DIM,
|
|
8
|
+
GREEN,
|
|
9
|
+
MAGENTA,
|
|
10
|
+
RESET,
|
|
11
|
+
TEAL,
|
|
12
|
+
YELLOW,
|
|
13
|
+
separator
|
|
14
|
+
} from "./chunk-NMGPBPNU.js";
|
|
15
|
+
|
|
16
|
+
// src/commands/tools.ts
|
|
17
|
+
function weightLabel(weight) {
|
|
18
|
+
return weight === "lightweight" ? `${GREEN}lightweight${RESET}` : `${YELLOW}heavyweight${RESET}`;
|
|
19
|
+
}
|
|
20
|
+
async function tools() {
|
|
21
|
+
const registry = ToolRegistry.createDefault();
|
|
22
|
+
const allTools = registry.list();
|
|
23
|
+
console.log(`
|
|
24
|
+
${TEAL}${BOLD}ch4p Tools${RESET}`);
|
|
25
|
+
console.log(separator());
|
|
26
|
+
console.log("");
|
|
27
|
+
const maxNameLen = Math.max(...allTools.map((t) => t.name.length));
|
|
28
|
+
for (const tool of allTools) {
|
|
29
|
+
const paddedName = tool.name.padEnd(maxNameLen + 2, " ");
|
|
30
|
+
console.log(
|
|
31
|
+
` ${MAGENTA}${BOLD}${paddedName}${RESET}${tool.description}`
|
|
32
|
+
);
|
|
33
|
+
console.log(
|
|
34
|
+
` ${"".padEnd(maxNameLen + 2, " ")}${DIM}weight: ${RESET}${weightLabel(tool.weight)}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
const lwCount = allTools.filter((t) => t.weight === "lightweight").length;
|
|
38
|
+
const hwCount = allTools.filter((t) => t.weight === "heavyweight").length;
|
|
39
|
+
console.log(`
|
|
40
|
+
${separator()}`);
|
|
41
|
+
console.log(
|
|
42
|
+
` ${allTools.length} tools (${GREEN}${lwCount} lightweight${RESET}, ${YELLOW}${hwCount} heavyweight${RESET})`
|
|
43
|
+
);
|
|
44
|
+
console.log(` ${DIM}Lightweight tools run on the main thread.${RESET}`);
|
|
45
|
+
console.log(` ${DIM}Heavyweight tools run in worker threads for isolation.${RESET}
|
|
46
|
+
`);
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
tools
|
|
50
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ch4p/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Personal AI assistant platform — security-first, multi-channel, programmable",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -53,22 +53,22 @@
|
|
|
53
53
|
"playwright-core": "^1.50.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@ch4p/
|
|
57
|
-
"@ch4p/
|
|
58
|
-
"@ch4p/
|
|
59
|
-
"@ch4p/
|
|
60
|
-
"@ch4p/
|
|
61
|
-
"@ch4p/
|
|
62
|
-
"@ch4p/
|
|
63
|
-
"@ch4p/
|
|
64
|
-
"@ch4p/
|
|
65
|
-
"@ch4p/
|
|
66
|
-
"@ch4p/
|
|
67
|
-
"@ch4p/
|
|
68
|
-
"@ch4p/plugin-x402": "0.
|
|
69
|
-
"@ch4p/
|
|
70
|
-
"@ch4p/
|
|
71
|
-
"@ch4p/
|
|
56
|
+
"@ch4p/core": "0.2.0",
|
|
57
|
+
"@ch4p/tools": "0.2.0",
|
|
58
|
+
"@ch4p/observability": "0.2.0",
|
|
59
|
+
"@ch4p/engines": "0.2.0",
|
|
60
|
+
"@ch4p/gateway": "0.2.0",
|
|
61
|
+
"@ch4p/security": "0.2.0",
|
|
62
|
+
"@ch4p/skills": "0.2.0",
|
|
63
|
+
"@ch4p/agent": "0.2.0",
|
|
64
|
+
"@ch4p/providers": "0.2.0",
|
|
65
|
+
"@ch4p/channels": "0.2.0",
|
|
66
|
+
"@ch4p/supervisor": "0.2.0",
|
|
67
|
+
"@ch4p/memory": "0.2.0",
|
|
68
|
+
"@ch4p/plugin-x402": "0.2.0",
|
|
69
|
+
"@ch4p/canvas": "0.2.0",
|
|
70
|
+
"@ch4p/tunnels": "0.2.0",
|
|
71
|
+
"@ch4p/voice": "0.2.0"
|
|
72
72
|
},
|
|
73
73
|
"scripts": {
|
|
74
74
|
"build": "tsup",
|