@cotal-ai/web 0.0.0 → 0.11.1
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 +202 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/web/app.js +823 -0
- package/dist/web/graph.html +207 -0
- package/dist/web/graph.js +528 -0
- package/dist/web/index.html +350 -0
- package/dist/web.d.ts +14 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +327 -0
- package/dist/web.js.map +1 -0
- package/package.json +32 -5
- package/README.md +0 -4
package/dist/web.js
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { closeSync, openSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { CotalEndpoint, deliveryOf, parseSubject, spaceWildcard, mintCreds, newIdentity, clearChannel, } from "@cotal-ai/core";
|
|
7
|
+
import { c, connectOrExit, localProcessPath, userViewAuth, userViewAuthOrExit, } from "@cotal-ai/workspace";
|
|
8
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
/** The dashboard's default port and its branded address. The server binds loopback
|
|
10
|
+
* (127.0.0.1) but serves any Host, so `cotal.localhost` — which Chrome/Firefox/Edge
|
|
11
|
+
* resolve to loopback with no DNS setup — just works. (Safari may not resolve
|
|
12
|
+
* `*.localhost`; plain http://127.0.0.1:7799 always does.) */
|
|
13
|
+
export const WEB_PORT = 7799;
|
|
14
|
+
export const WEB_URL = `http://cotal.localhost:${WEB_PORT}/`;
|
|
15
|
+
export const webProcess = {
|
|
16
|
+
kind: "local-process",
|
|
17
|
+
name: "web",
|
|
18
|
+
label: "web dashboard",
|
|
19
|
+
order: 40,
|
|
20
|
+
pidFile: "web.pid",
|
|
21
|
+
};
|
|
22
|
+
function pidAlive(pid) {
|
|
23
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
24
|
+
return false;
|
|
25
|
+
try {
|
|
26
|
+
process.kill(pid, 0);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
return e.code === "EPERM";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Atomically claim this mesh's web pidfile so concurrent custom-port launches cannot overwrite it. */
|
|
34
|
+
function claimPid(path) {
|
|
35
|
+
let created = false;
|
|
36
|
+
try {
|
|
37
|
+
const fd = openSync(path, "wx", 0o600);
|
|
38
|
+
created = true;
|
|
39
|
+
try {
|
|
40
|
+
writeFileSync(fd, String(process.pid));
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
closeSync(fd);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
if (created)
|
|
48
|
+
rmSync(path, { force: true });
|
|
49
|
+
if (e.code !== "EEXIST")
|
|
50
|
+
throw e;
|
|
51
|
+
const raw = readFileSync(path, "utf8").trim();
|
|
52
|
+
if (raw.startsWith("removing:")) {
|
|
53
|
+
const owner = Number(raw.slice("removing:".length));
|
|
54
|
+
throw new Error(pidAlive(owner)
|
|
55
|
+
? `web extension removal is in progress (pid ${owner})`
|
|
56
|
+
: `web dashboard has a stale extension-removal reservation at ${path} - remove it and retry`);
|
|
57
|
+
}
|
|
58
|
+
const prior = Number(raw);
|
|
59
|
+
if (pidAlive(prior))
|
|
60
|
+
throw new Error(`web dashboard is already running for this mesh (pid ${prior})`);
|
|
61
|
+
throw new Error(`web dashboard has a stale pidfile at ${path} - clean it with \`cotal down web\`, then retry`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function releasePid(path) {
|
|
65
|
+
try {
|
|
66
|
+
if (readFileSync(path, "utf8").trim() === String(process.pid))
|
|
67
|
+
rmSync(path, { force: true });
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Already removed by `down` or another cleanup path.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const PAGE = {
|
|
74
|
+
"/": { path: join(here, "web/index.html"), type: "text/html; charset=utf-8" },
|
|
75
|
+
"/app.js": { path: join(here, "web/app.js"), type: "text/javascript; charset=utf-8" },
|
|
76
|
+
"/graph": { path: join(here, "web/graph.html"), type: "text/html; charset=utf-8" },
|
|
77
|
+
"/graph.js": { path: join(here, "web/graph.js"), type: "text/javascript; charset=utf-8" },
|
|
78
|
+
};
|
|
79
|
+
/** A live observability dashboard for a space, served over HTTP + SSE. A read-only
|
|
80
|
+
* observer endpoint (invisible to peers) feeds the page presence, channel history,
|
|
81
|
+
* and a live message stream — no manager required. Bound to loopback. */
|
|
82
|
+
export async function web(args) {
|
|
83
|
+
const values = args.values;
|
|
84
|
+
// Resolve WHICH running mesh + creds (admin god-view: shows DMs + anycast), then DROP the account
|
|
85
|
+
// seed. The dashboard is a loopback HTTP process; holding the space signing seed (`auth` — it can
|
|
86
|
+
// mint ANY identity/role) for the whole session would make a dashboard compromise = full account
|
|
87
|
+
// control. Instead pre-mint ONE scoped `channel-purger` cred for the only write path (channel delete
|
|
88
|
+
// = filtered CHAT purge + a channel-registry key delete) and let the seed fall out of scope here, so
|
|
89
|
+
// it isn't reachable from the request handlers. `--creds` / open mode have no seed → the connection
|
|
90
|
+
// creds carry the purge rights.
|
|
91
|
+
//
|
|
92
|
+
// USER MODE: the god view rides an exchange-gated "admin" VIEW bearer (ledger scope "admin",
|
|
93
|
+
// fresh-checked at every mint and every connect) — standing via a bearer SOURCE so the tap
|
|
94
|
+
// survives the ≤5-minute token life. No pre-minted purge cred: channel delete mints a one-shot
|
|
95
|
+
// "channel-purger" view per action, so each destructive click is a fresh ledger check, and
|
|
96
|
+
// `cotal actor revoke` kills the dashboard live (eviction) while a scope edit bites at the next
|
|
97
|
+
// refresh.
|
|
98
|
+
const { conn, user } = await (async () => {
|
|
99
|
+
const conn = await connectOrExit(values, "admin");
|
|
100
|
+
return { conn, user: conn.bearer ? await userViewAuthOrExit(conn, "admin") : undefined };
|
|
101
|
+
})();
|
|
102
|
+
const { server, space } = conn;
|
|
103
|
+
const pidPath = conn.root ? localProcessPath(webProcess.pidFile, { root: conn.root, space }) : undefined;
|
|
104
|
+
if (pidPath) {
|
|
105
|
+
claimPid(pidPath);
|
|
106
|
+
process.once("exit", () => releasePid(pidPath));
|
|
107
|
+
}
|
|
108
|
+
const purgeCreds = !user && conn.auth ? await mintCreds(conn.auth, newIdentity(), "channel-purger") : conn.creds;
|
|
109
|
+
const port = values.port ? Number(values.port) : WEB_PORT;
|
|
110
|
+
// Observer: never registers presence, never consumes an inbox — invisible to peers.
|
|
111
|
+
const ep = new CotalEndpoint({
|
|
112
|
+
space,
|
|
113
|
+
servers: server,
|
|
114
|
+
...(user
|
|
115
|
+
? { bearer: user.source, sentinelCreds: user.sentinelCreds, card: { owner: user.owner, actor: user.actor, name: "web", kind: "endpoint" } }
|
|
116
|
+
: { creds: conn.creds, card: { name: "web", kind: "endpoint" } }),
|
|
117
|
+
channels: [],
|
|
118
|
+
consume: false, // observer: reads via tap + history + presence-watch, binds no durables
|
|
119
|
+
registerPresence: false,
|
|
120
|
+
watchPresence: true,
|
|
121
|
+
});
|
|
122
|
+
ep.on("error", (e) => console.error(c.red("! " + e.message)));
|
|
123
|
+
await ep.start();
|
|
124
|
+
const clients = new Set();
|
|
125
|
+
const send = (res, event, data) => res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
126
|
+
const broadcast = (event, data) => {
|
|
127
|
+
for (const res of clients)
|
|
128
|
+
if (!res.writableEnded)
|
|
129
|
+
send(res, event, data);
|
|
130
|
+
};
|
|
131
|
+
// Presence changes → push the whole roster; the client just re-renders it.
|
|
132
|
+
ep.on("presence", () => broadcast("roster", ep.getRoster()));
|
|
133
|
+
// Broker-sourced channel membership (the authoritative graph spokes): push a `membership` SSE event
|
|
134
|
+
// on every feed change (debounced; the client re-reads the snapshot). Best-effort — a space without the
|
|
135
|
+
// feed (no delivery daemon, or provisioned before this feature) simply never emits, and the graph
|
|
136
|
+
// degrades to traffic-only. The admin cred carries the read grant; agents never do.
|
|
137
|
+
let membershipWatch;
|
|
138
|
+
const pushMembership = debounce(() => {
|
|
139
|
+
void ep.readMembership().then((m) => broadcast("membership", m)).catch(() => { });
|
|
140
|
+
}, 150);
|
|
141
|
+
try {
|
|
142
|
+
membershipWatch = await ep.watchMembership(pushMembership);
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
console.error(c.dim(`• membership feed unavailable - graph shows traffic only (${e.message})`));
|
|
146
|
+
}
|
|
147
|
+
// Every comm on the mesh (chat / unicast / anycast) → push to the live feed. The admin cred
|
|
148
|
+
// allows the whole space, so the observer taps everything — DMs + anycast included.
|
|
149
|
+
const tapSubject = spaceWildcard(space);
|
|
150
|
+
ep.tap((subject, msg) => {
|
|
151
|
+
const mode = deliveryOf(subject);
|
|
152
|
+
if (!mode || !msg)
|
|
153
|
+
return;
|
|
154
|
+
// senderId is the subject's sender token — the *verified* publisher (the server
|
|
155
|
+
// policed who could publish it), vs the advisory `from` in the payload.
|
|
156
|
+
const senderId = parseSubject(subject)?.sender;
|
|
157
|
+
broadcast("message", { mode, senderId, msg });
|
|
158
|
+
}, { subject: tapSubject });
|
|
159
|
+
const httpServer = createServer(async (req, res) => {
|
|
160
|
+
const path = (req.url ?? "/").split("?")[0];
|
|
161
|
+
const query = new URLSearchParams((req.url ?? "").split("?")[1] ?? "");
|
|
162
|
+
if (path === "/feed") {
|
|
163
|
+
res.writeHead(200, {
|
|
164
|
+
"content-type": "text/event-stream",
|
|
165
|
+
"cache-control": "no-cache",
|
|
166
|
+
connection: "keep-alive",
|
|
167
|
+
});
|
|
168
|
+
clients.add(res);
|
|
169
|
+
send(res, "roster", ep.getRoster());
|
|
170
|
+
// Seed this client's graph with the current membership snapshot (the live tap only carries
|
|
171
|
+
// post-connect traffic; membership is state, so a fresh client needs it explicitly).
|
|
172
|
+
void ep.readMembership().then((m) => { if (!res.writableEnded)
|
|
173
|
+
send(res, "membership", m); }).catch(() => { });
|
|
174
|
+
req.on("close", () => clients.delete(res));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (path === "/api/meta")
|
|
178
|
+
return json(res, { space });
|
|
179
|
+
if (path === "/api/roster")
|
|
180
|
+
return json(res, ep.getRoster());
|
|
181
|
+
if (path === "/api/membership") {
|
|
182
|
+
// Authoritative who-is-subscribed (broker-sourced); {asOf, members:[{id,live,durable,observedAt}]}.
|
|
183
|
+
// An unavailable feed returns an empty snapshot so the graph cleanly degrades to traffic-only.
|
|
184
|
+
try {
|
|
185
|
+
return json(res, await ep.readMembership());
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return json(res, { asOf: undefined, members: [] });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (path === "/api/channels")
|
|
192
|
+
return json(res, await ep.listChannels());
|
|
193
|
+
if (path === "/api/activity") {
|
|
194
|
+
// Backfill the all-activity feed: merge recent channel history with DM history (the live
|
|
195
|
+
// SSE tap only carries messages from after a client connects). Entries are mode-tagged
|
|
196
|
+
// ({mode, msg}) to match the live feed so DMs render as DMs.
|
|
197
|
+
const limit = query.get("limit") ? Number(query.get("limit")) : 200;
|
|
198
|
+
const chans = await ep.listChannels();
|
|
199
|
+
const chat = (await Promise.all(chans.map((ch) => ep.channelHistory(ch.channel, { limit }))))
|
|
200
|
+
.flat()
|
|
201
|
+
.map((msg) => ({ mode: "chat", msg }));
|
|
202
|
+
const dms = (await ep.dmHistory({ limit })).map((msg) => ({ mode: "unicast", msg }));
|
|
203
|
+
const all = [...chat, ...dms].sort((a, b) => a.msg.ts - b.msg.ts);
|
|
204
|
+
return json(res, all.slice(-limit));
|
|
205
|
+
}
|
|
206
|
+
if (path === "/api/dms") {
|
|
207
|
+
// DM history for the Direct-messages lens (god-view); the client groups it by peer/pair.
|
|
208
|
+
const limit = query.get("limit") ? Number(query.get("limit")) : 500;
|
|
209
|
+
return json(res, await ep.dmHistory({ limit }));
|
|
210
|
+
}
|
|
211
|
+
if (path.startsWith("/api/channels/") && path.endsWith("/history")) {
|
|
212
|
+
const name = decodeURIComponent(path.slice("/api/channels/".length, -"/history".length));
|
|
213
|
+
const limit = query.get("limit") ? Number(query.get("limit")) : 200;
|
|
214
|
+
return json(res, await ep.channelHistory(name, { limit }));
|
|
215
|
+
}
|
|
216
|
+
// Delete a channel and its content. The only write path on this otherwise read-only
|
|
217
|
+
// dashboard, so it's POST-gated and guarded by a confirm in the UI. Uses the manager cred
|
|
218
|
+
// pre-minted at startup (auth mode) or the connection creds (open / --creds), NOT the account
|
|
219
|
+
// seed (which we dropped). A wildcard / missing channel is a 400.
|
|
220
|
+
if (path === "/api/channel/delete" && req.method === "POST") {
|
|
221
|
+
const body = await readBody(req).catch(() => ({}));
|
|
222
|
+
const channel = typeof body.channel === "string" ? body.channel : "";
|
|
223
|
+
if (!channel) {
|
|
224
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
225
|
+
res.end(JSON.stringify({ error: "channel required" }));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
// User mode mints a one-shot channel-purger VIEW per delete — the ledger is re-checked at
|
|
230
|
+
// this click, and a mid-session revoke becomes this handler's 400, never a dead dashboard.
|
|
231
|
+
const result = user
|
|
232
|
+
? await userViewAuth(conn, "channel-purger").then((p) => clearChannel({ servers: server, space, channel, bearer: p.bearer, sentinelCreds: p.sentinelCreds }))
|
|
233
|
+
: await clearChannel({ servers: server, space, channel, creds: purgeCreds });
|
|
234
|
+
return json(res, { ok: true, ...result });
|
|
235
|
+
}
|
|
236
|
+
catch (e) {
|
|
237
|
+
res.writeHead(400, { "content-type": "application/json" });
|
|
238
|
+
res.end(JSON.stringify({ error: e.message }));
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const file = PAGE[path];
|
|
243
|
+
if (file) {
|
|
244
|
+
// no-cache: always revalidate so a `cotal` upgrade's new dashboard code is picked up on
|
|
245
|
+
// reload — a stale cached graph.js silently runs old behavior (e.g. pre-fix filters).
|
|
246
|
+
res.writeHead(200, { "content-type": file.type, "cache-control": "no-cache" });
|
|
247
|
+
res.end(readFileSync(file.path));
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
res.writeHead(404).end("not found");
|
|
251
|
+
});
|
|
252
|
+
// Comment ping keeps idle SSE connections alive through proxies.
|
|
253
|
+
const ping = setInterval(() => {
|
|
254
|
+
for (const res of clients)
|
|
255
|
+
if (!res.writableEnded)
|
|
256
|
+
res.write(": ping\n\n");
|
|
257
|
+
}, 20_000);
|
|
258
|
+
httpServer.on("error", (e) => {
|
|
259
|
+
if (e.code === "EADDRINUSE")
|
|
260
|
+
console.error(c.red(`Port ${port} is in use. Pass --port <n>.`));
|
|
261
|
+
else
|
|
262
|
+
console.error(c.red("! " + e.message));
|
|
263
|
+
process.exit(1);
|
|
264
|
+
});
|
|
265
|
+
await new Promise((ready) => httpServer.listen(port, "127.0.0.1", ready));
|
|
266
|
+
// Branded URL only when on the default port; a custom --port keeps the plain loopback address.
|
|
267
|
+
const url = port === WEB_PORT ? WEB_URL : `http://127.0.0.1:${port}/`;
|
|
268
|
+
console.log(`${c.bold("Cotal web")} - observing space ${c.bold(space)}`);
|
|
269
|
+
console.log(c.dim(" god-view - DMs + anycast visible"));
|
|
270
|
+
console.log(` ${c.cyan(url)} ${c.dim("(Ctrl-C to stop)")}`);
|
|
271
|
+
if (!values["no-open"])
|
|
272
|
+
openBrowser(url);
|
|
273
|
+
let shuttingDown = false;
|
|
274
|
+
const shutdown = async () => {
|
|
275
|
+
if (shuttingDown)
|
|
276
|
+
return;
|
|
277
|
+
shuttingDown = true;
|
|
278
|
+
clearInterval(ping);
|
|
279
|
+
membershipWatch?.stop();
|
|
280
|
+
for (const res of clients)
|
|
281
|
+
res.end();
|
|
282
|
+
httpServer.close();
|
|
283
|
+
await ep.stop();
|
|
284
|
+
if (pidPath)
|
|
285
|
+
releasePid(pidPath);
|
|
286
|
+
process.exit(0);
|
|
287
|
+
};
|
|
288
|
+
process.on("SIGINT", () => void shutdown());
|
|
289
|
+
process.on("SIGTERM", () => void shutdown());
|
|
290
|
+
await new Promise(() => { });
|
|
291
|
+
}
|
|
292
|
+
function json(res, data) {
|
|
293
|
+
res.writeHead(200, { "content-type": "application/json" });
|
|
294
|
+
res.end(JSON.stringify(data));
|
|
295
|
+
}
|
|
296
|
+
/** Trailing-edge debounce — coalesces a burst of membership-feed deltas into one push. */
|
|
297
|
+
function debounce(fn, ms) {
|
|
298
|
+
let t;
|
|
299
|
+
return () => {
|
|
300
|
+
if (t)
|
|
301
|
+
clearTimeout(t);
|
|
302
|
+
t = setTimeout(fn, ms);
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
async function readBody(req) {
|
|
306
|
+
const chunks = [];
|
|
307
|
+
for await (const chunk of req)
|
|
308
|
+
chunks.push(chunk);
|
|
309
|
+
const raw = Buffer.concat(chunks).toString("utf8");
|
|
310
|
+
return raw ? JSON.parse(raw) : {};
|
|
311
|
+
}
|
|
312
|
+
/** Best-effort open of the dashboard in the default browser. The URL is already
|
|
313
|
+
* printed, so a failure here is harmless — never block startup on it. */
|
|
314
|
+
function openBrowser(url) {
|
|
315
|
+
const [cmd, args] = process.platform === "darwin"
|
|
316
|
+
? ["open", [url]]
|
|
317
|
+
: process.platform === "win32"
|
|
318
|
+
? ["cmd", ["/c", "start", "", url]]
|
|
319
|
+
: ["xdg-open", [url]];
|
|
320
|
+
try {
|
|
321
|
+
spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
/* no opener on this platform — the printed URL is the fallback */
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=web.js.map
|
package/dist/web.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cotal-ai/web",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"description": "Cotal browser observability dashboard — adds the `web` command to the cotal CLI (install: cotal ext add @cotal-ai/web).",
|
|
4
|
+
"version": "0.11.1",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
|
-
"homepage": "https://github.com/Cotal-AI/Cotal",
|
|
7
6
|
"repository": {
|
|
8
7
|
"type": "git",
|
|
9
|
-
"url": "
|
|
8
|
+
"url": "https://github.com/Cotal-AI/Cotal.git",
|
|
9
|
+
"directory": "implementations/web"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@cotal-ai/core": "*",
|
|
22
|
+
"@cotal-ai/workspace": "*"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@cotal-ai/core": "0.11.2",
|
|
26
|
+
"@cotal-ai/workspace": "0.11.2"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist"
|
|
30
|
+
],
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
36
|
+
"build": "tsc -p tsconfig.json && rm -rf dist/web && cp -R src/web dist/web"
|
|
10
37
|
}
|
|
11
|
-
}
|
|
38
|
+
}
|
package/README.md
DELETED