···11+{
22+ "lexicon": 1,
33+ "id": "fm.teal.alpha.actor.status",
44+ "defs": {
55+ "main": {
66+ "type": "record",
77+ "description": "This lexicon is in a not officially released state. It is subject to change. | A declaration of the status of the actor. Only one can be shown at a time. If there are multiple, the latest record should be picked and earlier records should be deleted or tombstoned.",
88+ "key": "literal:self",
99+ "record": {
1010+ "type": "object",
1111+ "required": ["time", "item"],
1212+ "properties": {
1313+ "time": {
1414+ "type": "string",
1515+ "format": "datetime",
1616+ "description": "The RFC 3339 formatted time of when the item was recorded"
1717+ },
1818+ "expiry": {
1919+ "type": "string",
2020+ "format": "datetime",
2121+ "description": "The RFC 3339 formatted time of the expiry time of the item. If unavailable, default to 10 minutes past the start time."
2222+ },
2323+ "item": {
2424+ "type": "ref",
2525+ "ref": "fm.teal.alpha.feed.defs#playView"
2626+ }
2727+ }
2828+ }
2929+ }
3030+ }
3131+}
+94
lexicons/fm/teal/alpha/feed/defs.json
···11+{
22+ "lexicon": 1,
33+ "id": "fm.teal.alpha.feed.defs",
44+ "description": "This lexicon is in a not officially released state. It is subject to change. | Misc. items related to feeds.",
55+ "defs": {
66+ "playView": {
77+ "type": "object",
88+ "required": ["trackName", "artists"],
99+ "properties": {
1010+ "trackName": {
1111+ "type": "string",
1212+ "minLength": 1,
1313+ "maxLength": 256,
1414+ "maxGraphemes": 2560,
1515+ "description": "The name of the track"
1616+ },
1717+ "trackMbId": {
1818+ "type": "string",
1919+ "format": "uri",
2020+ "description": "The MusicBrainz ID URI of the track, formatted as mbid:<uuid>"
2121+ },
2222+ "recordingMbId": {
2323+ "type": "string",
2424+ "format": "uri",
2525+ "description": "The MusicBrainz recording ID URI of the track, formatted as mbid:<uuid>"
2626+ },
2727+ "duration": {
2828+ "type": "integer",
2929+ "description": "The length of the track in seconds"
3030+ },
3131+ "artists": {
3232+ "type": "array",
3333+ "items": {
3434+ "type": "ref",
3535+ "ref": "#artist"
3636+ },
3737+ "description": "Array of artists in order of original appearance."
3838+ },
3939+ "releaseName": {
4040+ "type": "string",
4141+ "maxLength": 256,
4242+ "maxGraphemes": 2560,
4343+ "description": "The name of the release/album"
4444+ },
4545+ "releaseMbId": {
4646+ "type": "string",
4747+ "format": "uri",
4848+ "description": "The MusicBrainz release ID URI, formatted as mbid:<uuid>"
4949+ },
5050+ "isrc": {
5151+ "type": "string",
5252+ "description": "The ISRC code associated with the recording"
5353+ },
5454+ "originUrl": {
5555+ "type": "string",
5656+ "description": "The URL associated with this track"
5757+ },
5858+ "musicServiceBaseDomain": {
5959+ "type": "string",
6060+ "description": "The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided."
6161+ },
6262+ "submissionClientAgent": {
6363+ "type": "string",
6464+ "maxLength": 256,
6565+ "maxGraphemes": 2560,
6666+ "description": "A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided."
6767+ },
6868+ "playedTime": {
6969+ "type": "string",
7070+ "format": "datetime",
7171+ "description": "The unix timestamp of when the track was played"
7272+ }
7373+ }
7474+ },
7575+ "artist": {
7676+ "type": "object",
7777+ "required": ["artistName"],
7878+ "properties": {
7979+ "artistName": {
8080+ "type": "string",
8181+ "minLength": 1,
8282+ "maxLength": 256,
8383+ "maxGraphemes": 2560,
8484+ "description": "The name of the artist"
8585+ },
8686+ "artistMbId": {
8787+ "type": "string",
8888+ "format": "uri",
8989+ "description": "The MusicBrainz artist ID URI, formatted as mbid:<uuid>"
9090+ }
9191+ }
9292+ }
9393+ }
9494+}
···2828 >, as well as a hobbyist with embedded firmwares in Rust 🦀. Sometimes serious, mostly just
2929 killing time.
3030 </p>
3131- <div class="flex gap-2 max-lg:justify-center">
3131+ <div class="grid grid-cols-2 gap-1 max-lg:justify-center md:grid-cols-3 md:gap-2">
3232 <a
3333 href="https://bsky.app/profile/pds.dad"
3434 class="btn rounded-full text-xl font-bold not-italic btn-ghost md:btn-lg"
+36-36
src/lib/components/NavBar.svelte
···88 { name: 'Home', href: '#home' },
99 { name: 'Projects', href: '#projects' },
1010 { name: 'Writings', href: '#writings' },
1111- { name: 'Freetime', href: '#freetime' },
1111+ { name: 'Free Time', href: '#freetime' },
1212 { name: 'Sponsors', href: '#sponsors' }
1313 ];
1414···37373838 let active = $state(navigation[0].href);
39394040- onMount(() => {
4141- const sections = navigation
4242- .map((item) => document.getElementById(item.href.slice(1)))
4343- .filter((el): el is HTMLElement => el !== null);
4040+ // onMount(() => {
4141+ // const sections = navigation
4242+ // .map((item) => document.getElementById(item.href.slice(1)))
4343+ // .filter((el): el is HTMLElement => el !== null);
44444545- // Track which sections currently cross the activation band so we can
4646- // always pick the topmost one even when several overlap it.
4747- const intersecting = new Set<string>();
4545+ // // Track which sections currently cross the activation band so we can
4646+ // // always pick the topmost one even when several overlap it.
4747+ // const intersecting = new Set<string>();
48484949- const updateActive = () => {
5050- const next = navigation.find((item) => intersecting.has(item.href));
5151- if (!next || next.href === active) return;
5252- active = next.href;
5353- // Use SvelteKit's replaceState (not the native history.replaceState):
5454- // it updates the URL without scrolling *and* preserves the router's
5555- // internal history.state. Calling native history.replaceState(null, …)
5656- // here wipes SvelteKit's `sveltekit:history`/`sveltekit:navigation`
5757- // state, which corrupts the router's scroll handling and makes anchor
5858- // links intermittently fail to scroll.
5959- replaceState(next.href, {});
6060- };
4949+ // const updateActive = () => {
5050+ // const next = navigation.find((item) => intersecting.has(item.href));
5151+ // if (!next || next.href === active) return;
5252+ // active = next.href;
5353+ // // Use SvelteKit's replaceState (not the native history.replaceState):
5454+ // // it updates the URL without scrolling *and* preserves the router's
5555+ // // internal history.state. Calling native history.replaceState(null, …)
5656+ // // here wipes SvelteKit's `sveltekit:history`/`sveltekit:navigation`
5757+ // // state, which corrupts the router's scroll handling and makes anchor
5858+ // // links intermittently fail to scroll.
5959+ // replaceState(next.href, {});
6060+ // };
61616262- const observer = new IntersectionObserver(
6363- (entries) => {
6464- for (const entry of entries) {
6565- const hash = `#${entry.target.id}`;
6666- if (entry.isIntersecting) intersecting.add(hash);
6767- else intersecting.delete(hash);
6868- }
6969- updateActive();
7070- },
7171- // Thin band ~45% down the viewport: a section becomes active as it
7272- // crosses that line.
7373- { rootMargin: '-45% 0px -50% 0px', threshold: 0 }
7474- );
6262+ // const observer = new IntersectionObserver(
6363+ // (entries) => {
6464+ // for (const entry of entries) {
6565+ // const hash = `#${entry.target.id}`;
6666+ // if (entry.isIntersecting) intersecting.add(hash);
6767+ // else intersecting.delete(hash);
6868+ // }
6969+ // updateActive();
7070+ // },
7171+ // // Thin band ~45% down the viewport: a section becomes active as it
7272+ // // crosses that line.
7373+ // { rootMargin: '-45% 0px -50% 0px', threshold: 0 }
7474+ // );
75757676- sections.forEach((section) => observer.observe(section));
7777- return () => observer.disconnect();
7878- });
7676+ // sections.forEach((section) => observer.observe(section));
7777+ // return () => observer.disconnect();
7878+ // });
7979</script>
80808181<div class="sticky top-0 z-50 flex justify-center py-4">
+7
src/lib/components/OpenSourceProjects.svelte
···66 import badger from '$lib/assets/projects/badger.jpg';
77 import twentyfortyeight from '$lib/assets/projects/2048.png';
88 import giveaways from '$lib/assets/projects/giveaways.webp';
99+ import atToolbox from '$lib/assets/projects/attoolbox.webp';
9101011 type Project = {
1112 name: string;
···4243 'A simple Rust firmware written for the Badger 2040 W from Pimoroni. Counts wifi networks found, reads a shtc3 sensor for temperature and humidity, and displays the results on the Badger display.',
4344 image: badger,
4445 href: 'https://tangled.org/pds.dad/rusty-badger'
4646+ },
4747+ {
4848+ name: 'AT Toobox',
4949+ description: 'An iOS app that makes atproto actions easy with shortcuts',
5050+ image: atToolbox,
5151+ href: 'https://apps.apple.com/us/app/at-toolbox/id6747999688'
4552 },
4653 {
4754 name: 'at://2048',
+5
src/lib/lexicons/buzz.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as bookhive from './buzz/bookhive.js'
+6
src/lib/lexicons/buzz/bookhive.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as book from './bookhive/book.js'
66+export * as defs from './bookhive/defs.js'
+151
src/lib/lexicons/buzz/bookhive/book.defs.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+import { l } from '@atproto/lex'
66+import * as BookhiveDefs from './defs.defs.js'
77+88+const $nsid = 'buzz.bookhive.book'
99+1010+export { $nsid }
1111+1212+/** A book in the user's library */
1313+type Main = {
1414+ $type: 'buzz.bookhive.book'
1515+1616+ /**
1717+ * Cover image of the book
1818+ */
1919+ cover?: l.BlobRef
2020+2121+ /**
2222+ * Whether the user owns this book
2323+ */
2424+ owned?: boolean
2525+2626+ /**
2727+ * Number of stars given to the book (1-10) which will be mapped to 1-5 stars
2828+ */
2929+ stars?: number
3030+3131+ /**
3232+ * The title of the book
3333+ */
3434+ title: string
3535+3636+ /**
3737+ * The book's hive id, used to correlate user's books with the hive
3838+ */
3939+ hiveId: string
4040+4141+ /**
4242+ * The book's review
4343+ */
4444+ review?: string
4545+ status?:
4646+ | 'buzz.bookhive.defs#finished'
4747+ | 'buzz.bookhive.defs#reading'
4848+ | 'buzz.bookhive.defs#wantToRead'
4949+ | 'buzz.bookhive.defs#abandoned'
5050+ | l.UnknownString
5151+5252+ /**
5353+ * The authors of the book (tab separated)
5454+ */
5555+ authors: string
5656+ createdAt: l.DatetimeString
5757+5858+ /**
5959+ * The date the user started reading the book
6060+ */
6161+ startedAt?: l.DatetimeString
6262+6363+ /**
6464+ * The date the user finished reading the book
6565+ */
6666+ finishedAt?: l.DatetimeString
6767+6868+ /**
6969+ * AT-URI of the canonical catalogBook record in @bookhive.buzz
7070+ */
7171+ hiveBookUri?: string
7272+7373+ /**
7474+ * External identifiers for the book
7575+ */
7676+ identifiers?: BookhiveDefs.BookIdentifiers
7777+7878+ /**
7979+ * Progress tracking details for the book
8080+ */
8181+ bookProgress?: BookhiveDefs.BookProgress
8282+}
8383+8484+export type { Main }
8585+8686+/** A book in the user's library */
8787+const main = /*#__PURE__*/ l.record<'tid', Main>(
8888+ 'tid',
8989+ $nsid,
9090+ /*#__PURE__*/ l.object({
9191+ cover: /*#__PURE__*/ l.optional(
9292+ /*#__PURE__*/ l.blob({
9393+ accept: ['image/png', 'image/jpeg'],
9494+ maxSize: 1000000,
9595+ }),
9696+ ),
9797+ owned: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),
9898+ stars: /*#__PURE__*/ l.optional(
9999+ /*#__PURE__*/ l.integer({ maximum: 10, minimum: 1 }),
100100+ ),
101101+ title: /*#__PURE__*/ l.string({ maxLength: 512, minLength: 1 }),
102102+ hiveId: /*#__PURE__*/ l.string(),
103103+ review: /*#__PURE__*/ l.optional(
104104+ /*#__PURE__*/ l.string({ maxGraphemes: 15000 }),
105105+ ),
106106+ status: /*#__PURE__*/ l.optional(
107107+ /*#__PURE__*/ l.string<{
108108+ knownValues: [
109109+ 'buzz.bookhive.defs#finished',
110110+ 'buzz.bookhive.defs#reading',
111111+ 'buzz.bookhive.defs#wantToRead',
112112+ 'buzz.bookhive.defs#abandoned',
113113+ ]
114114+ }>(),
115115+ ),
116116+ authors: /*#__PURE__*/ l.string({ maxLength: 2048, minLength: 1 }),
117117+ createdAt: /*#__PURE__*/ l.string({ format: 'datetime' }),
118118+ startedAt: /*#__PURE__*/ l.optional(
119119+ /*#__PURE__*/ l.string({ format: 'datetime' }),
120120+ ),
121121+ finishedAt: /*#__PURE__*/ l.optional(
122122+ /*#__PURE__*/ l.string({ format: 'datetime' }),
123123+ ),
124124+ hiveBookUri: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
125125+ identifiers: /*#__PURE__*/ l.optional(
126126+ /*#__PURE__*/ l.ref<BookhiveDefs.BookIdentifiers>(
127127+ (() => BookhiveDefs.bookIdentifiers) as any,
128128+ ),
129129+ ),
130130+ bookProgress: /*#__PURE__*/ l.optional(
131131+ /*#__PURE__*/ l.ref<BookhiveDefs.BookProgress>(
132132+ (() => BookhiveDefs.bookProgress) as any,
133133+ ),
134134+ ),
135135+ }),
136136+)
137137+138138+export { main }
139139+140140+export const $type = $nsid
141141+export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main)
142142+export const $build = /*#__PURE__*/ main.build.bind(main)
143143+export const $assert = /*#__PURE__*/ main.assert.bind(main)
144144+export const $check = /*#__PURE__*/ main.check.bind(main)
145145+export const $cast = /*#__PURE__*/ main.cast.bind(main)
146146+export const $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main)
147147+export const $matches = /*#__PURE__*/ main.matches.bind(main)
148148+export const $parse = /*#__PURE__*/ main.parse.bind(main)
149149+export const $safeParse = /*#__PURE__*/ main.safeParse.bind(main)
150150+export const $validate = /*#__PURE__*/ main.validate.bind(main)
151151+export const $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main)
+6
src/lib/lexicons/buzz/bookhive/book.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * from './book.defs.js'
66+export { main as default } from './book.defs.js'
+469
src/lib/lexicons/buzz/bookhive/defs.defs.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+import { l } from '@atproto/lex'
66+import * as RepoStrongRef from '../../com/atproto/repo/strongRef.defs.js'
77+88+const $nsid = 'buzz.bookhive.defs'
99+1010+export { $nsid }
1111+1212+type Review = {
1313+ $type?: 'buzz.bookhive.defs#review'
1414+1515+ /**
1616+ * The DID of the user who made the review
1717+ */
1818+ did: string
1919+2020+ /**
2121+ * The number of stars given to the book
2222+ */
2323+ stars?: number
2424+2525+ /**
2626+ * The handle of the user who made the review
2727+ */
2828+ handle: string
2929+3030+ /**
3131+ * The review content
3232+ */
3333+ review: string
3434+3535+ /**
3636+ * The date the review was created
3737+ */
3838+ createdAt: l.DatetimeString
3939+}
4040+4141+export type { Review }
4242+4343+const review = /*#__PURE__*/ l.typedObject<Review>(
4444+ $nsid,
4545+ 'review',
4646+ /*#__PURE__*/ l.object({
4747+ did: /*#__PURE__*/ l.string(),
4848+ stars: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.integer()),
4949+ handle: /*#__PURE__*/ l.string(),
5050+ review: /*#__PURE__*/ l.string(),
5151+ createdAt: /*#__PURE__*/ l.string({ format: 'datetime' }),
5252+ }),
5353+)
5454+5555+export { review }
5656+5757+type Comment = {
5858+ $type?: 'buzz.bookhive.defs#comment'
5959+6060+ /**
6161+ * The DID of the user who made the comment
6262+ */
6363+ did: string
6464+ book: RepoStrongRef.Main
6565+6666+ /**
6767+ * The handle of the user who made the comment
6868+ */
6969+ handle: string
7070+ parent: RepoStrongRef.Main
7171+7272+ /**
7373+ * The content of the comment.
7474+ */
7575+ comment: string
7676+7777+ /**
7878+ * Client-declared timestamp when this comment was originally created.
7979+ */
8080+ createdAt: l.DatetimeString
8181+}
8282+8383+export type { Comment }
8484+8585+const comment = /*#__PURE__*/ l.typedObject<Comment>(
8686+ $nsid,
8787+ 'comment',
8888+ /*#__PURE__*/ l.object({
8989+ did: /*#__PURE__*/ l.string(),
9090+ book: /*#__PURE__*/ l.ref<RepoStrongRef.Main>(
9191+ (() => RepoStrongRef.main) as any,
9292+ ),
9393+ handle: /*#__PURE__*/ l.string(),
9494+ parent: /*#__PURE__*/ l.ref<RepoStrongRef.Main>(
9595+ (() => RepoStrongRef.main) as any,
9696+ ),
9797+ comment: /*#__PURE__*/ l.string({ maxLength: 100000, maxGraphemes: 10000 }),
9898+ createdAt: /*#__PURE__*/ l.string({ format: 'datetime' }),
9999+ }),
100100+)
101101+102102+export { comment }
103103+104104+type Profile = {
105105+ $type?: 'buzz.bookhive.defs#profile'
106106+ avatar?: string
107107+ handle: string
108108+ reviews: number
109109+ booksRead: number
110110+ description?: string
111111+ displayName: string
112112+113113+ /**
114114+ * Whether the authed user is following this profile
115115+ */
116116+ isFollowing?: boolean
117117+}
118118+119119+export type { Profile }
120120+121121+const profile = /*#__PURE__*/ l.typedObject<Profile>(
122122+ $nsid,
123123+ 'profile',
124124+ /*#__PURE__*/ l.object({
125125+ avatar: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
126126+ handle: /*#__PURE__*/ l.string(),
127127+ reviews: /*#__PURE__*/ l.integer({ minimum: 0 }),
128128+ booksRead: /*#__PURE__*/ l.integer({ minimum: 0 }),
129129+ description: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
130130+ displayName: /*#__PURE__*/ l.string(),
131131+ isFollowing: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),
132132+ }),
133133+)
134134+135135+export { profile }
136136+137137+/** User is currently reading the book */
138138+type Reading = 'buzz.bookhive.defs#reading'
139139+140140+export type { Reading }
141141+142142+/** User is currently reading the book */
143143+const reading = /*#__PURE__*/ l.token($nsid, 'reading')
144144+145145+export { reading }
146146+147147+type Activity = {
148148+ $type?: 'buzz.bookhive.defs#activity'
149149+ type: 'review' | 'rated' | 'started' | 'finished' | l.UnknownString
150150+151151+ /**
152152+ * The title of the book
153153+ */
154154+ title: string
155155+156156+ /**
157157+ * The hive id of the book
158158+ */
159159+ hiveId: string
160160+161161+ /**
162162+ * The DID of the user who added the book
163163+ */
164164+ userDid: string
165165+ createdAt: l.DatetimeString
166166+167167+ /**
168168+ * The handle of the user who added the book
169169+ */
170170+ userHandle: string
171171+}
172172+173173+export type { Activity }
174174+175175+const activity = /*#__PURE__*/ l.typedObject<Activity>(
176176+ $nsid,
177177+ 'activity',
178178+ /*#__PURE__*/ l.object({
179179+ type: /*#__PURE__*/ l.string<{
180180+ knownValues: ['review', 'rated', 'started', 'finished']
181181+ }>(),
182182+ title: /*#__PURE__*/ l.string(),
183183+ hiveId: /*#__PURE__*/ l.string(),
184184+ userDid: /*#__PURE__*/ l.string(),
185185+ createdAt: /*#__PURE__*/ l.string({ format: 'datetime' }),
186186+ userHandle: /*#__PURE__*/ l.string(),
187187+ }),
188188+)
189189+190190+export { activity }
191191+192192+/** User has finished reading the book */
193193+type Finished = 'buzz.bookhive.defs#finished'
194194+195195+export type { Finished }
196196+197197+/** User has finished reading the book */
198198+const finished = /*#__PURE__*/ l.token($nsid, 'finished')
199199+200200+export { finished }
201201+202202+type UserBook = {
203203+ $type?: 'buzz.bookhive.defs#userBook'
204204+205205+ /**
206206+ * Cover image of the book
207207+ */
208208+ cover?: string
209209+210210+ /**
211211+ * Whether the user owns this book
212212+ */
213213+ owned?: boolean
214214+215215+ /**
216216+ * Number of stars given to the book (1-10) which will be mapped to 1-5 stars
217217+ */
218218+ stars?: number
219219+220220+ /**
221221+ * The title of the book
222222+ */
223223+ title: string
224224+225225+ /**
226226+ * The book's hive id, used to correlate user's books with the hive
227227+ */
228228+ hiveId: string
229229+230230+ /**
231231+ * Average rating (0-1000)
232232+ */
233233+ rating?: number
234234+235235+ /**
236236+ * The book's review
237237+ */
238238+ review?: string
239239+ status?:
240240+ | 'buzz.bookhive.defs#finished'
241241+ | 'buzz.bookhive.defs#reading'
242242+ | 'buzz.bookhive.defs#wantToRead'
243243+ | 'buzz.bookhive.defs#abandoned'
244244+ | l.UnknownString
245245+246246+ /**
247247+ * The authors of the book (tab separated)
248248+ */
249249+ authors: string
250250+251251+ /**
252252+ * The DID of the user who added the book
253253+ */
254254+ userDid: string
255255+ createdAt: l.DatetimeString
256256+257257+ /**
258258+ * The date the user started reading the book
259259+ */
260260+ startedAt?: l.DatetimeString
261261+262262+ /**
263263+ * Cover image of the book
264264+ */
265265+ thumbnail: string
266266+267267+ /**
268268+ * The date the user finished reading the book
269269+ */
270270+ finishedAt?: l.DatetimeString
271271+272272+ /**
273273+ * The handle of the user who added the book
274274+ */
275275+ userHandle?: string
276276+277277+ /**
278278+ * Book description/summary
279279+ */
280280+ description?: string
281281+282282+ /**
283283+ * External identifiers for the book
284284+ */
285285+ identifiers?: BookIdentifiers
286286+287287+ /**
288288+ * Progress tracking information for the book
289289+ */
290290+ bookProgress?: BookProgress
291291+}
292292+293293+export type { UserBook }
294294+295295+const userBook = /*#__PURE__*/ l.typedObject<UserBook>(
296296+ $nsid,
297297+ 'userBook',
298298+ /*#__PURE__*/ l.object({
299299+ cover: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
300300+ owned: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),
301301+ stars: /*#__PURE__*/ l.optional(
302302+ /*#__PURE__*/ l.integer({ maximum: 10, minimum: 1 }),
303303+ ),
304304+ title: /*#__PURE__*/ l.string({ maxLength: 512, minLength: 1 }),
305305+ hiveId: /*#__PURE__*/ l.string(),
306306+ rating: /*#__PURE__*/ l.optional(
307307+ /*#__PURE__*/ l.integer({ maximum: 1000, minimum: 0 }),
308308+ ),
309309+ review: /*#__PURE__*/ l.optional(
310310+ /*#__PURE__*/ l.string({ maxGraphemes: 15000 }),
311311+ ),
312312+ status: /*#__PURE__*/ l.optional(
313313+ /*#__PURE__*/ l.string<{
314314+ knownValues: [
315315+ 'buzz.bookhive.defs#finished',
316316+ 'buzz.bookhive.defs#reading',
317317+ 'buzz.bookhive.defs#wantToRead',
318318+ 'buzz.bookhive.defs#abandoned',
319319+ ]
320320+ }>(),
321321+ ),
322322+ authors: /*#__PURE__*/ l.string({ maxLength: 2048, minLength: 1 }),
323323+ userDid: /*#__PURE__*/ l.string(),
324324+ createdAt: /*#__PURE__*/ l.string({ format: 'datetime' }),
325325+ startedAt: /*#__PURE__*/ l.optional(
326326+ /*#__PURE__*/ l.string({ format: 'datetime' }),
327327+ ),
328328+ thumbnail: /*#__PURE__*/ l.string(),
329329+ finishedAt: /*#__PURE__*/ l.optional(
330330+ /*#__PURE__*/ l.string({ format: 'datetime' }),
331331+ ),
332332+ userHandle: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
333333+ description: /*#__PURE__*/ l.optional(
334334+ /*#__PURE__*/ l.string({ maxLength: 5000 }),
335335+ ),
336336+ identifiers: /*#__PURE__*/ l.optional(
337337+ /*#__PURE__*/ l.ref<BookIdentifiers>((() => bookIdentifiers) as any),
338338+ ),
339339+ bookProgress: /*#__PURE__*/ l.optional(
340340+ /*#__PURE__*/ l.ref<BookProgress>((() => bookProgress) as any),
341341+ ),
342342+ }),
343343+)
344344+345345+export { userBook }
346346+347347+/** User has abandoned the book */
348348+type Abandoned = 'buzz.bookhive.defs#abandoned'
349349+350350+export type { Abandoned }
351351+352352+/** User has abandoned the book */
353353+const abandoned = /*#__PURE__*/ l.token($nsid, 'abandoned')
354354+355355+export { abandoned }
356356+357357+/** User wants to read the book */
358358+type WantToRead = 'buzz.bookhive.defs#wantToRead'
359359+360360+export type { WantToRead }
361361+362362+/** User wants to read the book */
363363+const wantToRead = /*#__PURE__*/ l.token($nsid, 'wantToRead')
364364+365365+export { wantToRead }
366366+367367+/** Reading progress tracking data */
368368+type BookProgress = {
369369+ $type?: 'buzz.bookhive.defs#bookProgress'
370370+371371+ /**
372372+ * How far through the book the reader is (0-100)
373373+ */
374374+ percent?: number
375375+376376+ /**
377377+ * When the progress was last updated
378378+ */
379379+ updatedAt: l.DatetimeString
380380+381381+ /**
382382+ * Total number of pages in the book
383383+ */
384384+ totalPages?: number
385385+386386+ /**
387387+ * Current page the user is on
388388+ */
389389+ currentPage?: number
390390+391391+ /**
392392+ * Total number of chapters in the book
393393+ */
394394+ totalChapters?: number
395395+396396+ /**
397397+ * Current chapter the user is on
398398+ */
399399+ currentChapter?: number
400400+}
401401+402402+export type { BookProgress }
403403+404404+/** Reading progress tracking data */
405405+const bookProgress = /*#__PURE__*/ l.typedObject<BookProgress>(
406406+ $nsid,
407407+ 'bookProgress',
408408+ /*#__PURE__*/ l.object({
409409+ percent: /*#__PURE__*/ l.optional(
410410+ /*#__PURE__*/ l.integer({ maximum: 100, minimum: 0 }),
411411+ ),
412412+ updatedAt: /*#__PURE__*/ l.string({ format: 'datetime' }),
413413+ totalPages: /*#__PURE__*/ l.optional(
414414+ /*#__PURE__*/ l.integer({ minimum: 1 }),
415415+ ),
416416+ currentPage: /*#__PURE__*/ l.optional(
417417+ /*#__PURE__*/ l.integer({ minimum: 1 }),
418418+ ),
419419+ totalChapters: /*#__PURE__*/ l.optional(
420420+ /*#__PURE__*/ l.integer({ minimum: 1 }),
421421+ ),
422422+ currentChapter: /*#__PURE__*/ l.optional(
423423+ /*#__PURE__*/ l.integer({ minimum: 1 }),
424424+ ),
425425+ }),
426426+)
427427+428428+export { bookProgress }
429429+430430+/** External identifiers for a book */
431431+type BookIdentifiers = {
432432+ $type?: 'buzz.bookhive.defs#bookIdentifiers'
433433+434434+ /**
435435+ * BookHive's internal ID
436436+ */
437437+ hiveId?: string
438438+439439+ /**
440440+ * 10-digit ISBN
441441+ */
442442+ isbn10?: string
443443+444444+ /**
445445+ * 13-digit ISBN
446446+ */
447447+ isbn13?: string
448448+449449+ /**
450450+ * Goodreads book ID
451451+ */
452452+ goodreadsId?: string
453453+}
454454+455455+export type { BookIdentifiers }
456456+457457+/** External identifiers for a book */
458458+const bookIdentifiers = /*#__PURE__*/ l.typedObject<BookIdentifiers>(
459459+ $nsid,
460460+ 'bookIdentifiers',
461461+ /*#__PURE__*/ l.object({
462462+ hiveId: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
463463+ isbn10: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
464464+ isbn13: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
465465+ goodreadsId: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
466466+ }),
467467+)
468468+469469+export { bookIdentifiers }
+5
src/lib/lexicons/buzz/bookhive/defs.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * from './defs.defs.js'
+1
src/lib/lexicons/com/atproto.ts
···33 */
4455export * as label from './atproto/label.js'
66+export * as repo from './atproto/repo.js'
+5
src/lib/lexicons/com/atproto/repo.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as strongRef from './repo/strongRef.js'
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * from './strongRef.defs.js'
66+export { main as default } from './strongRef.defs.js'
+5
src/lib/lexicons/fm.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as teal from './fm/teal.js'
+5
src/lib/lexicons/fm/teal.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as alpha from './teal/alpha.js'
+6
src/lib/lexicons/fm/teal/alpha.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as actor from './alpha/actor.js'
66+export * as feed from './alpha/feed.js'
+5
src/lib/lexicons/fm/teal/alpha/actor.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as status from './actor/status.js'
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+import { l } from '@atproto/lex'
66+import * as FeedDefs from '../feed/defs.defs.js'
77+88+const $nsid = 'fm.teal.alpha.actor.status'
99+1010+export { $nsid }
1111+1212+/** This lexicon is in a not officially released state. It is subject to change. | A declaration of the status of the actor. Only one can be shown at a time. If there are multiple, the latest record should be picked and earlier records should be deleted or tombstoned. */
1313+type Main = {
1414+ $type: 'fm.teal.alpha.actor.status'
1515+1616+ /**
1717+ * The RFC 3339 formatted time of when the item was recorded
1818+ */
1919+ time: l.DatetimeString
2020+2121+ /**
2222+ * The RFC 3339 formatted time of the expiry time of the item. If unavailable, default to 10 minutes past the start time.
2323+ */
2424+ expiry?: l.DatetimeString
2525+ item: FeedDefs.PlayView
2626+}
2727+2828+export type { Main }
2929+3030+/** This lexicon is in a not officially released state. It is subject to change. | A declaration of the status of the actor. Only one can be shown at a time. If there are multiple, the latest record should be picked and earlier records should be deleted or tombstoned. */
3131+const main = /*#__PURE__*/ l.record<'literal:self', Main>(
3232+ 'literal:self',
3333+ $nsid,
3434+ /*#__PURE__*/ l.object({
3535+ time: /*#__PURE__*/ l.string({ format: 'datetime' }),
3636+ expiry: /*#__PURE__*/ l.optional(
3737+ /*#__PURE__*/ l.string({ format: 'datetime' }),
3838+ ),
3939+ item: /*#__PURE__*/ l.ref<FeedDefs.PlayView>(
4040+ (() => FeedDefs.playView) as any,
4141+ ),
4242+ }),
4343+)
4444+4545+export { main }
4646+4747+export const $type = $nsid
4848+export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main)
4949+export const $build = /*#__PURE__*/ main.build.bind(main)
5050+export const $assert = /*#__PURE__*/ main.assert.bind(main)
5151+export const $check = /*#__PURE__*/ main.check.bind(main)
5252+export const $cast = /*#__PURE__*/ main.cast.bind(main)
5353+export const $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main)
5454+export const $matches = /*#__PURE__*/ main.matches.bind(main)
5555+export const $parse = /*#__PURE__*/ main.parse.bind(main)
5656+export const $safeParse = /*#__PURE__*/ main.safeParse.bind(main)
5757+export const $validate = /*#__PURE__*/ main.validate.bind(main)
5858+export const $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main)
+6
src/lib/lexicons/fm/teal/alpha/actor/status.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * from './status.defs.js'
66+export { main as default } from './status.defs.js'
+5
src/lib/lexicons/fm/teal/alpha/feed.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * as defs from './feed/defs.js'
+147
src/lib/lexicons/fm/teal/alpha/feed/defs.defs.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+import { l } from '@atproto/lex'
66+77+const $nsid = 'fm.teal.alpha.feed.defs'
88+99+export { $nsid }
1010+1111+type PlayView = {
1212+ $type?: 'fm.teal.alpha.feed.defs#playView'
1313+1414+ /**
1515+ * The name of the track
1616+ */
1717+ trackName: string
1818+1919+ /**
2020+ * The MusicBrainz ID URI of the track, formatted as mbid:<uuid>
2121+ */
2222+ trackMbId?: l.UriString
2323+2424+ /**
2525+ * The MusicBrainz recording ID URI of the track, formatted as mbid:<uuid>
2626+ */
2727+ recordingMbId?: l.UriString
2828+2929+ /**
3030+ * The length of the track in seconds
3131+ */
3232+ duration?: number
3333+3434+ /**
3535+ * Array of artists in order of original appearance.
3636+ */
3737+ artists: Artist[]
3838+3939+ /**
4040+ * The name of the release/album
4141+ */
4242+ releaseName?: string
4343+4444+ /**
4545+ * The MusicBrainz release ID URI, formatted as mbid:<uuid>
4646+ */
4747+ releaseMbId?: l.UriString
4848+4949+ /**
5050+ * The ISRC code associated with the recording
5151+ */
5252+ isrc?: string
5353+5454+ /**
5555+ * The URL associated with this track
5656+ */
5757+ originUrl?: string
5858+5959+ /**
6060+ * The base domain of the music service. e.g. music.apple.com, tidal.com, spotify.com. Defaults to 'local' if not provided.
6161+ */
6262+ musicServiceBaseDomain?: string
6363+6464+ /**
6565+ * A user-agent style string specifying the user agent. e.g. tealtracker/0.0.1b (Linux; Android 13; SM-A715F). Defaults to 'manual/unknown' if not provided.
6666+ */
6767+ submissionClientAgent?: string
6868+6969+ /**
7070+ * The unix timestamp of when the track was played
7171+ */
7272+ playedTime?: l.DatetimeString
7373+}
7474+7575+export type { PlayView }
7676+7777+const playView = /*#__PURE__*/ l.typedObject<PlayView>(
7878+ $nsid,
7979+ 'playView',
8080+ /*#__PURE__*/ l.object({
8181+ trackName: /*#__PURE__*/ l.string({
8282+ minLength: 1,
8383+ maxLength: 256,
8484+ maxGraphemes: 2560,
8585+ }),
8686+ trackMbId: /*#__PURE__*/ l.optional(
8787+ /*#__PURE__*/ l.string({ format: 'uri' }),
8888+ ),
8989+ recordingMbId: /*#__PURE__*/ l.optional(
9090+ /*#__PURE__*/ l.string({ format: 'uri' }),
9191+ ),
9292+ duration: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.integer()),
9393+ artists: /*#__PURE__*/ l.array(
9494+ /*#__PURE__*/ l.ref<Artist>((() => artist) as any),
9595+ ),
9696+ releaseName: /*#__PURE__*/ l.optional(
9797+ /*#__PURE__*/ l.string({ maxLength: 256, maxGraphemes: 2560 }),
9898+ ),
9999+ releaseMbId: /*#__PURE__*/ l.optional(
100100+ /*#__PURE__*/ l.string({ format: 'uri' }),
101101+ ),
102102+ isrc: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
103103+ originUrl: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
104104+ musicServiceBaseDomain: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),
105105+ submissionClientAgent: /*#__PURE__*/ l.optional(
106106+ /*#__PURE__*/ l.string({ maxLength: 256, maxGraphemes: 2560 }),
107107+ ),
108108+ playedTime: /*#__PURE__*/ l.optional(
109109+ /*#__PURE__*/ l.string({ format: 'datetime' }),
110110+ ),
111111+ }),
112112+)
113113+114114+export { playView }
115115+116116+type Artist = {
117117+ $type?: 'fm.teal.alpha.feed.defs#artist'
118118+119119+ /**
120120+ * The name of the artist
121121+ */
122122+ artistName: string
123123+124124+ /**
125125+ * The MusicBrainz artist ID URI, formatted as mbid:<uuid>
126126+ */
127127+ artistMbId?: l.UriString
128128+}
129129+130130+export type { Artist }
131131+132132+const artist = /*#__PURE__*/ l.typedObject<Artist>(
133133+ $nsid,
134134+ 'artist',
135135+ /*#__PURE__*/ l.object({
136136+ artistName: /*#__PURE__*/ l.string({
137137+ minLength: 1,
138138+ maxLength: 256,
139139+ maxGraphemes: 2560,
140140+ }),
141141+ artistMbId: /*#__PURE__*/ l.optional(
142142+ /*#__PURE__*/ l.string({ format: 'uri' }),
143143+ ),
144144+ }),
145145+)
146146+147147+export { artist }
+5
src/lib/lexicons/fm/teal/alpha/feed/defs.ts
···11+/*
22+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33+ */
44+55+export * from './defs.defs.js'
+2
src/lib/lexicons/index.ts
···22 * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33 */
4455+export * as buzz from './buzz.js'
56export * as com from './com.js'
77+export * as fm from './fm.js'
68export * as site from './site.js'
+1-1
src/lib/lexicons/site/standard/theme.ts
···22 * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
33 */
4455-export * as color from './theme/color.js'
65export * as basic from './theme/basic.js'
66+export * as color from './theme/color.js'