From b052f741d935abd2f51423abf3fcda9157844b5c Mon Sep 17 00:00:00 2001 From: "netop://ウィビ" Date: Sat, 11 Apr 2026 14:42:43 -0700 Subject: initial commit --- src/app.html | 66 ++++++ src/lib/component/About.svelte | 98 +++++++++ src/lib/component/Blog.svelte | 244 ++++++++++++++++++++++ src/lib/component/CV.svelte | 78 +++++++ src/lib/component/Music.svelte | 354 ++++++++++++++++++++++++++++++++ src/lib/component/MyMusic.svelte | 173 ++++++++++++++++ src/lib/component/Project.svelte | 241 ++++++++++++++++++++++ src/lib/component/Promo.svelte | 66 ++++++ src/lib/component/Remarks.svelte | 179 ++++++++++++++++ src/lib/component/Ring.svelte | 312 ++++++++++++++++++++++++++++ src/lib/component/Social.svelte | 112 ++++++++++ src/lib/component/Support.svelte | 70 +++++++ src/lib/component/Uses.svelte | 145 +++++++++++++ src/routes/+layout.svelte | 147 +++++++++++++ src/routes/+page.svelte | 115 +++++++++++ src/routes/api/blog.json/+server.ts | 51 +++++ src/routes/api/cv.json/+server.ts | 75 +++++++ src/routes/api/mastodon.json/+server.ts | 55 +++++ src/routes/api/remarks.json/+server.ts | 51 +++++ 19 files changed, 2632 insertions(+) create mode 100644 src/app.html create mode 100644 src/lib/component/About.svelte create mode 100644 src/lib/component/Blog.svelte create mode 100644 src/lib/component/CV.svelte create mode 100644 src/lib/component/Music.svelte create mode 100644 src/lib/component/MyMusic.svelte create mode 100644 src/lib/component/Project.svelte create mode 100644 src/lib/component/Promo.svelte create mode 100644 src/lib/component/Remarks.svelte create mode 100644 src/lib/component/Ring.svelte create mode 100644 src/lib/component/Social.svelte create mode 100644 src/lib/component/Support.svelte create mode 100644 src/lib/component/Uses.svelte create mode 100644 src/routes/+layout.svelte create mode 100644 src/routes/+page.svelte create mode 100644 src/routes/api/blog.json/+server.ts create mode 100644 src/routes/api/cv.json/+server.ts create mode 100644 src/routes/api/mastodon.json/+server.ts create mode 100644 src/routes/api/remarks.json/+server.ts (limited to 'src') diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..cdd05c3 --- /dev/null +++ b/src/app.html @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + the webb page + + %sveltekit.head% + + + + + + +
%sveltekit.body%
+ + diff --git a/src/lib/component/About.svelte b/src/lib/component/About.svelte new file mode 100644 index 0000000..c2a076d --- /dev/null +++ b/src/lib/component/About.svelte @@ -0,0 +1,98 @@ + + + + +

about.webb.page

+ +

TL;DR bio: Architech × Excessively Black × East Coast kid on the West Coast × JU$T × Building a better Internet

+ +

I go by NetOperator Wibby, NetOpWibby, or netop://ウエブ pretty much everywhere online. "NetOperator" is the term given to chronically online people internet enthusiasts in the Megaman Battle Network series, one of my favorite game series of all time and constant source of inspiration.

+ +

TL;DR career bio: From college dropout to self-taught designer turned developer during the 2008 recession → Stopped working on music to focus on family and career → lots of startup work → Now I work at a major "fruit" company. Not bad, eh? Bless the Internet.

+ +

Short life bio: Voracious reader, absolutely loved mystery books: Encyclopedia Brown, Hardy Boys, Nancy Drew, Archie Comics, &c. Frequently took things apart and collected scraps to build "inventions." Avid sketcher and jotter of ideas.

+

Majorly influenced by Pharrell Williams, Chad Hugo, Timbaland, Clipse, N.E.R.D, Nujabes, Shing02, Fat Jon, Five Deez, &c and wanted to make music and beats. Performed exactly once and was recognized on the street afterwards ("your performance was really good"). Developed a perfectionist mindset, which is to blame for my debut album still under wraps (lyrics still hold up though), among other things.

+

Married the girl of my dreams in 2017 (maiden name? Page). We met on a web page in 9th grade, a little known social network called "Classface." Webb + Page. You can't make this up. Oh, and I lost my job four days after our wedding (IoT company imploded and we were the last to know). You wanna hear God laugh? Make plans. Now we have a loquat tree in our backyard in sunny California…LOL (Love Our Loquats)!

+

I try to live life according to The Golden Rule, and to stick to my ethics and morals as much as possible. It's bothersome when I find that others do not. But like…that's life? It's annoying though. You all should think like me!! 😤

+ +
+ +

Anyhoo, I love the internet. The internet has empowered me to learn, explore, and get inspired by so many cool people around the world. If you love yourself, you probably love others and aren't bigoted. That makes you cool as fuck. If this isn't you, I hope you find peace.

+ +{#if selfie === ""} +

loading…

+{:else} +
+ selfie +
the most fantabulous
+
+{/if} diff --git a/src/lib/component/Blog.svelte b/src/lib/component/Blog.svelte new file mode 100644 index 0000000..8469701 --- /dev/null +++ b/src/lib/component/Blog.svelte @@ -0,0 +1,244 @@ + + + + +

+ blog.webb.page +

+ + diff --git a/src/lib/component/CV.svelte b/src/lib/component/CV.svelte new file mode 100644 index 0000000..b24d2cf --- /dev/null +++ b/src/lib/component/CV.svelte @@ -0,0 +1,78 @@ + + + + +

+ cv.webb.page +

+ +{#if cv === ""} +
loading…
+{:else} +
+ {cv} +
+{/if} diff --git a/src/lib/component/Music.svelte b/src/lib/component/Music.svelte new file mode 100644 index 0000000..01b731a --- /dev/null +++ b/src/lib/component/Music.svelte @@ -0,0 +1,354 @@ + + + + +

music.webb.page/bandcamp

+ + diff --git a/src/lib/component/MyMusic.svelte b/src/lib/component/MyMusic.svelte new file mode 100644 index 0000000..aed9098 --- /dev/null +++ b/src/lib/component/MyMusic.svelte @@ -0,0 +1,173 @@ + + + + +

music.webb.page

+ + diff --git a/src/lib/component/Project.svelte b/src/lib/component/Project.svelte new file mode 100644 index 0000000..024045e --- /dev/null +++ b/src/lib/component/Project.svelte @@ -0,0 +1,241 @@ + + + + +

projects.webb.page

+ + diff --git a/src/lib/component/Promo.svelte b/src/lib/component/Promo.svelte new file mode 100644 index 0000000..54f57bd --- /dev/null +++ b/src/lib/component/Promo.svelte @@ -0,0 +1,66 @@ + + + + +

promo.webb.page

+ + diff --git a/src/lib/component/Remarks.svelte b/src/lib/component/Remarks.svelte new file mode 100644 index 0000000..6633654 --- /dev/null +++ b/src/lib/component/Remarks.svelte @@ -0,0 +1,179 @@ + + + + +

+ blog.webb.page/remarks +

+ + diff --git a/src/lib/component/Ring.svelte b/src/lib/component/Ring.svelte new file mode 100644 index 0000000..01e4910 --- /dev/null +++ b/src/lib/component/Ring.svelte @@ -0,0 +1,312 @@ + + + + +

ring.webb.page

+ + diff --git a/src/lib/component/Social.svelte b/src/lib/component/Social.svelte new file mode 100644 index 0000000..1e469eb --- /dev/null +++ b/src/lib/component/Social.svelte @@ -0,0 +1,112 @@ + + + + +

social.webb.page/mastodon

+ +{#if mastodonLoaded} +
+ {@html mastodonPostContent} + + {#if mastodonPostMedia.length} +
+ {#each mastodonPostMedia as media} + {#if videoRegex.test(media)} + + + {:else} +
+ mastodon media +
+
+ {/if} + {/each} +
+ {/if} + +

— + + + +

+
+{:else} +
+

loading…

+
+{/if} diff --git a/src/lib/component/Support.svelte b/src/lib/component/Support.svelte new file mode 100644 index 0000000..ceff0fd --- /dev/null +++ b/src/lib/component/Support.svelte @@ -0,0 +1,70 @@ + + + + +

support.webb.page

+ + + +

I have a number of domains for sale. Past projects never embarked on but names I don’t want to let expire just yet; dsgn.io, hackerspace.wtf, imagination.industries, and phoenix.systems.

diff --git a/src/lib/component/Uses.svelte b/src/lib/component/Uses.svelte new file mode 100644 index 0000000..4c91944 --- /dev/null +++ b/src/lib/component/Uses.svelte @@ -0,0 +1,145 @@ + + + + +

uses.webb.page

+ + diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..be635e8 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,147 @@ + + + + +
+ +
+ + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..a0f1a90 --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,115 @@ + + + + + + + + +
+ +
+ +
+ + + +
+ +
+ + + +
+ +
+ + + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
diff --git a/src/routes/api/blog.json/+server.ts b/src/routes/api/blog.json/+server.ts new file mode 100644 index 0000000..f416647 --- /dev/null +++ b/src/routes/api/blog.json/+server.ts @@ -0,0 +1,51 @@ + + + +/*** IMPORT ------------------------------------------- ***/ + +import { error, json } from "@sveltejs/kit"; + +/*** EXPORT ------------------------------------------- ***/ + +export const POST = async({ fetch, request }) => { + try { + const { filename } = await request.json(); + + const response = await fetch(`https://blog.webb.page/${String(filename)}`, { + headers: { "Content-Type": "text/plain" }, + method: "GET" + }); + + const memo = parseMemo(await response.text()); + memo.push(` [READ]`, "\n"); + + return json({ content: memo.join("\n") }); + } catch(welp) { + console.error(`Error fetching memo: ${String(welp)}`); + return error(500); + } +}; + +/*** HELPER ------------------------------------------- ***/ + +function parseMemo(text: string): string { + const intro = text.split(/^Body$/m)[0]; + const lines = intro.split("\n").filter(Boolean); + const format = [""]; + let firstLine = ""; + + lines.map((line, index) => { + if (index === 1) + firstLine = " " + line.split(/\s+\B/)[1].trim(); + + if (index === 2) { + firstLine += ` • ${line.trim()}`; + format.push(firstLine); + } + + if (index === 4) + format.push(" " + line.trim()); + }); + + return format; +} diff --git a/src/routes/api/cv.json/+server.ts b/src/routes/api/cv.json/+server.ts new file mode 100644 index 0000000..956525f --- /dev/null +++ b/src/routes/api/cv.json/+server.ts @@ -0,0 +1,75 @@ + + + +/*** IMPORT ------------------------------------------- ***/ + +import { error, json } from "@sveltejs/kit"; + +/*** EXPORT ------------------------------------------- ***/ + +export const POST = async({ fetch, request }) => { + try { + const response = await fetch("https://cv.webb.page", { + headers: { "Content-Type": "text/plain" }, + method: "GET" + }); + + const content = await response.text(); + return json({ content: processCV(content) }); + } catch(welp) { + console.error(`Error fetching CV: ${String(welp)}`); + return error(500); + } +}; + +/*** HELPER ------------------------------------------- ***/ + +function processCV(text) { + const sections = text.split(/(^░▒▓[\s\S]*?^---$)/m); + const intro = sections[1]; + const body = sections[2]; + const lines = body.split(/\n{2,}/); + const table = processTable(body); + + const processedLines = lines.map(line => { + if (line.includes("Proficiency") && line.includes("Notes")) + return table.join("").trim(); + + return line.replace(/\s+/g, " "); + }); + + return intro + processedLines.join("\n\n") + "\n\n\n"; +} + +function processTable(text) { + const lines = text.split(/\r?\n/); + const tableStartIndex = lines.findIndex(line => line.includes("|")); + + if (tableStartIndex === -1) + return null; + + const separatorLineIndex = lines.findIndex((line, index) => index > tableStartIndex && line.includes("|-") || line.includes("| -")); + + if (separatorLineIndex === -1) + return null; + + let tableEndIndex = separatorLineIndex + 1; + + while (tableEndIndex < lines.length && lines[tableEndIndex].includes("|")) { + tableEndIndex++; + } + + const contentRows = lines.slice(separatorLineIndex + 1, tableEndIndex); + + return contentRows.map(row => { + let cells = row.split("|").map(cell => cell.trim()); + + if (cells[0] === "") + cells.shift(); + + if (cells[cells.length - 1] === "") + cells.pop(); + + return cells.join(" / ") + "\n"; + }); +} diff --git a/src/routes/api/mastodon.json/+server.ts b/src/routes/api/mastodon.json/+server.ts new file mode 100644 index 0000000..72cbd38 --- /dev/null +++ b/src/routes/api/mastodon.json/+server.ts @@ -0,0 +1,55 @@ + + + +/*** IMPORT ------------------------------------------- ***/ + +import { error, json } from "@sveltejs/kit"; + +/*** EXPORT ------------------------------------------- ***/ + +export const POST = async({ fetch }) => { + try { + const response = await fetch("https://social.coop/users/netopwibby/outbox?page=true", { + headers: { "Content-Type": "application/json" }, + method: "GET" + }); + + const { orderedItems } = await response.json(); + const { object } = findCreateType(orderedItems); + + return json({ + created: object.published, + content: object.content, + link: object.url, + media: processAttachments(object.attachment) + }); + } catch(welp) { + console.error(`Error fetching latest Mastodon post: ${String(welp)}`); + return error(500); + } +}; + +/*** HELPER ------------------------------------------- ***/ + +function findCreateType(arr: Array<{ [key: string]: any }>): { [key: string]: any } | undefined { + return arr.find(obj => obj.type === "Create"); +} + +function processAttachments(attachments: Array<{ [key: string]: any }>): Array { + const media = []; + + if (attachments) { + for (const attachment of attachments) { + // TODO + // : use blurhash given to us by mastodon + // : https://github.com/woltapp/blurhash/tree/master/TypeScript#example + // : `attachment` comes with blurhash, height, mediaType, width + // if (attachment && attachment.url) + + // @ts-ignore | Argument of type "any" is not assignable to parameter of type "never". + media.push(attachment.url); + } + } + + return media; +} diff --git a/src/routes/api/remarks.json/+server.ts b/src/routes/api/remarks.json/+server.ts new file mode 100644 index 0000000..c708207 --- /dev/null +++ b/src/routes/api/remarks.json/+server.ts @@ -0,0 +1,51 @@ + + + +/*** IMPORT ------------------------------------------- ***/ + +import { error, json } from "@sveltejs/kit"; + +/*** EXPORT ------------------------------------------- ***/ + +export const POST = async({ fetch, request }) => { + try { + const { filename } = await request.json(); + + const response = await fetch("https://blog.webb.page/remarks/" + String(filename), { + headers: { "Content-Type": "text/plain" }, + method: "GET" + }); + + const remark = parseRemark(await response.text()); + remark.push(` [READ]`, "\n"); + + return json({ content: remark.join("\n") }); + } catch(welp) { + console.error(`Error fetching remark: ${String(welp)}`); + return error(500); + } +}; + +/*** HELPER ------------------------------------------- ***/ + +function parseRemark(text: string): string { + const intro = text.split(/^Body$/m)[0]; + const lines = intro.split("\n").filter(Boolean); + const format = [""]; + let firstLine = ""; + + lines.map((line, index) => { + if (index === 1) + firstLine = " " + line.split(/\s+\B/)[1].trim(); + + if (index === 2) { + firstLine += ` • ${line.trim()}`; + format.push(firstLine); + } + + if (index === 4) + format.push(" " + line.trim()); + }); + + return format; +} -- cgit v1.2.3