22 Commits

Author SHA1 Message Date
bc7c658293 update: CoreMirror.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m12s
2025-04-09 12:28:56 -04:00
4d84e69bb5 update: libbacktrace. 2025-04-09 12:26:44 -04:00
03fac74908 update: c-ares 1.34.5. 2025-04-09 12:24:55 -04:00
5252ff1ecf update: OpenSSL 3.5.0. 2025-04-09 12:22:12 -04:00
20100d3fd4 ssb: Oops, that event was Firefox-specific.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m36s
2025-04-07 22:35:40 -04:00
dd3b2656ad ssb: Message % menu tweaks. Show on click. Hide when clicking off. Bury the message ID further.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-04-07 21:39:14 -04:00
657f25e22b ssb: Bring back the date. Whoops.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m37s
2025-04-05 22:05:26 -04:00
8be354fc49 ssb: It is troubling to me that querying like this is so much faster.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m37s
2025-04-05 18:40:00 -04:00
e574758340 ssb: Make a message % context menu with some new options to begin to declutter the message view itself.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m42s
2025-04-05 17:53:47 -04:00
40cf519492 http: I caught an http listener lingering on shutdown. Clean them up more correctly. Possible progress on #108.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m38s
2025-04-05 09:53:47 -04:00
0e4fda54e9 fdroid: Lean into SSB in the description.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m45s
2025-04-03 12:31:59 -04:00
868f91e1ef docs: Noticed some errors in the readme.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 32m38s
2025-04-02 20:01:26 -04:00
b9000c154f apps: Add a very wip web app.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m8s
2025-04-02 18:07:25 -04:00
894c72a82f ssb: Still chasing faster loads of the default news query.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m59s
2025-04-02 12:44:17 -04:00
c128cfc25c ssb: This makes the channels query sub-second for me.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m39s
2025-04-01 19:50:13 -04:00
36c88b463c buttfeed: Add PatchFox.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m41s
2025-04-01 08:13:54 -04:00
8a66e74074 ssb: Faster *and* correct. I think.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m43s
2025-03-30 13:18:16 -04:00
ea60b165da ssb: Had my refs backward.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m17s
2025-03-30 12:27:36 -04:00
1011e0026b ssb: Rearrange indexes for an overall faster load on mobile for me. Tidy up some things along the way.
Some checks are pending
Build Tilde Friends / Build-All (push) Has started running
2025-03-30 12:16:23 -04:00
9462521287 update: CodeMirror.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m53s
2025-03-27 12:37:13 -04:00
576022c41a build: 0.0.30-wip, let's gooooo.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 30m42s
2025-03-26 20:19:28 -04:00
70c38b7ea8 build: nix => 0.0.29.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled
2025-03-26 18:57:05 -04:00
24 changed files with 447 additions and 214 deletions

View File

@ -16,9 +16,9 @@ MAKEFLAGS += --no-builtin-rules
## LD := Linker. ## LD := Linker.
## ANDROID_SDK := Path to the Android SDK. ## ANDROID_SDK := Path to the Android SDK.
VERSION_CODE := 34 VERSION_CODE := 35
VERSION_CODE_IOS := 11 VERSION_CODE_IOS := 12
VERSION_NUMBER := 0.0.29 VERSION_NUMBER := 0.0.30-wip
VERSION_NAME := This program kills fascists. VERSION_NAME := This program kills fascists.
IPHONEOS_VERSION_MIN=14.0 IPHONEOS_VERSION_MIN=14.0

View File

@ -38,7 +38,7 @@ dependencies in the right places.
### Requirements ### Requirements
System OpenSSL libraries are assumed to be available on Haiku and OpenSSL. System OpenSSL libraries are assumed to be available on Haiku and OpenBSD.
On MacOS, Xcode's command-line tools are expected to be available. On MacOS, Xcode's command-line tools are expected to be available.
@ -55,9 +55,8 @@ standard.
## Running ## Running
By default, running the built `out/debug/tildefriends` executable will start a By default, running the built `out/debug/tildefriends` executable will start a
web server at <http://localhost:12345/>. It expects to be run with the web server at <http://localhost:12345/>. `tildefriends -h` lists further
repository root as the current working directory. `tildefriends -h` lists options.
further options.
The first user to create an account and log in will be granted administrative The first user to create an account and log in will be granted administrative
privileges. Further administration can be done in the `admin` app at privileges. Further administration can be done in the `admin` app at

View File

@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&wOd/+1l5wpywBlfxC1Lm0i+HhYidrgSfrn9LRX7qy2w=.sha256" "previous": "&VvfYCIWHlYDtlgOBhDByg1l9rt8NIRt/TCurKx2/AWE=.sha256"
} }

View File

@ -184,9 +184,9 @@ class TfElement extends LitElement {
json_each(?1) AS following json_each(?1) AS following
WHERE WHERE
messages.author = following.value AND messages.author = following.value AND
messages.content ->> 'type' = 'about' AND
messages.rowid > ?3 AND messages.rowid > ?3 AND
messages.rowid <= ?4 AND messages.rowid <= ?4
json_extract(messages.content, '$.type') = 'about'
UNION UNION
SELECT SELECT
messages.author, json(messages.content) AS content, messages.sequence messages.author, json(messages.content) AS content, messages.sequence
@ -195,8 +195,8 @@ class TfElement extends LitElement {
json_each(?2) AS following json_each(?2) AS following
WHERE WHERE
messages.author = following.value AND messages.author = following.value AND
messages.rowid <= ?4 AND messages.content ->> 'type' = 'about' AND
json_extract(messages.content, '$.type') = 'about' messages.rowid <= ?4
ORDER BY messages.author, messages.sequence ORDER BY messages.author, messages.sequence
`, `,
[ [
@ -382,7 +382,6 @@ class TfElement extends LitElement {
'🔐': latest[0], '🔐': latest[0],
}); });
console.log('private took', (new Date() - start_time) / 1000.0); console.log('private took', (new Date() - start_time) / 1000.0);
console.log(latest);
self.private_messages = latest[1]; self.private_messages = latest[1];
}); });
} }

View File

@ -33,6 +33,25 @@ class TfMessageElement extends LitElement {
this.channel_unread = -1; this.channel_unread = -1;
} }
connectedCallback() {
super.connectedCallback();
this._click_callback = this.document_click.bind(this);
document.body.addEventListener('mouseup', this._click_callback);
}
disconnectedCallback() {
super.disconnectedCallback();
document.body.removeEventListener('mouseup', this._click_callback);
}
document_click(event) {
let content = this.renderRoot.querySelector('.w3-dropdown-content');
let target = event.target;
if (content && !content.contains(target)) {
content.classList.remove('w3-show');
}
}
show_reply() { show_reply() {
let event = new CustomEvent('tf-draft', { let event = new CustomEvent('tf-draft', {
bubbles: true, bubbles: true,
@ -371,62 +390,61 @@ class TfMessageElement extends LitElement {
return content; return content;
} }
render_raw_button() { copy_id(event) {
navigator.clipboard.writeText(this.message?.id);
}
toggle_menu(event) {
event.srcElement.parentNode
.querySelector('.w3-dropdown-content')
.classList.toggle('w3-show');
}
render_menu() {
let content = this.get_content(); let content = this.get_content();
let raw_button; let formats = [['message', 'Message']];
switch (this.format) { if (content?.type == 'post' || content?.type == 'blog') {
case 'raw': formats.push(['md', 'Markdown']);
if (content?.type == 'post' || content?.type == 'blog') {
raw_button = html`<button
class="w3-button w3-theme-d1"
@click=${() => (this.format = 'md')}
>
Markdown
</button>`;
} else {
raw_button = html`<button
class="w3-button w3-theme-d1"
@click=${() => (this.format = 'message')}
>
Message
</button>`;
}
break;
case 'md':
raw_button = html`<button
class="w3-button w3-theme-d1"
@click=${() => (this.format = 'message')}
>
Message
</button>`;
break;
case 'decrypted':
raw_button = html`<button
class="w3-button w3-theme-d1"
@click=${() => (this.format = 'raw')}
>
Raw
</button>`;
break;
default:
if (this.message.decrypted) {
raw_button = html`<button
class="w3-button w3-theme-d1"
@click=${() => (this.format = 'decrypted')}
>
Decrypted
</button>`;
} else {
raw_button = html`<button
class="w3-button w3-theme-d1"
@click=${() => (this.format = 'raw')}
>
Raw
</button>`;
}
break;
} }
return raw_button; if (this.message?.decrypted) {
formats.push(['decrypted', 'Decrypted']);
}
formats.push(['raw', 'Raw']);
return html`
<div class="w3-bar-item w3-right">
<button class="w3-button w3-theme-d1" @click=${this.toggle_menu}>
%
</button>
<div
class="w3-dropdown-content w3-bar-block w3-card-4 w3-theme-l1"
style="right: 48px"
>
<a
target="_top"
class="w3-button w3-bar-item"
href=${'#' + encodeURIComponent(this.message?.id)}
>View Message</a
>
<button
class="w3-button w3-bar-item w3-border-bottom"
@click=${this.copy_id}
>
Copy ID
</button>
${formats.map(
([format, name]) => html`
<button
class="w3-button w3-bar-item"
style=${format == this.format ? 'font-weight: bold' : ''}
@click=${() => (this.format = format)}
>
${name}
</button>
`
)}
</div>
</div>
`;
} }
render_header() { render_header() {
@ -440,14 +458,10 @@ class TfMessageElement extends LitElement {
<span class="w3-bar-item"> <span class="w3-bar-item">
<tf-user id=${this.message.author} .users=${this.users}></tf-user> <tf-user id=${this.message.author} .users=${this.users}></tf-user>
</span> </span>
${is_encrypted} ${is_encrypted} ${this.render_menu()}
<span class="w3-bar-item w3-right">${this.render_raw_button()}</span> <div class="w3-bar-item w3-right" style="text-wrap: nowrap">
<span class="w3-bar-item w3-right" style="text-wrap: nowrap" ${new Date(this.message.timestamp).toLocaleString()}
><a target="_top" href=${'#' + encodeURIComponent(this.message.id)} </div>
>%</a
>
${new Date(this.message.timestamp).toLocaleString()}</span
>
</header> </header>
`; `;
} }

View File

@ -159,6 +159,7 @@ class TfTabNewsFeedElement extends LitElement {
); );
result = (await this.decrypt(result)).filter((x) => x.decrypted); result = (await this.decrypt(result)).filter((x) => x.decrypted);
} else { } else {
let t0 = new Date();
result = await tfrpc.rpc.query( result = await tfrpc.rpc.query(
` `
WITH WITH
@ -166,26 +167,45 @@ class TfTabNewsFeedElement extends LitElement {
SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature SELECT messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM messages FROM messages
JOIN json_each(?) AS following ON messages.author = following.value JOIN json_each(?) AS following ON messages.author = following.value
WHERE timestamp >= 0 AND timestamp < ?3), ),
news AS ( news AS (
SELECT * FROM all_news SELECT * FROM all_news
WHERE (?2 IS NULL OR all_news.timestamp >= ?2) AND all_news.timestamp < ?3 WHERE all_news.timestamp < ?3 AND (?2 IS NULL OR all_news.timestamp >= ?2)
ORDER BY timestamp DESC LIMIT 20 ORDER BY timestamp DESC LIMIT 20
) )
SELECT FALSE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM news
JOIN messages_refs ON news.id = messages_refs.ref
JOIN messages ON messages_refs.message = messages.id
UNION
SELECT FALSE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM news
JOIN messages_refs ON news.id = messages_refs.message
JOIN messages ON messages_refs.ref = messages.id
UNION
SELECT TRUE AS is_primary, news.* FROM news SELECT TRUE AS is_primary, news.* FROM news
`, `,
[JSON.stringify(this.following), start_time, end_time] [JSON.stringify(this.following), start_time, end_time]
); );
let news_length = result.length;
let t1 = new Date();
let refs = await tfrpc.rpc.query(
`
WITH
news AS (
SELECT value AS id FROM json_each(?)
)
SELECT refs_out.ref AS ref FROM messages_refs refs_out JOIN news ON refs_out.message = news.id
UNION
SELECT refs_in.message AS ref FROM messages_refs refs_in JOIN news ON refs_in.ref = news.id
`,
[JSON.stringify(result.map((x) => x.id))]
);
let t2 = new Date();
let related_messages = await tfrpc.rpc.query(
`
SELECT FALSE AS is_primary, messages.rowid, messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
FROM messages
JOIN json_each(?2) refs ON messages.id = refs.value
JOIN json_each(?1) AS following ON messages.author = following.value
`,
[JSON.stringify(this.following), JSON.stringify(refs.map((x) => x.ref))]
);
result = [].concat(result, related_messages);
let t3 = new Date();
console.log(
`load of ${result.length} rows took ${(t3 - t0) / 1000} (${(t1 - t0) / 1000} to find ${news_length} messages, ${(t2 - t1) / 1000} to find ${refs.length} refs, and ${(t3 - t2) / 1000} to find ${related_messages.length} related messages) following=${this.following.length} st=${start_time} et=${end_time}`
);
} }
this.time_loading = undefined; this.time_loading = undefined;
return result; return result;
@ -311,7 +331,7 @@ class TfTabNewsFeedElement extends LitElement {
this.messages = this.merge_messages(this.messages, messages); this.messages = this.merge_messages(this.messages, messages);
this.time_loading = undefined; this.time_loading = undefined;
console.log( console.log(
`loading messages done for ${self.whoami} in ${(new Date() - start_time) / 1000}s` `loading ${messages.length} messages done for ${self.whoami} in ${(new Date() - start_time) / 1000}s`
); );
} }

View File

@ -285,7 +285,7 @@ class TfTabNewsElement extends LitElement {
return cache(html` return cache(html`
${this.render_sidebar()} ${this.render_sidebar()}
<div <div
style="margin-left: 2in; padding: 0px; top: 0; max-height: 100%; overflow: auto" style="margin-left: 2in; padding: 0px; top: 0; max-height: 100%; overflow: auto; contain: layout"
id="main" id="main"
class="w3-main" class="w3-main"
> >

5
apps/web.json Normal file
View File

@ -0,0 +1,5 @@
{
"type": "tildefriends-app",
"emoji": "🕸",
"previous": "&n7hu5b8/TsfiG6FDlCRG5nPCrIdCr96+xpIJ/aQT/uM=.sha256"
}

100
apps/web/app.js Normal file
View File

@ -0,0 +1,100 @@
let g_hash;
async function query(sql, params) {
let results = [];
await ssb.sqlAsync(sql, params, function (row) {
results.push(row);
});
return results;
}
async function resolve(id) {
try {
let blob = await ssb.blobGet(id);
if (blob) {
let json;
try {
json = JSON.parse(utf8Decode(blob));
} catch {
return {id: utf8Decode(blob)};
}
if (json?.links) {
for (let [key, value] of Object.entries(json.links)) {
json.links[key] = await resolve(value);
}
return json;
} else {
return 'huh?' + json;
}
} else {
return `missing<${id}>`;
}
} catch (e) {
return id + ': ' + e.message;
}
}
async function get_names(identities) {
return Object.fromEntries(
(
await query(
`
SELECT author, name FROM (
SELECT
messages.author,
RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank,
messages.content ->> 'name' AS name
FROM messages
JOIN json_each(?) AS identities ON identities.value = messages.author
WHERE
json_extract(messages.content, '$.type') = 'about' AND
content ->> 'about' = messages.author AND name IS NOT NULL)
WHERE author_rank = 1
`,
[JSON.stringify(identities)]
)
).map((x) => [x.author, x.name])
);
}
async function render(hash) {
g_hash = hash;
if (!hash) {
let sites = await query(
`
SELECT site.author, site.id
FROM messages site
WHERE site.content ->> 'type' = 'web-init'
`,
[]
);
let names = await get_names(sites.map((x) => x.author));
if (hash === g_hash) {
await app.setDocument(
`<ul style="background-color: #ddd">${sites.map((x) => `<li><a target="_top" href="#${encodeURIComponent(x.id)}">${names[x.author] ?? x.author} - ${x.id}</a></li>`).join('\n')}</ul>`
);
}
} else {
let site_id =
hash.charAt(0) == '#'
? decodeURIComponent(hash.substring(1))
: decodeURIComponent(hash);
await app.setDocument(`<html style="margin: 0; padding: 0; width: 100vw; height: 100vh; margin: 0; padding: 0">
<body style="display: flex; flex-direction: column; width: 100vw; height: 100vh">
<iframe src="${encodeURIComponent(site_id)}/index.html" style="flex: 1 1; border: 0; background-color: #fff"></iframe>
</body>
</html>`);
}
}
core.register('message', async function message_handler(message) {
if (message.event == 'hashChange') {
await render(message.hash);
}
});
async function main() {
render(null);
}
main();

63
apps/web/handler.js Normal file
View File

@ -0,0 +1,63 @@
async function query(sql, params) {
let results = [];
await ssb.sqlAsync(sql, params, function (row) {
results.push(row);
});
return results;
}
function guess_content_type(name) {
if (name.endsWith('.html')) {
return 'text/html; charset=UTF-8';
} else if (name.endsWith('.js') || name.endsWith('.mjs')) {
return 'text/javascript; charset=UTF-8';
} else if (name.endsWith('.css')) {
return 'text/stylesheet; charset=UTF-8';
} else {
return 'application/binary';
}
}
async function main() {
let path = request.path.replaceAll(/(%[0-9a-fA-F]{2})/g, (x) =>
String.fromCharCode(parseInt(x.substring(1), 16))
);
let match = path.match(/^(%.{44}\.sha256)(?:\/)?(.*)$/);
let content_type = guess_content_type(request.path);
let root = await query(
`
SELECT root.content ->> 'root' AS root
FROM messages site
JOIN messages root
ON site.id = ? AND root.author = site.author AND root.content ->> 'site' = site.id
ORDER BY root.sequence DESC LIMIT 1
`,
[match[1]]
);
let root_id = root[0]['root'];
let last_id = root_id;
let blob = await ssb.blobGet(root_id);
try {
for (let part of match[2]?.split('/')) {
let dir = JSON.parse(utf8Decode(blob));
last_id = dir?.links[part];
blob = await ssb.blobGet(dir?.links[part]);
content_type = guess_content_type(part);
}
} catch {}
respond({
status_code: 200,
data: blob ? utf8Decode(blob) : `${last_id} not found`,
content_type: content_type,
});
}
main().catch(function (e) {
respond({
status_code: 200,
data: `${e.message}\n${e.stack}`,
content_type: 'text/plain',
});
});

View File

@ -25,14 +25,14 @@
}: }:
pkgs.stdenv.mkDerivation rec { pkgs.stdenv.mkDerivation rec {
pname = "tildefriends"; pname = "tildefriends";
version = "0.0.28"; version = "0.0.29";
src = pkgs.fetchFromGitea { src = pkgs.fetchFromGitea {
domain = "dev.tildefriends.net"; domain = "dev.tildefriends.net";
owner = "cory"; owner = "cory";
repo = "tildefriends"; repo = "tildefriends";
rev = "v${version}"; rev = "v${version}";
hash = "sha256-vcLJCXgIrjC37t9oavK2QMRcMJljghuzKDYxQ4nyTcE="; hash = "sha256-bQXFpocOYOlFmVj9OZeQhNrgFuTJ8sx2RSw1tgmelOM=";
fetchSubmodules = true; fetchSubmodules = true;
}; };

2
deps/c-ares vendored

File diff suppressed because one or more lines are too long

209
deps/codemirror_src/package-lock.json generated vendored
View File

@ -30,9 +30,9 @@
} }
}, },
"node_modules/@codemirror/commands": { "node_modules/@codemirror/commands": {
"version": "6.8.0", "version": "6.8.1",
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.0.tgz", "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz",
"integrity": "sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==", "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==",
"dependencies": { "dependencies": {
"@codemirror/language": "^6.0.0", "@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.4.0", "@codemirror/state": "^6.4.0",
@ -92,9 +92,9 @@
} }
}, },
"node_modules/@codemirror/language": { "node_modules/@codemirror/language": {
"version": "6.10.8", "version": "6.11.0",
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.8.tgz", "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz",
"integrity": "sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==", "integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==",
"dependencies": { "dependencies": {
"@codemirror/state": "^6.0.0", "@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.23.0", "@codemirror/view": "^6.23.0",
@ -105,9 +105,9 @@
} }
}, },
"node_modules/@codemirror/lint": { "node_modules/@codemirror/lint": {
"version": "6.8.4", "version": "6.8.5",
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.4.tgz", "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz",
"integrity": "sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==", "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==",
"dependencies": { "dependencies": {
"@codemirror/state": "^6.0.0", "@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.35.0", "@codemirror/view": "^6.35.0",
@ -144,9 +144,9 @@
} }
}, },
"node_modules/@codemirror/view": { "node_modules/@codemirror/view": {
"version": "6.36.4", "version": "6.36.5",
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.4.tgz", "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.5.tgz",
"integrity": "sha512-ZQ0V5ovw/miKEXTvjgzRyjnrk9TwriUB1k4R5p7uNnHR9Hus+D1SXHGdJshijEzPFjU25xea/7nhIeSqYFKdbA==", "integrity": "sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==",
"dependencies": { "dependencies": {
"@codemirror/state": "^6.5.0", "@codemirror/state": "^6.5.0",
"style-mod": "^4.1.0", "style-mod": "^4.1.0",
@ -217,9 +217,9 @@
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==" "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="
}, },
"node_modules/@lezer/css": { "node_modules/@lezer/css": {
"version": "1.1.10", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.10.tgz", "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.11.tgz",
"integrity": "sha512-V5/89eDapjeAkWPBpWEfQjZ1Hag3aYUUJOL8213X0dFRuXJ4BXa5NKl9USzOnaLod4AOpmVCkduir2oKwZYZtg==", "integrity": "sha512-FuAnusbLBl1SEAtfN8NdShxYJiESKw9LAFysfea1T96jD3ydBn12oYjaSG1a04BQRIUd93/0D8e5CV1cUMkmQg==",
"dependencies": { "dependencies": {
"@lezer/common": "^1.2.0", "@lezer/common": "^1.2.0",
"@lezer/highlight": "^1.0.0", "@lezer/highlight": "^1.0.0",
@ -344,9 +344,9 @@
} }
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.39.0.tgz",
"integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==", "integrity": "sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -356,9 +356,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.39.0.tgz",
"integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==", "integrity": "sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -368,9 +368,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.39.0.tgz",
"integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==", "integrity": "sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -380,9 +380,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.39.0.tgz",
"integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==", "integrity": "sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -392,9 +392,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.39.0.tgz",
"integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==", "integrity": "sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -404,9 +404,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.39.0.tgz",
"integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==", "integrity": "sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -416,9 +416,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.39.0.tgz",
"integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==", "integrity": "sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -428,9 +428,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.39.0.tgz",
"integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==", "integrity": "sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -440,9 +440,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.39.0.tgz",
"integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==", "integrity": "sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -452,9 +452,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.39.0.tgz",
"integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==", "integrity": "sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -464,9 +464,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-loongarch64-gnu": { "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.39.0.tgz",
"integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==", "integrity": "sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@ -476,9 +476,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.39.0.tgz",
"integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==", "integrity": "sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -488,9 +488,21 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.39.0.tgz",
"integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==", "integrity": "sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==",
"cpu": [
"riscv64"
],
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.39.0.tgz",
"integrity": "sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -500,9 +512,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.39.0.tgz",
"integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==", "integrity": "sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -512,9 +524,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.39.0.tgz",
"integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==", "integrity": "sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -524,9 +536,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.39.0.tgz",
"integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==", "integrity": "sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -536,9 +548,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.39.0.tgz",
"integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==", "integrity": "sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -548,9 +560,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.39.0.tgz",
"integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==", "integrity": "sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -560,9 +572,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.39.0.tgz",
"integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==", "integrity": "sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -572,9 +584,9 @@
] ]
}, },
"node_modules/@types/estree": { "node_modules/@types/estree": {
"version": "1.0.6", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="
}, },
"node_modules/@types/resolve": { "node_modules/@types/resolve": {
"version": "1.20.2", "version": "1.20.2",
@ -733,11 +745,11 @@
} }
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.34.9", "version": "4.39.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.39.0.tgz",
"integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==", "integrity": "sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==",
"dependencies": { "dependencies": {
"@types/estree": "1.0.6" "@types/estree": "1.0.7"
}, },
"bin": { "bin": {
"rollup": "dist/bin/rollup" "rollup": "dist/bin/rollup"
@ -747,25 +759,26 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.34.9", "@rollup/rollup-android-arm-eabi": "4.39.0",
"@rollup/rollup-android-arm64": "4.34.9", "@rollup/rollup-android-arm64": "4.39.0",
"@rollup/rollup-darwin-arm64": "4.34.9", "@rollup/rollup-darwin-arm64": "4.39.0",
"@rollup/rollup-darwin-x64": "4.34.9", "@rollup/rollup-darwin-x64": "4.39.0",
"@rollup/rollup-freebsd-arm64": "4.34.9", "@rollup/rollup-freebsd-arm64": "4.39.0",
"@rollup/rollup-freebsd-x64": "4.34.9", "@rollup/rollup-freebsd-x64": "4.39.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.34.9", "@rollup/rollup-linux-arm-gnueabihf": "4.39.0",
"@rollup/rollup-linux-arm-musleabihf": "4.34.9", "@rollup/rollup-linux-arm-musleabihf": "4.39.0",
"@rollup/rollup-linux-arm64-gnu": "4.34.9", "@rollup/rollup-linux-arm64-gnu": "4.39.0",
"@rollup/rollup-linux-arm64-musl": "4.34.9", "@rollup/rollup-linux-arm64-musl": "4.39.0",
"@rollup/rollup-linux-loongarch64-gnu": "4.34.9", "@rollup/rollup-linux-loongarch64-gnu": "4.39.0",
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.9", "@rollup/rollup-linux-powerpc64le-gnu": "4.39.0",
"@rollup/rollup-linux-riscv64-gnu": "4.34.9", "@rollup/rollup-linux-riscv64-gnu": "4.39.0",
"@rollup/rollup-linux-s390x-gnu": "4.34.9", "@rollup/rollup-linux-riscv64-musl": "4.39.0",
"@rollup/rollup-linux-x64-gnu": "4.34.9", "@rollup/rollup-linux-s390x-gnu": "4.39.0",
"@rollup/rollup-linux-x64-musl": "4.34.9", "@rollup/rollup-linux-x64-gnu": "4.39.0",
"@rollup/rollup-win32-arm64-msvc": "4.34.9", "@rollup/rollup-linux-x64-musl": "4.39.0",
"@rollup/rollup-win32-ia32-msvc": "4.34.9", "@rollup/rollup-win32-arm64-msvc": "4.39.0",
"@rollup/rollup-win32-x64-msvc": "4.34.9", "@rollup/rollup-win32-ia32-msvc": "4.39.0",
"@rollup/rollup-win32-x64-msvc": "4.39.0",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },

View File

@ -1 +1 @@
A tool for making and sharing A Secure Scuttlebutt decentralized social network client

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unprompted.tildefriends" package="com.unprompted.tildefriends"
android:versionCode="34" android:versionCode="35"
android:versionName="0.0.29"> android:versionName="0.0.30-wip">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<application <application

View File

@ -347,7 +347,6 @@ public class TildeFriendsActivity extends Activity {
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
e.printStackTrace(); e.printStackTrace();
} catch (java.io.FileNotFoundException e) { } catch (java.io.FileNotFoundException e) {
Log.w("tildefriends", "Port file does not yet exist.");
} catch (java.io.IOException e) { } catch (java.io.IOException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -785,8 +785,25 @@ void tf_http_add_handler(tf_http_t* http, const char* pattern, tf_http_callback_
static void _http_free_listener_on_close(uv_handle_t* handle) static void _http_free_listener_on_close(uv_handle_t* handle)
{ {
tf_http_listener_t* listener = handle->data; tf_http_listener_t* listener = handle->data;
tf_http_t* http = listener->http;
for (int i = 0; i < http->listeners_count; i++)
{
if (http->listeners[i] == listener)
{
http->listeners[i] = http->listeners[http->listeners_count - 1];
http->listeners_count--;
break;
}
}
handle->data = NULL; handle->data = NULL;
tf_free(listener); tf_free(listener);
if (!http->listeners_count)
{
tf_free(http->listeners);
http->listeners = NULL;
tf_http_destroy(http);
}
} }
void tf_http_destroy(tf_http_t* http) void tf_http_destroy(tf_http_t* http)
@ -812,6 +829,10 @@ void tf_http_destroy(tf_http_t* http)
listener->cleanup(listener->user_data); listener->cleanup(listener->user_data);
listener->cleanup = NULL; listener->cleanup = NULL;
} }
if (listener->tcp.data && !uv_is_closing((uv_handle_t*)&listener->tcp))
{
uv_close((uv_handle_t*)&listener->tcp, _http_free_listener_on_close);
}
} }
for (int i = 0; i < http->handlers_count; i++) for (int i = 0; i < http->handlers_count; i++)
@ -829,20 +850,11 @@ void tf_http_destroy(tf_http_t* http)
http->user_data = NULL; http->user_data = NULL;
} }
if (http->connections_count == 0) if (http->connections_count == 0 && http->listeners_count == 0)
{ {
tf_free(http->connections); tf_free(http->connections);
http->connections = NULL; http->connections = NULL;
for (int i = 0; i < http->listeners_count; i++)
{
tf_http_listener_t* listener = http->listeners[i];
uv_close((uv_handle_t*)&listener->tcp, _http_free_listener_on_close);
}
tf_free(http->listeners);
http->listeners = NULL;
http->listeners_count = 0;
for (int i = 0; i < http->handlers_count; i++) for (int i = 0; i < http->handlers_count; i++)
{ {
if (http->handlers[i].pattern) if (http->handlers[i].pattern)

View File

@ -13,13 +13,13 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.0.29</string> <string>0.0.30</string>
<key>CFBundleSupportedPlatforms</key> <key>CFBundleSupportedPlatforms</key>
<array> <array>
<string>iPhoneOS</string> <string>iPhoneOS</string>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>11</string> <string>12</string>
<key>DTPlatformName</key> <key>DTPlatformName</key>
<string>iphoneos</string> <string>iphoneos</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>

View File

@ -176,13 +176,19 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
_tf_ssb_db_exec(db, "ALTER TABLE messages RENAME COLUMN sequence_before_author TO flags"); _tf_ssb_db_exec(db, "ALTER TABLE messages RENAME COLUMN sequence_before_author TO flags");
} }
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_id_index ON messages (author, id)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_id_author_index ON messages (id, author)");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_sequence_index ON messages (author, sequence)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_sequence_index ON messages (author, sequence)");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_timestamp_index ON messages (author, timestamp)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_author_timestamp_index ON messages (author, timestamp)");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_timestamp_index ON messages (timestamp)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_timestamp_index ON messages (timestamp)");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_type_timestamp_index ON messages (content ->> 'type', timestamp)"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_type_timestamp_index ON messages (content ->> 'type', timestamp)");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_size_by_author_index ON messages (author, length(content))"); _tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_size_by_author_index ON messages (author, length(content))");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_type_author_channel_index ON messages (content ->> 'type', author, content ->> 'channel');"); _tf_ssb_db_exec(
db, "CREATE INDEX IF NOT EXISTS messages_type_author_channel_root_rowid_index ON messages (author, content ->> 'type', content ->> 'channel', content ->> 'root')");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_type_author_channel_index");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_author_id_index");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_by_author_index");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_timestamp_author_index");
_tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_id_index");
_tf_ssb_db_exec(db, _tf_ssb_db_exec(db,
"CREATE TABLE IF NOT EXISTS blobs (" "CREATE TABLE IF NOT EXISTS blobs ("
" id TEXT PRIMARY KEY," " id TEXT PRIMARY KEY,"
@ -286,8 +292,10 @@ void tf_ssb_db_init(tf_ssb_t* ssb)
_tf_ssb_db_exec(db, "DROP TRIGGER IF EXISTS messages_ad_refs"); _tf_ssb_db_exec(db, "DROP TRIGGER IF EXISTS messages_ad_refs");
_tf_ssb_db_exec(db, "CREATE TRIGGER IF NOT EXISTS messages_ad_refs AFTER DELETE ON messages BEGIN DELETE FROM messages_refs WHERE messages_refs.message = old.id; END"); _tf_ssb_db_exec(db, "CREATE TRIGGER IF NOT EXISTS messages_ad_refs AFTER DELETE ON messages BEGIN DELETE FROM messages_refs WHERE messages_refs.message = old.id; END");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_refs_message_idx ON messages_refs (message)"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_refs_message_idx");
_tf_ssb_db_exec(db, "CREATE INDEX IF NOT EXISTS messages_refs_ref_idx ON messages_refs (ref)"); _tf_ssb_db_exec(db, "DROP INDEX IF EXISTS messages_refs_ref_idx");
_tf_ssb_db_exec(db, "CREATE UNIQUE INDEX IF NOT EXISTS messages_refs_message_ref_idx ON messages_refs (message, ref)");
_tf_ssb_db_exec(db, "CREATE UNIQUE INDEX IF NOT EXISTS messages_refs_ref_message_idx ON messages_refs (ref, message)");
if (!_tf_ssb_db_has_rows(db, "PRAGMA table_list('blobs_refs')")) if (!_tf_ssb_db_has_rows(db, "PRAGMA table_list('blobs_refs')"))
{ {

View File

@ -1,2 +1,2 @@
#define VERSION_NUMBER "0.0.29" #define VERSION_NUMBER "0.0.30-wip"
#define VERSION_NAME "This program kills fascists." #define VERSION_NAME "This program kills fascists."

View File

@ -17,6 +17,7 @@ k_feeds = {
'habitat': 'https://tildegit.org/jeremylist/habitat.rss', 'habitat': 'https://tildegit.org/jeremylist/habitat.rss',
'manyverse': 'https://gitlab.com/staltz/manyverse/-/commits/master?format=atom', 'manyverse': 'https://gitlab.com/staltz/manyverse/-/commits/master?format=atom',
'ahau': 'https://gitlab.com/ahau/ahau/-/commits/master.atom', 'ahau': 'https://gitlab.com/ahau/ahau/-/commits/master.atom',
'patchfox': 'https://github.com/soapdog/patchfox/commits.atom',
} }
def fix_title(entry): def fix_title(entry):